summaryrefslogtreecommitdiffstats
path: root/Python/structmember.c
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2015-09-04 21:57:25 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2015-09-04 21:57:25 (GMT)
commitadfefa527a32e711c1bea9c1ac32c20e9cce0660 (patch)
tree8e03b6d95d1f6f32780d8535aa5b60d411d0646f /Python/structmember.c
parent19bbb9af678040e8963edfcfdc30e9f87b106fb9 (diff)
downloadcpython-adfefa527a32e711c1bea9c1ac32c20e9cce0660.zip
cpython-adfefa527a32e711c1bea9c1ac32c20e9cce0660.tar.gz
cpython-adfefa527a32e711c1bea9c1ac32c20e9cce0660.tar.bz2
Issue #23517: Fix implementation of the ROUND_HALF_UP rounding mode in
datetime.datetime.fromtimestamp() and datetime.datetime.utcfromtimestamp(). microseconds sign should be kept before rounding.
Diffstat (limited to 'Python/structmember.c')
0 files changed, 0 insertions, 0 deletions
value='bug_3592747'>bug_3592747 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--ChangeLog16033
-rw-r--r--ChangeLog.19992738
-rw-r--r--ChangeLog.20001868
-rw-r--r--ChangeLog.20013023
-rw-r--r--ChangeLog.20024741
-rw-r--r--ChangeLog.20033349
-rw-r--r--ChangeLog.20044619
-rw-r--r--ChangeLog.20053822
-rw-r--r--README16
-rw-r--r--changes1307
-rw-r--r--compat/fixstrtod.c8
-rw-r--r--compat/gettod.c8
-rw-r--r--compat/memcmp.c40
-rw-r--r--compat/opendir.c117
-rw-r--r--compat/strftime.c515
-rw-r--r--compat/string.h2
-rw-r--r--compat/strncasecmp.c44
-rw-r--r--compat/strstr.c29
-rw-r--r--compat/strtod.c62
-rw-r--r--compat/strtol.c39
-rw-r--r--compat/strtoll.c109
-rw-r--r--compat/strtoul.c70
-rw-r--r--compat/strtoull.c259
-rw-r--r--compat/tclErrno.h97
-rw-r--r--compat/tmpnam.c40
-rw-r--r--compat/waitpid.c92
-rw-r--r--doc/Access.32
-rw-r--r--doc/AddErrInfo.3279
-rw-r--r--doc/Alloc.310
-rw-r--r--doc/AllowExc.38
-rw-r--r--doc/AppInit.310
-rw-r--r--doc/AssocData.314
-rw-r--r--doc/Async.316
-rw-r--r--doc/BackgdErr.333
-rw-r--r--doc/Backslash.38
-rw-r--r--doc/BoolObj.3106
-rw-r--r--doc/ByteArrObj.36
-rw-r--r--doc/CallDel.36
-rw-r--r--doc/ChnlStack.320
-rw-r--r--doc/CmdCmplt.34
-rw-r--r--doc/Concat.38
-rw-r--r--doc/CrtChannel.3375
-rw-r--r--doc/CrtChnlHdlr.36
-rw-r--r--doc/CrtCloseHdlr.34
-rw-r--r--doc/CrtCommand.329
-rw-r--r--doc/CrtFileHdlr.314
-rw-r--r--doc/CrtMathFnc.391
-rw-r--r--doc/CrtObjCmd.351
-rw-r--r--doc/CrtSlave.367
-rw-r--r--doc/CrtTimerHdlr.39
-rw-r--r--doc/CrtTrace.343
-rw-r--r--doc/DString.328
-rw-r--r--doc/DetachPids.316
-rw-r--r--doc/DictObj.3234
-rw-r--r--doc/DoOneEvent.38
-rw-r--r--doc/DoWhenIdle.34
-rw-r--r--doc/DoubleObj.365
-rw-r--r--doc/DumpActiveMemory.35
-rw-r--r--doc/Encoding.3241
-rw-r--r--doc/Ensemble.3186
-rw-r--r--doc/Environment.320
-rw-r--r--doc/Eval.347
-rw-r--r--doc/Exit.336
-rw-r--r--doc/ExprLong.324
-rw-r--r--doc/ExprLongObj.36
-rw-r--r--doc/FileSystem.31074
-rw-r--r--doc/FindExec.34
-rw-r--r--[-rwxr-xr-x]doc/GetCwd.34
-rw-r--r--doc/GetHostName.32
-rw-r--r--doc/GetIndex.339
-rw-r--r--doc/GetInt.355
-rw-r--r--doc/GetOpnFl.322
-rw-r--r--doc/GetStdChan.33
-rw-r--r--doc/GetTime.357
-rw-r--r--[-rwxr-xr-x]doc/GetVersion.31
-rw-r--r--doc/Hash.3141
-rw-r--r--doc/Init.37
-rw-r--r--doc/InitStubs.310
-rw-r--r--doc/IntObj.3199
-rw-r--r--doc/Interp.320
-rw-r--r--doc/Limit.3194
-rw-r--r--doc/LinkVar.3122
-rw-r--r--doc/ListObj.327
-rw-r--r--doc/Macintosh.3109
-rw-r--r--doc/Namespace.3165
-rw-r--r--doc/Notifier.3141
-rw-r--r--doc/Object.374
-rw-r--r--doc/ObjectType.3147
-rw-r--r--doc/OpenFileChnl.382
-rw-r--r--doc/OpenTcp.327
-rw-r--r--doc/Panic.324
-rw-r--r--doc/ParseCmd.3104
-rw-r--r--doc/PkgRequire.333
-rw-r--r--doc/Preserve.34
-rw-r--r--doc/PrintDbl.328
-rw-r--r--doc/RecEvalObj.316
-rw-r--r--doc/RecordEval.316
-rw-r--r--doc/RegConfig.3112
-rw-r--r--doc/RegExp.3183
-rw-r--r--doc/SaveResult.385
-rw-r--r--doc/SetChanErr.3153
-rw-r--r--doc/SetErrno.312
-rw-r--r--doc/SetResult.387
-rw-r--r--doc/SetVar.360
-rw-r--r--doc/Signal.312
-rw-r--r--doc/Sleep.35
-rw-r--r--doc/SourceRCFile.35
-rw-r--r--doc/SplitList.324
-rw-r--r--doc/SplitPath.38
-rw-r--r--doc/StaticPkg.38
-rw-r--r--doc/StdChannels.335
-rw-r--r--doc/StrMatch.329
-rw-r--r--doc/StringObj.3142
-rw-r--r--doc/SubstObj.317
-rw-r--r--doc/TCL_MEM_DEBUG.337
-rw-r--r--doc/Tcl.n75
-rw-r--r--doc/Tcl_Main.322
-rw-r--r--doc/Thread.392
-rw-r--r--doc/ToUpper.32
-rw-r--r--doc/TraceCmd.355
-rw-r--r--doc/TraceVar.3103
-rw-r--r--doc/Translate.324
-rw-r--r--doc/UniCharIsAlpha.33
-rw-r--r--doc/UpVar.321
-rw-r--r--doc/Utf.398
-rw-r--r--doc/WrongNumArgs.311
-rw-r--r--doc/after.n10
-rw-r--r--doc/append.n9
-rw-r--r--doc/apply.n96
-rw-r--r--doc/array.n48
-rw-r--r--doc/bgerror.n41
-rw-r--r--doc/binary.n489
-rw-r--r--doc/catch.n66
-rw-r--r--doc/chan.n736
-rw-r--r--doc/clock.n1089
-rw-r--r--doc/close.n8
-rw-r--r--doc/concat.n34
-rw-r--r--doc/dde.n63
-rw-r--r--doc/dict.n389
-rw-r--r--doc/encoding.n20
-rw-r--r--doc/error.n48
-rw-r--r--doc/eval.n50
-rw-r--r--doc/exec.n197
-rw-r--r--doc/exit.n10
-rw-r--r--doc/expr.n351
-rw-r--r--doc/fblocked.n2
-rw-r--r--doc/fconfigure.n50
-rw-r--r--doc/fcopy.n93
-rw-r--r--doc/file.n245
-rw-r--r--doc/fileevent.n12
-rw-r--r--doc/filename.n148
-rw-r--r--doc/flush.n2
-rw-r--r--doc/for.n2
-rw-r--r--doc/foreach.n29
-rw-r--r--doc/format.n94
-rw-r--r--doc/gets.n2
-rw-r--r--doc/glob.n104
-rw-r--r--doc/global.n6
-rw-r--r--doc/history.n22
-rw-r--r--doc/http.n271
-rw-r--r--doc/if.n3
-rw-r--r--doc/incr.n8
-rw-r--r--doc/info.n160
-rw-r--r--doc/interp.n402
-rw-r--r--doc/join.n4
-rw-r--r--doc/lappend.n17
-rw-r--r--doc/lassign.n55
-rw-r--r--doc/library.n48
-rw-r--r--doc/lindex.n55
-rw-r--r--doc/linsert.n18
-rw-r--r--doc/list.n11
-rw-r--r--doc/llength.n4
-rw-r--r--doc/load.n29
-rw-r--r--doc/lrange.n27
-rw-r--r--doc/lrepeat.n39
-rw-r--r--doc/lreplace.n55
-rw-r--r--doc/lreverse.n31
-rw-r--r--doc/lsearch.n221
-rw-r--r--[-rwxr-xr-x]doc/lset.n53
-rw-r--r--doc/lsort.n67
-rw-r--r--doc/man.macros201
-rw-r--r--doc/mathfunc.n271
-rw-r--r--doc/mathop.n299
-rw-r--r--doc/memory.n34
-rw-r--r--doc/msgcat.n93
-rw-r--r--doc/namespace.n325
-rw-r--r--doc/open.n105
-rw-r--r--doc/package.n195
-rw-r--r--doc/packagens.n5
-rw-r--r--doc/pid.n2
-rw-r--r--doc/pkgMkIndex.n60
-rw-r--r--doc/platform.n66
-rw-r--r--doc/platform_shell.n57
-rw-r--r--doc/proc.n22
-rw-r--r--doc/puts.n7
-rw-r--r--doc/pwd.n3
-rw-r--r--doc/re_syntax.n1254
-rw-r--r--doc/read.n4
-rw-r--r--doc/refchan.n340
-rw-r--r--doc/regexp.n96
-rw-r--r--doc/registry.n57
-rw-r--r--doc/regsub.n107
-rw-r--r--doc/resource.n154
-rw-r--r--doc/return.n234
-rw-r--r--doc/safe.n58
-rw-r--r--doc/scan.n169
-rw-r--r--doc/seek.n4
-rw-r--r--doc/set.n7
-rw-r--r--doc/socket.n18
-rw-r--r--doc/source.n40
-rw-r--r--doc/split.n14
-rw-r--r--doc/string.n145
-rw-r--r--doc/subst.n72
-rw-r--r--doc/switch.n94
-rw-r--r--doc/tclsh.145
-rw-r--r--doc/tcltest.n651
-rw-r--r--doc/tclvars.n302
-rw-r--r--doc/tell.n4
-rw-r--r--doc/time.n2
-rw-r--r--doc/tm.n293
-rw-r--r--doc/trace.n244
-rw-r--r--doc/unknown.n28
-rw-r--r--doc/unload.n162
-rw-r--r--doc/unset.n7
-rw-r--r--doc/update.n5
-rw-r--r--doc/uplevel.n13
-rw-r--r--doc/upvar.n32
-rw-r--r--doc/vwait.n2
-rw-r--r--generic/README4
-rw-r--r--generic/regc_color.c1253
-rw-r--r--generic/regc_cvec.c131
-rw-r--r--generic/regc_lex.c1830
-rw-r--r--generic/regc_locale.c118
-rw-r--r--generic/regc_nfa.c2631
-rw-r--r--generic/regcomp.c3495
-rw-r--r--generic/regcustom.h137
-rw-r--r--generic/rege_dfa.c1223
-rw-r--r--generic/regerror.c148
-rw-r--r--generic/regex.h159
-rw-r--r--generic/regexec.c1830
-rw-r--r--generic/regfree.c47
-rw-r--r--generic/regfronts.c92
-rw-r--r--generic/regguts.h398
-rw-r--r--generic/tcl.decls924
-rw-r--r--generic/tcl.h2343
-rw-r--r--generic/tclAlloc.c509
-rw-r--r--generic/tclAsync.c203
-rw-r--r--generic/tclBasic.c7584
-rw-r--r--generic/tclBinary.c2351
-rw-r--r--generic/tclCkalloc.c891
-rw-r--r--generic/tclClock.c2239
-rw-r--r--generic/tclCmdAH.c2576
-rw-r--r--generic/tclCmdIL.c4697
-rw-r--r--generic/tclCmdMZ.c6460
-rw-r--r--generic/tclCompCmds.c6484
-rw-r--r--generic/tclCompExpr.c3229
-rw-r--r--generic/tclCompile.c3761
-rw-r--r--generic/tclCompile.h1199
-rw-r--r--generic/tclConfig.c392
-rw-r--r--generic/tclDTrace.d30
-rw-r--r--generic/tclDate.c4361
-rw-r--r--generic/tclDecls.h5694
-rw-r--r--generic/tclDictObj.c3170
-rw-r--r--generic/tclEncoding.c2354
-rw-r--r--generic/tclEnv.c558
-rw-r--r--generic/tclEvent.c1301
-rw-r--r--generic/tclExecute.c10605
-rw-r--r--generic/tclFCmd.c751
-rw-r--r--generic/tclFileName.c2922
-rw-r--r--generic/tclFileSystem.h121
-rw-r--r--generic/tclGet.c347
-rw-r--r--generic/tclGetDate.y1725
-rw-r--r--generic/tclHash.c715
-rw-r--r--generic/tclHistory.c103
-rw-r--r--generic/tclIO.c8844
-rw-r--r--generic/tclIO.h356
-rw-r--r--generic/tclIOCmd.c1728
-rw-r--r--generic/tclIOGT.c1538
-rw-r--r--generic/tclIORChan.c3187
-rw-r--r--generic/tclIOSock.c50
-rw-r--r--generic/tclIOUtil.c6842
-rw-r--r--generic/tclIndexObj.c535
-rw-r--r--generic/tclInitScript.h110
-rw-r--r--generic/tclInt.decls934
-rw-r--r--generic/tclInt.h4753
-rw-r--r--generic/tclIntDecls.h1935
-rw-r--r--generic/tclIntPlatDecls.h919
-rw-r--r--generic/tclInterp.c4194
-rw-r--r--generic/tclLink.c519
-rw-r--r--generic/tclListObj.c2152
-rw-r--r--generic/tclLiteral.c855
-rw-r--r--generic/tclLoad.c839
-rw-r--r--generic/tclLoadNone.c103
-rw-r--r--generic/tclMain.c582
-rw-r--r--generic/tclMath.h25
-rw-r--r--generic/tclNamesp.c6976
-rw-r--r--generic/tclNotify.c629
-rw-r--r--generic/tclObj.c3909
-rw-r--r--generic/tclPanic.c56
-rw-r--r--generic/tclParse.c2393
-rw-r--r--generic/tclParseExpr.c2083
-rw-r--r--generic/tclPathObj.c2836
-rw-r--r--generic/tclPipe.c588
-rw-r--r--generic/tclPkg.c1581
-rw-r--r--generic/tclPkgConfig.c135
-rw-r--r--generic/tclPlatDecls.h190
-rw-r--r--generic/tclPort.h25
-rw-r--r--generic/tclPosixStr.c773
-rw-r--r--generic/tclPreserve.c328
-rw-r--r--generic/tclProc.c3089
-rw-r--r--generic/tclRegexp.c570
-rw-r--r--generic/tclRegexp.h35
-rw-r--r--generic/tclResolve.c450
-rw-r--r--generic/tclResult.c1272
-rw-r--r--generic/tclScan.c1007
-rwxr-xr-xgeneric/tclStrToD.c4994
-rw-r--r--generic/tclStringObj.c2271
-rw-r--r--generic/tclStubInit.c521
-rw-r--r--generic/tclStubLib.c148
-rw-r--r--generic/tclTest.c5720
-rw-r--r--generic/tclTestObj.c615
-rw-r--r--generic/tclTestProcBodyObj.c127
-rw-r--r--generic/tclThread.c354
-rw-r--r--[-rwxr-xr-x]generic/tclThreadAlloc.c736
-rw-r--r--generic/tclThreadJoin.c313
-rw-r--r--generic/tclThreadStorage.c597
-rw-r--r--generic/tclThreadTest.c599
-rw-r--r--generic/tclTimer.c851
-rw-r--r--generic/tclTomMath.decls222
-rw-r--r--generic/tclTomMath.h836
-rw-r--r--generic/tclTomMathDecls.h819
-rw-r--r--generic/tclTomMathInt.h2
-rw-r--r--generic/tclTomMathInterface.c311
-rw-r--r--generic/tclTrace.c3249
-rw-r--r--generic/tclUniData.c6
-rw-r--r--generic/tclUtf.c856
-rw-r--r--generic/tclUtil.c3817
-rw-r--r--generic/tclVar.c6591
-rw-r--r--generic/tommath.h1
-rw-r--r--library/auto.tcl122
-rw-r--r--library/clock.tcl4695
-rw-r--r--library/dde/pkgIndex.tcl4
-rw-r--r--library/history.tcl2
-rw-r--r--library/http/http.tcl861
-rw-r--r--library/http/pkgIndex.tcl10
-rw-r--r--library/init.tcl278
-rw-r--r--library/ldAout.tcl231
-rw-r--r--library/msgcat/msgcat.tcl108
-rw-r--r--library/msgcat/pkgIndex.tcl4
-rwxr-xr-xlibrary/msgs/af.msg49
-rwxr-xr-xlibrary/msgs/af_za.msg6
-rwxr-xr-xlibrary/msgs/ar.msg54
-rwxr-xr-xlibrary/msgs/ar_in.msg6
-rwxr-xr-xlibrary/msgs/ar_jo.msg39
-rwxr-xr-xlibrary/msgs/ar_lb.msg39
-rwxr-xr-xlibrary/msgs/ar_sy.msg39
-rwxr-xr-xlibrary/msgs/be.msg52
-rwxr-xr-xlibrary/msgs/bg.msg52
-rwxr-xr-xlibrary/msgs/bn.msg49
-rwxr-xr-xlibrary/msgs/bn_in.msg6
-rwxr-xr-xlibrary/msgs/ca.msg50
-rwxr-xr-xlibrary/msgs/cs.msg54
-rwxr-xr-xlibrary/msgs/da.msg52
-rwxr-xr-xlibrary/msgs/de.msg54
-rwxr-xr-xlibrary/msgs/de_at.msg35
-rwxr-xr-xlibrary/msgs/de_be.msg53
-rwxr-xr-xlibrary/msgs/el.msg52
-rwxr-xr-xlibrary/msgs/en_au.msg7
-rwxr-xr-xlibrary/msgs/en_be.msg7
-rwxr-xr-xlibrary/msgs/en_bw.msg6
-rwxr-xr-xlibrary/msgs/en_ca.msg7
-rwxr-xr-xlibrary/msgs/en_gb.msg7
-rwxr-xr-xlibrary/msgs/en_hk.msg8
-rwxr-xr-xlibrary/msgs/en_ie.msg7
-rwxr-xr-xlibrary/msgs/en_in.msg8
-rwxr-xr-xlibrary/msgs/en_nz.msg7
-rwxr-xr-xlibrary/msgs/en_ph.msg8
-rwxr-xr-xlibrary/msgs/en_sg.msg6
-rwxr-xr-xlibrary/msgs/en_za.msg6
-rwxr-xr-xlibrary/msgs/en_zw.msg6
-rwxr-xr-xlibrary/msgs/eo.msg54
-rwxr-xr-xlibrary/msgs/es.msg52
-rwxr-xr-xlibrary/msgs/es_ar.msg6
-rwxr-xr-xlibrary/msgs/es_bo.msg6
-rwxr-xr-xlibrary/msgs/es_cl.msg6
-rwxr-xr-xlibrary/msgs/es_co.msg6
-rwxr-xr-xlibrary/msgs/es_cr.msg6
-rwxr-xr-xlibrary/msgs/es_do.msg6
-rwxr-xr-xlibrary/msgs/es_ec.msg6
-rwxr-xr-xlibrary/msgs/es_gt.msg6
-rwxr-xr-xlibrary/msgs/es_hn.msg6
-rwxr-xr-xlibrary/msgs/es_mx.msg6
-rwxr-xr-xlibrary/msgs/es_ni.msg6
-rwxr-xr-xlibrary/msgs/es_pa.msg6
-rwxr-xr-xlibrary/msgs/es_pe.msg6
-rwxr-xr-xlibrary/msgs/es_pr.msg6
-rwxr-xr-xlibrary/msgs/es_py.msg6
-rwxr-xr-xlibrary/msgs/es_sv.msg6
-rwxr-xr-xlibrary/msgs/es_uy.msg6
-rwxr-xr-xlibrary/msgs/es_ve.msg6
-rwxr-xr-xlibrary/msgs/et.msg52
-rwxr-xr-xlibrary/msgs/eu.msg47
-rwxr-xr-xlibrary/msgs/eu_es.msg7
-rwxr-xr-xlibrary/msgs/fa.msg47
-rwxr-xr-xlibrary/msgs/fa_in.msg52
-rwxr-xr-xlibrary/msgs/fa_ir.msg9
-rwxr-xr-xlibrary/msgs/fi.msg50
-rwxr-xr-xlibrary/msgs/fo.msg47
-rwxr-xr-xlibrary/msgs/fo_fo.msg7
-rwxr-xr-xlibrary/msgs/fr.msg52
-rwxr-xr-xlibrary/msgs/fr_be.msg7
-rwxr-xr-xlibrary/msgs/fr_ca.msg7
-rwxr-xr-xlibrary/msgs/fr_ch.msg7
-rwxr-xr-xlibrary/msgs/ga.msg47
-rwxr-xr-xlibrary/msgs/ga_ie.msg7
-rwxr-xr-xlibrary/msgs/gl.msg47
-rwxr-xr-xlibrary/msgs/gl_es.msg6
-rwxr-xr-xlibrary/msgs/gv.msg47
-rwxr-xr-xlibrary/msgs/gv_gb.msg6
-rwxr-xr-xlibrary/msgs/he.msg52
-rwxr-xr-xlibrary/msgs/hi.msg39
-rwxr-xr-xlibrary/msgs/hi_in.msg6
-rwxr-xr-xlibrary/msgs/hr.msg50
-rwxr-xr-xlibrary/msgs/hu.msg54
-rwxr-xr-xlibrary/msgs/id.msg47
-rwxr-xr-xlibrary/msgs/id_id.msg6
-rwxr-xr-xlibrary/msgs/is.msg50
-rwxr-xr-xlibrary/msgs/it.msg54
-rwxr-xr-xlibrary/msgs/it_ch.msg6
-rwxr-xr-xlibrary/msgs/ja.msg44
-rwxr-xr-xlibrary/msgs/kl.msg47
-rwxr-xr-xlibrary/msgs/kl_gl.msg7
-rwxr-xr-xlibrary/msgs/ko.msg55
-rwxr-xr-xlibrary/msgs/ko_kr.msg8
-rwxr-xr-xlibrary/msgs/kok.msg39
-rwxr-xr-xlibrary/msgs/kok_in.msg6
-rwxr-xr-xlibrary/msgs/kw.msg47
-rwxr-xr-xlibrary/msgs/kw_gb.msg6
-rwxr-xr-xlibrary/msgs/lt.msg52
-rwxr-xr-xlibrary/msgs/lv.msg52
-rwxr-xr-xlibrary/msgs/mk.msg52
-rwxr-xr-xlibrary/msgs/mr.msg39
-rwxr-xr-xlibrary/msgs/mr_in.msg6
-rwxr-xr-xlibrary/msgs/ms.msg47
-rwxr-xr-xlibrary/msgs/ms_my.msg6
-rwxr-xr-xlibrary/msgs/mt.msg27
-rwxr-xr-xlibrary/msgs/nb.msg52
-rwxr-xr-xlibrary/msgs/nl.msg50
-rwxr-xr-xlibrary/msgs/nl_be.msg7
-rwxr-xr-xlibrary/msgs/nn.msg52
-rwxr-xr-xlibrary/msgs/pl.msg52
-rwxr-xr-xlibrary/msgs/pt.msg50
-rwxr-xr-xlibrary/msgs/pt_br.msg7
-rwxr-xr-xlibrary/msgs/ro.msg52
-rwxr-xr-xlibrary/msgs/ru.msg52
-rwxr-xr-xlibrary/msgs/ru_ua.msg6
-rwxr-xr-xlibrary/msgs/sh.msg52
-rwxr-xr-xlibrary/msgs/sk.msg52
-rwxr-xr-xlibrary/msgs/sl.msg52
-rwxr-xr-xlibrary/msgs/sq.msg54
-rwxr-xr-xlibrary/msgs/sr.msg52
-rwxr-xr-xlibrary/msgs/sv.msg52
-rwxr-xr-xlibrary/msgs/sw.msg49
-rwxr-xr-xlibrary/msgs/ta.msg39
-rwxr-xr-xlibrary/msgs/ta_in.msg6
-rwxr-xr-xlibrary/msgs/te.msg47
-rwxr-xr-xlibrary/msgs/te_in.msg8
-rwxr-xr-xlibrary/msgs/th.msg54
-rwxr-xr-xlibrary/msgs/tr.msg50
-rwxr-xr-xlibrary/msgs/uk.msg52
-rwxr-xr-xlibrary/msgs/vi.msg50
-rwxr-xr-xlibrary/msgs/zh.msg55
-rwxr-xr-xlibrary/msgs/zh_cn.msg7
-rwxr-xr-xlibrary/msgs/zh_hk.msg28
-rwxr-xr-xlibrary/msgs/zh_sg.msg8
-rwxr-xr-xlibrary/msgs/zh_tw.msg8
-rw-r--r--library/opt/optparse.tcl10
-rw-r--r--library/opt/pkgIndex.tcl2
-rw-r--r--library/package.tcl264
-rw-r--r--library/parray.tcl5
-rwxr-xr-xlibrary/reg/pkgIndex.tcl8
-rw-r--r--library/safe.tcl1680
-rw-r--r--library/tclIndex10
-rw-r--r--library/tcltest/pkgIndex.tcl4
-rw-r--r--library/tcltest/tcltest.tcl82
-rw-r--r--library/tm.tcl380
-rw-r--r--library/tzdata/Africa/Abidjan6
-rw-r--r--library/tzdata/Africa/Accra20
-rw-r--r--library/tzdata/Africa/Addis_Ababa7
-rw-r--r--library/tzdata/Africa/Algiers39
-rwxr-xr-xlibrary/tzdata/Africa/Asmara8
-rw-r--r--library/tzdata/Africa/Asmera5
-rw-r--r--library/tzdata/Africa/Bamako8
-rw-r--r--library/tzdata/Africa/Bangui6
-rw-r--r--library/tzdata/Africa/Banjul8
-rw-r--r--library/tzdata/Africa/Bissau7
-rw-r--r--library/tzdata/Africa/Blantyre6
-rw-r--r--library/tzdata/Africa/Brazzaville6
-rw-r--r--library/tzdata/Africa/Bujumbura6
-rw-r--r--library/tzdata/Africa/Cairo128
-rw-r--r--library/tzdata/Africa/Casablanca32
-rw-r--r--library/tzdata/Africa/Ceuta258
-rw-r--r--library/tzdata/Africa/Conakry8
-rw-r--r--library/tzdata/Africa/Dakar7
-rw-r--r--library/tzdata/Africa/Dar_es_Salaam8
-rw-r--r--library/tzdata/Africa/Djibouti6
-rw-r--r--library/tzdata/Africa/Douala6
-rw-r--r--library/tzdata/Africa/El_Aaiun7
-rw-r--r--library/tzdata/Africa/Freetown36
-rw-r--r--library/tzdata/Africa/Gaborone8
-rw-r--r--library/tzdata/Africa/Harare6
-rw-r--r--library/tzdata/Africa/Johannesburg11
-rw-r--r--library/tzdata/Africa/Juba39
-rw-r--r--library/tzdata/Africa/Kampala9
-rw-r--r--library/tzdata/Africa/Khartoum39
-rw-r--r--library/tzdata/Africa/Kigali6
-rw-r--r--library/tzdata/Africa/Kinshasa6
-rw-r--r--library/tzdata/Africa/Lagos6
-rw-r--r--library/tzdata/Africa/Libreville6
-rw-r--r--library/tzdata/Africa/Lome6
-rw-r--r--library/tzdata/Africa/Luanda7
-rw-r--r--library/tzdata/Africa/Lubumbashi6
-rw-r--r--library/tzdata/Africa/Lusaka6
-rw-r--r--library/tzdata/Africa/Malabo7
-rw-r--r--library/tzdata/Africa/Maputo6
-rw-r--r--library/tzdata/Africa/Maseru8
-rw-r--r--library/tzdata/Africa/Mbabane6
-rw-r--r--library/tzdata/Africa/Mogadishu8
-rw-r--r--library/tzdata/Africa/Monrovia8
-rw-r--r--library/tzdata/Africa/Nairobi9
-rw-r--r--library/tzdata/Africa/Ndjamena8
-rw-r--r--library/tzdata/Africa/Niamey8
-rw-r--r--library/tzdata/Africa/Nouakchott8
-rw-r--r--library/tzdata/Africa/Ouagadougou6
-rw-r--r--library/tzdata/Africa/Porto-Novo7
-rw-r--r--library/tzdata/Africa/Sao_Tome7
-rw-r--r--library/tzdata/Africa/Timbuktu5
-rw-r--r--library/tzdata/Africa/Tripoli31
-rw-r--r--library/tzdata/Africa/Tunis39
-rw-r--r--library/tzdata/Africa/Windhoek222
-rw-r--r--library/tzdata/America/Adak276
-rw-r--r--library/tzdata/America/Anchorage276
-rw-r--r--library/tzdata/America/Anguilla6
-rw-r--r--library/tzdata/America/Antigua7
-rw-r--r--library/tzdata/America/Araguaina57
-rw-r--r--library/tzdata/America/Argentina/Buenos_Aires67
-rw-r--r--library/tzdata/America/Argentina/Catamarca68
-rw-r--r--library/tzdata/America/Argentina/ComodRivadavia5
-rw-r--r--library/tzdata/America/Argentina/Cordoba67
-rw-r--r--library/tzdata/America/Argentina/Jujuy67
-rw-r--r--library/tzdata/America/Argentina/La_Rioja69
-rw-r--r--library/tzdata/America/Argentina/Mendoza68
-rw-r--r--library/tzdata/America/Argentina/Rio_Gallegos68
-rw-r--r--library/tzdata/America/Argentina/Salta66
-rw-r--r--library/tzdata/America/Argentina/San_Juan69
-rw-r--r--library/tzdata/America/Argentina/San_Luis68
-rw-r--r--library/tzdata/America/Argentina/Tucuman69
-rw-r--r--library/tzdata/America/Argentina/Ushuaia68
-rw-r--r--library/tzdata/America/Aruba7
-rw-r--r--library/tzdata/America/Asuncion259
-rwxr-xr-xlibrary/tzdata/America/Atikokan12
-rw-r--r--library/tzdata/America/Atka5
-rw-r--r--library/tzdata/America/Bahia242
-rw-r--r--library/tzdata/America/Bahia_Banderas222
-rw-r--r--library/tzdata/America/Barbados15
-rw-r--r--library/tzdata/America/Belem35
-rw-r--r--library/tzdata/America/Belize60
-rwxr-xr-xlibrary/tzdata/America/Blanc-Sablon12
-rw-r--r--library/tzdata/America/Boa_Vista40
-rw-r--r--library/tzdata/America/Bogota9
-rw-r--r--library/tzdata/America/Boise281
-rw-r--r--library/tzdata/America/Buenos_Aires5
-rw-r--r--library/tzdata/America/Cambridge_Bay252
-rw-r--r--library/tzdata/America/Campo_Grande257
-rw-r--r--library/tzdata/America/Cancun216
-rw-r--r--library/tzdata/America/Caracas9
-rw-r--r--library/tzdata/America/Catamarca5
-rw-r--r--library/tzdata/America/Cayenne7
-rw-r--r--library/tzdata/America/Cayman7
-rw-r--r--library/tzdata/America/Chicago369
-rw-r--r--library/tzdata/America/Chihuahua221
-rw-r--r--library/tzdata/America/Coral_Harbour5
-rw-r--r--library/tzdata/America/Cordoba5
-rw-r--r--library/tzdata/America/Costa_Rica15
-rw-r--r--library/tzdata/America/Creston8
-rw-r--r--library/tzdata/America/Cuiaba257
-rw-r--r--library/tzdata/America/Curacao7
-rw-r--r--library/tzdata/America/Danmarkshavn39
-rw-r--r--library/tzdata/America/Dawson256
-rw-r--r--library/tzdata/America/Dawson_Creek64
-rw-r--r--library/tzdata/America/Denver291
-rw-r--r--library/tzdata/America/Detroit272
-rw-r--r--library/tzdata/America/Dominica6
-rw-r--r--library/tzdata/America/Edmonton284
-rw-r--r--library/tzdata/America/Eirunepe40
-rw-r--r--library/tzdata/America/El_Salvador10
-rw-r--r--library/tzdata/America/Ensenada5
-rw-r--r--library/tzdata/America/Fort_Wayne5
-rw-r--r--library/tzdata/America/Fortaleza48
-rw-r--r--library/tzdata/America/Glace_Bay273
-rw-r--r--library/tzdata/America/Godthab246
-rw-r--r--library/tzdata/America/Goose_Bay338
-rw-r--r--library/tzdata/America/Grand_Turk249
-rw-r--r--library/tzdata/America/Grenada6
-rw-r--r--library/tzdata/America/Guadeloupe6
-rw-r--r--library/tzdata/America/Guatemala14
-rw-r--r--library/tzdata/America/Guayaquil7
-rw-r--r--library/tzdata/America/Guyana9
-rw-r--r--library/tzdata/America/Halifax361
-rw-r--r--library/tzdata/America/Havana285
-rw-r--r--library/tzdata/America/Hermosillo21
-rw-r--r--library/tzdata/America/Indiana/Indianapolis234
-rw-r--r--library/tzdata/America/Indiana/Knox285
-rw-r--r--library/tzdata/America/Indiana/Marengo236
-rwxr-xr-xlibrary/tzdata/America/Indiana/Petersburg247
-rwxr-xr-xlibrary/tzdata/America/Indiana/Tell_City234
-rw-r--r--library/tzdata/America/Indiana/Vevay213
-rwxr-xr-xlibrary/tzdata/America/Indiana/Vincennes234
-rwxr-xr-xlibrary/tzdata/America/Indiana/Winamac240
-rw-r--r--library/tzdata/America/Indianapolis5
-rw-r--r--library/tzdata/America/Inuvik249
-rw-r--r--library/tzdata/America/Iqaluit250
-rw-r--r--library/tzdata/America/Jamaica28
-rw-r--r--library/tzdata/America/Jujuy5
-rw-r--r--library/tzdata/America/Juneau276
-rw-r--r--library/tzdata/America/Kentucky/Louisville314
-rw-r--r--library/tzdata/America/Kentucky/Monticello279
-rw-r--r--library/tzdata/America/Knox_IN5
-rw-r--r--library/tzdata/America/Kralendijk5
-rw-r--r--library/tzdata/America/La_Paz8
-rw-r--r--library/tzdata/America/Lima16
-rw-r--r--library/tzdata/America/Los_Angeles317
-rw-r--r--library/tzdata/America/Louisville5
-rw-r--r--library/tzdata/America/Lower_Princes5
-rw-r--r--library/tzdata/America/Maceio52
-rw-r--r--library/tzdata/America/Managua21
-rw-r--r--library/tzdata/America/Manaus39
-rw-r--r--library/tzdata/America/Marigot5
-rw-r--r--library/tzdata/America/Martinique9
-rw-r--r--library/tzdata/America/Matamoros219
-rw-r--r--library/tzdata/America/Mazatlan222
-rw-r--r--library/tzdata/America/Mendoza5
-rw-r--r--library/tzdata/America/Menominee274
-rw-r--r--library/tzdata/America/Merida216
-rw-r--r--library/tzdata/America/Metlakatla43
-rw-r--r--library/tzdata/America/Mexico_City228
-rw-r--r--library/tzdata/America/Miquelon234
-rwxr-xr-xlibrary/tzdata/America/Moncton342
-rw-r--r--library/tzdata/America/Monterrey218
-rw-r--r--library/tzdata/America/Montevideo261
-rw-r--r--library/tzdata/America/Montreal366
-rw-r--r--library/tzdata/America/Montserrat6
-rw-r--r--library/tzdata/America/Nassau279
-rw-r--r--library/tzdata/America/New_York369
-rw-r--r--library/tzdata/America/Nipigon264
-rw-r--r--library/tzdata/America/Nome276
-rw-r--r--library/tzdata/America/Noronha48
-rw-r--r--library/tzdata/America/North_Dakota/Beulah279
-rw-r--r--library/tzdata/America/North_Dakota/Center279
-rwxr-xr-xlibrary/tzdata/America/North_Dakota/New_Salem279
-rw-r--r--library/tzdata/America/Ojinaga222
-rw-r--r--library/tzdata/America/Panama7
-rw-r--r--library/tzdata/America/Pangnirtung252
-rw-r--r--library/tzdata/America/Paramaribo10
-rw-r--r--library/tzdata/America/Phoenix17
-rw-r--r--library/tzdata/America/Port-au-Prince41
-rw-r--r--library/tzdata/America/Port_of_Spain6
-rw-r--r--library/tzdata/America/Porto_Acre5
-rw-r--r--library/tzdata/America/Porto_Velho35
-rw-r--r--library/tzdata/America/Puerto_Rico10
-rw-r--r--library/tzdata/America/Rainy_River264
-rw-r--r--library/tzdata/America/Rankin_Inlet248
-rw-r--r--library/tzdata/America/Recife48
-rw-r--r--library/tzdata/America/Regina58
-rwxr-xr-xlibrary/tzdata/America/Resolute248
-rw-r--r--library/tzdata/America/Rio_Branco36
-rw-r--r--library/tzdata/America/Rosario5
-rw-r--r--library/tzdata/America/Santa_Isabel284
-rw-r--r--library/tzdata/America/Santarem36
-rw-r--r--library/tzdata/America/Santiago291
-rw-r--r--library/tzdata/America/Santo_Domingo21
-rw-r--r--library/tzdata/America/Sao_Paulo258
-rw-r--r--library/tzdata/America/Scoresbysund246
-rw-r--r--library/tzdata/America/Shiprock5
-rw-r--r--library/tzdata/America/Sitka275
-rw-r--r--library/tzdata/America/St_Barthelemy5
-rw-r--r--library/tzdata/America/St_Johns372
-rw-r--r--library/tzdata/America/St_Kitts6
-rw-r--r--library/tzdata/America/St_Lucia7
-rw-r--r--library/tzdata/America/St_Thomas6
-rw-r--r--library/tzdata/America/St_Vincent7
-rw-r--r--library/tzdata/America/Swift_Current29
-rw-r--r--library/tzdata/America/Tegucigalpa12
-rw-r--r--library/tzdata/America/Thule224
-rw-r--r--library/tzdata/America/Thunder_Bay272
-rw-r--r--library/tzdata/America/Tijuana285
-rw-r--r--library/tzdata/America/Toronto365
-rw-r--r--library/tzdata/America/Tortola6
-rw-r--r--library/tzdata/America/Vancouver320
-rw-r--r--library/tzdata/America/Virgin5
-rw-r--r--library/tzdata/America/Whitehorse256
-rw-r--r--library/tzdata/America/Winnipeg316
-rw-r--r--library/tzdata/America/Yakutat276
-rw-r--r--library/tzdata/America/Yellowknife252
-rw-r--r--library/tzdata/Antarctica/Casey10
-rw-r--r--library/tzdata/Antarctica/Davis12
-rw-r--r--library/tzdata/Antarctica/DumontDUrville8
-rw-r--r--library/tzdata/Antarctica/Macquarie102
-rw-r--r--library/tzdata/Antarctica/Mawson7
-rw-r--r--library/tzdata/Antarctica/McMurdo257
-rw-r--r--library/tzdata/Antarctica/Palmer254
-rw-r--r--library/tzdata/Antarctica/Rothera6
-rw-r--r--library/tzdata/Antarctica/South_Pole5
-rw-r--r--library/tzdata/Antarctica/Syowa6
-rw-r--r--library/tzdata/Antarctica/Vostok6
-rw-r--r--library/tzdata/Arctic/Longyearbyen5
-rw-r--r--library/tzdata/Asia/Aden6
-rw-r--r--library/tzdata/Asia/Almaty56
-rw-r--r--library/tzdata/Asia/Amman248
-rw-r--r--library/tzdata/Asia/Anadyr72
-rw-r--r--library/tzdata/Asia/Aqtau58
-rw-r--r--library/tzdata/Asia/Aqtobe57
-rw-r--r--library/tzdata/Asia/Ashgabat31
-rw-r--r--library/tzdata/Asia/Ashkhabad5
-rw-r--r--library/tzdata/Asia/Baghdad59
-rw-r--r--library/tzdata/Asia/Bahrain7
-rw-r--r--library/tzdata/Asia/Baku242
-rw-r--r--library/tzdata/Asia/Bangkok7
-rw-r--r--library/tzdata/Asia/Beirut270
-rw-r--r--library/tzdata/Asia/Bishkek57
-rw-r--r--library/tzdata/Asia/Brunei7
-rw-r--r--library/tzdata/Asia/Calcutta5
-rw-r--r--library/tzdata/Asia/Choibalsan51
-rw-r--r--library/tzdata/Asia/Chongqing19
-rw-r--r--library/tzdata/Asia/Chungking5
-rw-r--r--library/tzdata/Asia/Colombo13
-rw-r--r--library/tzdata/Asia/Dacca5
-rw-r--r--library/tzdata/Asia/Damascus280
-rw-r--r--library/tzdata/Asia/Dhaka14
-rw-r--r--library/tzdata/Asia/Dili10
-rw-r--r--library/tzdata/Asia/Dubai6
-rw-r--r--library/tzdata/Asia/Dushanbe29
-rw-r--r--library/tzdata/Asia/Gaza99
-rw-r--r--library/tzdata/Asia/Harbin22
-rw-r--r--library/tzdata/Asia/Hebron102
-rw-r--r--library/tzdata/Asia/Ho_Chi_Minh9
-rw-r--r--library/tzdata/Asia/Hong_Kong75
-rw-r--r--library/tzdata/Asia/Hovd51
-rw-r--r--library/tzdata/Asia/Irkutsk71
-rw-r--r--library/tzdata/Asia/Istanbul5
-rw-r--r--library/tzdata/Asia/Jakarta13
-rw-r--r--library/tzdata/Asia/Jayapura8
-rw-r--r--library/tzdata/Asia/Jerusalem148
-rw-r--r--library/tzdata/Asia/Kabul7
-rw-r--r--library/tzdata/Asia/Kamchatka71
-rw-r--r--library/tzdata/Asia/Karachi16
-rw-r--r--library/tzdata/Asia/Kashgar20
-rw-r--r--library/tzdata/Asia/Kathmandu7
-rw-r--r--library/tzdata/Asia/Katmandu5
-rw-r--r--library/tzdata/Asia/Kolkata10
-rw-r--r--library/tzdata/Asia/Krasnoyarsk70
-rw-r--r--library/tzdata/Asia/Kuala_Lumpur13
-rw-r--r--library/tzdata/Asia/Kuching24
-rw-r--r--library/tzdata/Asia/Kuwait6
-rw-r--r--library/tzdata/Asia/Macao5
-rw-r--r--library/tzdata/Asia/Macau46
-rw-r--r--library/tzdata/Asia/Magadan70
-rw-r--r--library/tzdata/Asia/Makassar9
-rw-r--r--library/tzdata/Asia/Manila15
-rw-r--r--library/tzdata/Asia/Muscat6
-rw-r--r--library/tzdata/Asia/Nicosia257
-rw-r--r--library/tzdata/Asia/Novokuznetsk71
-rw-r--r--library/tzdata/Asia/Novosibirsk71
-rw-r--r--library/tzdata/Asia/Omsk70
-rw-r--r--library/tzdata/Asia/Oral58
-rw-r--r--library/tzdata/Asia/Phnom_Penh9
-rw-r--r--library/tzdata/Asia/Pontianak13
-rw-r--r--library/tzdata/Asia/Pyongyang11
-rw-r--r--library/tzdata/Asia/Qatar7
-rw-r--r--library/tzdata/Asia/Qyzylorda58
-rw-r--r--library/tzdata/Asia/Rangoon9
-rw-r--r--library/tzdata/Asia/Riyadh6
-rw-r--r--library/tzdata/Asia/Saigon5
-rw-r--r--library/tzdata/Asia/Sakhalin72
-rw-r--r--library/tzdata/Asia/Samarkand32
-rw-r--r--library/tzdata/Asia/Seoul18
-rw-r--r--library/tzdata/Asia/Shanghai23
-rw-r--r--library/tzdata/Asia/Singapore14
-rw-r--r--library/tzdata/Asia/Taipei46
-rw-r--r--library/tzdata/Asia/Tashkent32
-rw-r--r--library/tzdata/Asia/Tbilisi60
-rw-r--r--library/tzdata/Asia/Tehran105
-rw-r--r--library/tzdata/Asia/Tel_Aviv5
-rw-r--r--library/tzdata/Asia/Thimbu5
-rw-r--r--library/tzdata/Asia/Thimphu7
-rw-r--r--library/tzdata/Asia/Tokyo16
-rw-r--r--library/tzdata/Asia/Ujung_Pandang5
-rw-r--r--library/tzdata/Asia/Ulaanbaatar51
-rw-r--r--library/tzdata/Asia/Ulan_Bator5
-rw-r--r--library/tzdata/Asia/Urumqi19
-rw-r--r--library/tzdata/Asia/Vientiane9
-rw-r--r--library/tzdata/Asia/Vladivostok70
-rw-r--r--library/tzdata/Asia/Yakutsk70
-rw-r--r--library/tzdata/Asia/Yekaterinburg70
-rw-r--r--library/tzdata/Asia/Yerevan70
-rw-r--r--library/tzdata/Atlantic/Azores349
-rw-r--r--library/tzdata/Atlantic/Bermuda259
-rw-r--r--library/tzdata/Atlantic/Canary248
-rw-r--r--library/tzdata/Atlantic/Cape_Verde9
-rw-r--r--library/tzdata/Atlantic/Faeroe5
-rwxr-xr-xlibrary/tzdata/Atlantic/Faroe245
-rw-r--r--library/tzdata/Atlantic/Jan_Mayen5
-rw-r--r--library/tzdata/Atlantic/Madeira350
-rw-r--r--library/tzdata/Atlantic/Reykjavik70
-rw-r--r--library/tzdata/Atlantic/South_Georgia6
-rw-r--r--library/tzdata/Atlantic/St_Helena7
-rw-r--r--library/tzdata/Atlantic/Stanley75
-rw-r--r--library/tzdata/Australia/ACT5
-rw-r--r--library/tzdata/Australia/Adelaide273
-rw-r--r--library/tzdata/Australia/Brisbane23
-rw-r--r--library/tzdata/Australia/Broken_Hill275
-rw-r--r--library/tzdata/Australia/Canberra5
-rw-r--r--library/tzdata/Australia/Currie273
-rw-r--r--library/tzdata/Australia/Darwin15
-rwxr-xr-xlibrary/tzdata/Australia/Eucla25
-rw-r--r--library/tzdata/Australia/Hobart281
-rw-r--r--library/tzdata/Australia/LHI5
-rw-r--r--library/tzdata/Australia/Lindeman28
-rw-r--r--library/tzdata/Australia/Lord_Howe244
-rw-r--r--library/tzdata/Australia/Melbourne272
-rw-r--r--library/tzdata/Australia/NSW5
-rw-r--r--library/tzdata/Australia/North5
-rw-r--r--library/tzdata/Australia/Perth25
-rw-r--r--library/tzdata/Australia/Queensland5
-rw-r--r--library/tzdata/Australia/South5
-rw-r--r--library/tzdata/Australia/Sydney272
-rw-r--r--library/tzdata/Australia/Tasmania5
-rw-r--r--library/tzdata/Australia/Victoria5
-rw-r--r--library/tzdata/Australia/West5
-rw-r--r--library/tzdata/Australia/Yancowinna5
-rw-r--r--library/tzdata/Brazil/Acre5
-rw-r--r--library/tzdata/Brazil/DeNoronha5
-rw-r--r--library/tzdata/Brazil/East5
-rw-r--r--library/tzdata/Brazil/West5
-rw-r--r--library/tzdata/CET265
-rw-r--r--library/tzdata/CST6CDT278
-rw-r--r--library/tzdata/Canada/Atlantic5
-rw-r--r--library/tzdata/Canada/Central5
-rw-r--r--library/tzdata/Canada/East-Saskatchewan5
-rw-r--r--library/tzdata/Canada/Eastern5
-rw-r--r--library/tzdata/Canada/Mountain5
-rw-r--r--library/tzdata/Canada/Newfoundland5
-rw-r--r--library/tzdata/Canada/Pacific5
-rw-r--r--library/tzdata/Canada/Saskatchewan5
-rw-r--r--library/tzdata/Canada/Yukon5
-rw-r--r--library/tzdata/Chile/Continental5
-rw-r--r--library/tzdata/Chile/EasterIsland5
-rw-r--r--library/tzdata/Cuba5
-rw-r--r--library/tzdata/EET251
-rw-r--r--library/tzdata/EST5
-rw-r--r--library/tzdata/EST5EDT278
-rw-r--r--library/tzdata/Egypt5
-rw-r--r--library/tzdata/Eire5
-rw-r--r--library/tzdata/Etc/GMT5
-rw-r--r--library/tzdata/Etc/GMT+05
-rw-r--r--library/tzdata/Etc/GMT+15
-rw-r--r--library/tzdata/Etc/GMT+105
-rw-r--r--library/tzdata/Etc/GMT+115
-rw-r--r--library/tzdata/Etc/GMT+125
-rw-r--r--library/tzdata/Etc/GMT+25
-rw-r--r--library/tzdata/Etc/GMT+35
-rw-r--r--library/tzdata/Etc/GMT+45
-rw-r--r--library/tzdata/Etc/GMT+55
-rw-r--r--library/tzdata/Etc/GMT+65
-rw-r--r--library/tzdata/Etc/GMT+75
-rw-r--r--library/tzdata/Etc/GMT+85
-rw-r--r--library/tzdata/Etc/GMT+95
-rw-r--r--library/tzdata/Etc/GMT-05
-rw-r--r--library/tzdata/Etc/GMT-15
-rw-r--r--library/tzdata/Etc/GMT-105
-rw-r--r--library/tzdata/Etc/GMT-115
-rw-r--r--library/tzdata/Etc/GMT-125
-rw-r--r--library/tzdata/Etc/GMT-135
-rw-r--r--library/tzdata/Etc/GMT-145
-rw-r--r--library/tzdata/Etc/GMT-25
-rw-r--r--library/tzdata/Etc/GMT-35
-rw-r--r--library/tzdata/Etc/GMT-45
-rw-r--r--library/tzdata/Etc/GMT-55
-rw-r--r--library/tzdata/Etc/GMT-65
-rw-r--r--library/tzdata/Etc/GMT-75
-rw-r--r--library/tzdata/Etc/GMT-85
-rw-r--r--library/tzdata/Etc/GMT-95
-rw-r--r--library/tzdata/Etc/GMT05
-rw-r--r--library/tzdata/Etc/Greenwich5
-rw-r--r--library/tzdata/Etc/UCT5
-rw-r--r--library/tzdata/Etc/UTC5
-rw-r--r--library/tzdata/Etc/Universal5
-rw-r--r--library/tzdata/Etc/Zulu5
-rw-r--r--library/tzdata/Europe/Amsterdam310
-rw-r--r--library/tzdata/Europe/Andorra237
-rw-r--r--library/tzdata/Europe/Athens268
-rw-r--r--library/tzdata/Europe/Belfast5
-rw-r--r--library/tzdata/Europe/Belgrade250
-rw-r--r--library/tzdata/Europe/Berlin274
-rw-r--r--library/tzdata/Europe/Bratislava5
-rw-r--r--library/tzdata/Europe/Brussels316
-rw-r--r--library/tzdata/Europe/Bucharest268
-rw-r--r--library/tzdata/Europe/Budapest284
-rw-r--r--library/tzdata/Europe/Chisinau272
-rw-r--r--library/tzdata/Europe/Copenhagen264
-rw-r--r--library/tzdata/Europe/Dublin359
-rw-r--r--library/tzdata/Europe/Gibraltar328
-rwxr-xr-xlibrary/tzdata/Europe/Guernsey5
-rw-r--r--library/tzdata/Europe/Helsinki248
-rwxr-xr-xlibrary/tzdata/Europe/Isle_of_Man5
-rw-r--r--library/tzdata/Europe/Istanbul304
-rwxr-xr-xlibrary/tzdata/Europe/Jersey5
-rw-r--r--library/tzdata/Europe/Kaliningrad84
-rw-r--r--library/tzdata/Europe/Kiev251
-rw-r--r--library/tzdata/Europe/Lisbon351
-rw-r--r--library/tzdata/Europe/Ljubljana5
-rw-r--r--library/tzdata/Europe/London372
-rw-r--r--library/tzdata/Europe/Luxembourg313
-rw-r--r--library/tzdata/Europe/Madrid294
-rw-r--r--library/tzdata/Europe/Malta299
-rw-r--r--library/tzdata/Europe/Mariehamn5
-rw-r--r--library/tzdata/Europe/Minsk74
-rw-r--r--library/tzdata/Europe/Monaco315
-rw-r--r--library/tzdata/Europe/Moscow83
-rw-r--r--library/tzdata/Europe/Nicosia5
-rw-r--r--library/tzdata/Europe/Oslo271
-rw-r--r--library/tzdata/Europe/Paris314
-rwxr-xr-xlibrary/tzdata/Europe/Podgorica5
-rw-r--r--library/tzdata/Europe/Prague272
-rw-r--r--library/tzdata/Europe/Riga258
-rw-r--r--library/tzdata/Europe/Rome301
-rw-r--r--library/tzdata/Europe/Samara73
-rw-r--r--library/tzdata/Europe/San_Marino5
-rw-r--r--library/tzdata/Europe/Sarajevo5
-rw-r--r--library/tzdata/Europe/Simferopol253
-rw-r--r--library/tzdata/Europe/Skopje5
-rw-r--r--library/tzdata/Europe/Sofia259
-rw-r--r--library/tzdata/Europe/Stockholm250
-rw-r--r--library/tzdata/Europe/Tallinn255
-rw-r--r--library/tzdata/Europe/Tirane263
-rw-r--r--library/tzdata/Europe/Tiraspol5
-rw-r--r--library/tzdata/Europe/Uzhgorod254
-rw-r--r--library/tzdata/Europe/Vaduz245
-rw-r--r--library/tzdata/Europe/Vatican5
-rw-r--r--library/tzdata/Europe/Vienna271
-rw-r--r--library/tzdata/Europe/Vilnius251
-rwxr-xr-xlibrary/tzdata/Europe/Volgograd70
-rw-r--r--library/tzdata/Europe/Warsaw296
-rw-r--r--library/tzdata/Europe/Zagreb5
-rw-r--r--library/tzdata/Europe/Zaporozhye252
-rw-r--r--library/tzdata/Europe/Zurich250
-rw-r--r--library/tzdata/GB5
-rw-r--r--library/tzdata/GB-Eire5
-rw-r--r--library/tzdata/GMT5
-rw-r--r--library/tzdata/GMT+05
-rw-r--r--library/tzdata/GMT-05
-rw-r--r--library/tzdata/GMT05
-rw-r--r--library/tzdata/Greenwich5
-rw-r--r--library/tzdata/HST5
-rw-r--r--library/tzdata/Hongkong5
-rw-r--r--library/tzdata/Iceland5
-rw-r--r--library/tzdata/Indian/Antananarivo8
-rw-r--r--library/tzdata/Indian/Chagos7
-rw-r--r--library/tzdata/Indian/Christmas6
-rw-r--r--library/tzdata/Indian/Cocos6
-rw-r--r--library/tzdata/Indian/Comoro6
-rw-r--r--library/tzdata/Indian/Kerguelen6
-rw-r--r--library/tzdata/Indian/Mahe6
-rw-r--r--library/tzdata/Indian/Maldives7
-rw-r--r--library/tzdata/Indian/Mauritius10
-rw-r--r--library/tzdata/Indian/Mayotte6
-rw-r--r--library/tzdata/Indian/Reunion6
-rw-r--r--library/tzdata/Iran5
-rw-r--r--library/tzdata/Israel5
-rw-r--r--library/tzdata/Jamaica5
-rw-r--r--library/tzdata/Japan5
-rw-r--r--library/tzdata/Kwajalein5
-rw-r--r--library/tzdata/Libya5
-rw-r--r--library/tzdata/MET265
-rw-r--r--library/tzdata/MST5
-rw-r--r--library/tzdata/MST7MDT278
-rw-r--r--library/tzdata/Mexico/BajaNorte5
-rw-r--r--library/tzdata/Mexico/BajaSur5
-rw-r--r--library/tzdata/Mexico/General5
-rw-r--r--library/tzdata/NZ5
-rw-r--r--library/tzdata/NZ-CHAT5
-rw-r--r--library/tzdata/Navajo5
-rw-r--r--library/tzdata/PRC5
-rw-r--r--library/tzdata/PST8PDT278
-rw-r--r--library/tzdata/Pacific/Apia13
-rw-r--r--library/tzdata/Pacific/Auckland285
-rw-r--r--library/tzdata/Pacific/Chatham257
-rw-r--r--library/tzdata/Pacific/Chuuk6
-rw-r--r--library/tzdata/Pacific/Easter275
-rw-r--r--library/tzdata/Pacific/Efate26
-rw-r--r--library/tzdata/Pacific/Enderbury8
-rw-r--r--library/tzdata/Pacific/Fakaofo7
-rw-r--r--library/tzdata/Pacific/Fiji16
-rw-r--r--library/tzdata/Pacific/Funafuti6
-rw-r--r--library/tzdata/Pacific/Galapagos7
-rw-r--r--library/tzdata/Pacific/Gambier6
-rw-r--r--library/tzdata/Pacific/Guadalcanal6
-rw-r--r--library/tzdata/Pacific/Guam8
-rw-r--r--library/tzdata/Pacific/Honolulu11
-rw-r--r--library/tzdata/Pacific/Johnston5
-rw-r--r--library/tzdata/Pacific/Kiritimati8
-rw-r--r--library/tzdata/Pacific/Kosrae8
-rw-r--r--library/tzdata/Pacific/Kwajalein8
-rw-r--r--library/tzdata/Pacific/Majuro7
-rw-r--r--library/tzdata/Pacific/Marquesas6
-rw-r--r--library/tzdata/Pacific/Midway10
-rw-r--r--library/tzdata/Pacific/Nauru9
-rw-r--r--library/tzdata/Pacific/Niue8
-rw-r--r--library/tzdata/Pacific/Norfolk7
-rw-r--r--library/tzdata/Pacific/Noumea12
-rw-r--r--library/tzdata/Pacific/Pago_Pago10
-rw-r--r--library/tzdata/Pacific/Palau6
-rw-r--r--library/tzdata/Pacific/Pitcairn7
-rw-r--r--library/tzdata/Pacific/Pohnpei6
-rw-r--r--library/tzdata/Pacific/Ponape5
-rw-r--r--library/tzdata/Pacific/Port_Moresby7
-rw-r--r--library/tzdata/Pacific/Rarotonga32
-rw-r--r--library/tzdata/Pacific/Saipan9
-rw-r--r--library/tzdata/Pacific/Samoa5
-rw-r--r--library/tzdata/Pacific/Tahiti6
-rw-r--r--library/tzdata/Pacific/Tarawa6
-rw-r--r--library/tzdata/Pacific/Tongatapu14
-rw-r--r--library/tzdata/Pacific/Truk5
-rw-r--r--library/tzdata/Pacific/Wake6
-rw-r--r--library/tzdata/Pacific/Wallis6
-rw-r--r--library/tzdata/Pacific/Yap5
-rw-r--r--library/tzdata/Poland5
-rw-r--r--library/tzdata/Portugal5
-rw-r--r--library/tzdata/ROC5
-rw-r--r--library/tzdata/ROK5
-rw-r--r--library/tzdata/Singapore5
-rw-r--r--library/tzdata/SystemV/AST45
-rw-r--r--library/tzdata/SystemV/AST4ADT5
-rw-r--r--library/tzdata/SystemV/CST65
-rw-r--r--library/tzdata/SystemV/CST6CDT5
-rw-r--r--library/tzdata/SystemV/EST55
-rw-r--r--library/tzdata/SystemV/EST5EDT5
-rw-r--r--library/tzdata/SystemV/HST105
-rw-r--r--library/tzdata/SystemV/MST75
-rw-r--r--library/tzdata/SystemV/MST7MDT5
-rw-r--r--library/tzdata/SystemV/PST85
-rw-r--r--library/tzdata/SystemV/PST8PDT5
-rw-r--r--library/tzdata/SystemV/YST95
-rw-r--r--library/tzdata/SystemV/YST9YDT5
-rw-r--r--library/tzdata/Turkey5
-rw-r--r--library/tzdata/UCT5
-rw-r--r--library/tzdata/US/Alaska5
-rw-r--r--library/tzdata/US/Aleutian5
-rw-r--r--library/tzdata/US/Arizona5
-rw-r--r--library/tzdata/US/Central5
-rw-r--r--library/tzdata/US/East-Indiana5
-rw-r--r--library/tzdata/US/Eastern5
-rw-r--r--library/tzdata/US/Hawaii5
-rw-r--r--library/tzdata/US/Indiana-Starke5
-rw-r--r--library/tzdata/US/Michigan5
-rw-r--r--library/tzdata/US/Mountain5
-rw-r--r--library/tzdata/US/Pacific5
-rw-r--r--library/tzdata/US/Pacific-New5
-rw-r--r--library/tzdata/US/Samoa5
-rw-r--r--library/tzdata/UTC5
-rw-r--r--library/tzdata/Universal5
-rw-r--r--library/tzdata/W-SU5
-rw-r--r--library/tzdata/WET251
-rw-r--r--library/tzdata/Zulu5
-rw-r--r--library/word.tcl142
-rw-r--r--libtommath/LICENSE4
-rw-r--r--libtommath/bn.ilg6
-rw-r--r--libtommath/bn.ind82
-rw-r--r--libtommath/bn.pdfbin0 -> 340921 bytes
-rw-r--r--libtommath/bn.tex1835
-rw-r--r--libtommath/bn_error.c43
-rw-r--r--libtommath/bn_fast_mp_invmod.c144
-rw-r--r--libtommath/bn_fast_mp_montgomery_reduce.c168
-rw-r--r--libtommath/bn_fast_s_mp_mul_digs.c103
-rw-r--r--libtommath/bn_fast_s_mp_mul_high_digs.c94
-rw-r--r--libtommath/bn_fast_s_mp_sqr.c110
-rw-r--r--libtommath/bn_mp_2expt.c44
-rw-r--r--libtommath/bn_mp_abs.c39
-rw-r--r--libtommath/bn_mp_add.c49
-rw-r--r--libtommath/bn_mp_add_d.c109
-rw-r--r--libtommath/bn_mp_addmod.c37
-rw-r--r--libtommath/bn_mp_and.c53
-rw-r--r--libtommath/bn_mp_clamp.c40
-rw-r--r--libtommath/bn_mp_clear.c40
-rw-r--r--libtommath/bn_mp_clear_multi.c30
-rw-r--r--libtommath/bn_mp_cmp.c39
-rw-r--r--libtommath/bn_mp_cmp_d.c40
-rw-r--r--libtommath/bn_mp_cmp_mag.c51
-rw-r--r--libtommath/bn_mp_cnt_lsb.c49
-rw-r--r--libtommath/bn_mp_copy.c64
-rw-r--r--libtommath/bn_mp_count_bits.c41
-rw-r--r--libtommath/bn_mp_div.c288
-rw-r--r--libtommath/bn_mp_div_2.c64
-rw-r--r--libtommath/bn_mp_div_2d.c93
-rw-r--r--libtommath/bn_mp_div_3.c75
-rw-r--r--libtommath/bn_mp_div_d.c110
-rw-r--r--libtommath/bn_mp_dr_is_modulus.c39
-rw-r--r--libtommath/bn_mp_dr_reduce.c90
-rw-r--r--libtommath/bn_mp_dr_setup.c28
-rw-r--r--libtommath/bn_mp_exch.c30
-rw-r--r--libtommath/bn_mp_expt_d.c53
-rw-r--r--libtommath/bn_mp_exptmod.c108
-rw-r--r--libtommath/bn_mp_exptmod_fast.c316
-rw-r--r--libtommath/bn_mp_exteuclid.c78
-rw-r--r--libtommath/bn_mp_fread.c63
-rw-r--r--libtommath/bn_mp_fwrite.c48
-rw-r--r--libtommath/bn_mp_gcd.c101
-rw-r--r--libtommath/bn_mp_get_int.c41
-rw-r--r--libtommath/bn_mp_grow.c53
-rw-r--r--libtommath/bn_mp_init.c42
-rw-r--r--libtommath/bn_mp_init_copy.c28
-rw-r--r--libtommath/bn_mp_init_multi.c55
-rw-r--r--libtommath/bn_mp_init_set.c28
-rw-r--r--libtommath/bn_mp_init_set_int.c27
-rw-r--r--libtommath/bn_mp_init_size.c44
-rw-r--r--libtommath/bn_mp_invmod.c39
-rw-r--r--libtommath/bn_mp_invmod_slow.c171
-rw-r--r--libtommath/bn_mp_is_square.c105
-rw-r--r--libtommath/bn_mp_jacobi.c101
-rw-r--r--libtommath/bn_mp_karatsuba_mul.c163
-rw-r--r--libtommath/bn_mp_karatsuba_sqr.c117
-rw-r--r--libtommath/bn_mp_lcm.c56
-rw-r--r--libtommath/bn_mp_lshd.c63
-rw-r--r--libtommath/bn_mp_mod.c44
-rw-r--r--libtommath/bn_mp_mod_2d.c51
-rw-r--r--libtommath/bn_mp_mod_d.c23
-rw-r--r--libtommath/bn_mp_montgomery_calc_normalization.c55
-rw-r--r--libtommath/bn_mp_montgomery_reduce.c114
-rw-r--r--libtommath/bn_mp_montgomery_setup.c55
-rw-r--r--libtommath/bn_mp_mul.c62
-rw-r--r--libtommath/bn_mp_mul_2.c78
-rw-r--r--libtommath/bn_mp_mul_2d.c81
-rw-r--r--libtommath/bn_mp_mul_d.c75
-rw-r--r--libtommath/bn_mp_mulmod.c36
-rw-r--r--libtommath/bn_mp_n_root.c128
-rw-r--r--libtommath/bn_mp_neg.c36
-rw-r--r--libtommath/bn_mp_or.c46
-rw-r--r--libtommath/bn_mp_prime_fermat.c58
-rw-r--r--libtommath/bn_mp_prime_is_divisible.c46
-rw-r--r--libtommath/bn_mp_prime_is_prime.c79
-rw-r--r--libtommath/bn_mp_prime_miller_rabin.c99
-rw-r--r--libtommath/bn_mp_prime_next_prime.c166
-rw-r--r--libtommath/bn_mp_prime_rabin_miller_trials.c48
-rw-r--r--libtommath/bn_mp_prime_random_ex.c121
-rw-r--r--libtommath/bn_mp_radix_size.c83
-rw-r--r--libtommath/bn_mp_radix_smap.c20
-rw-r--r--libtommath/bn_mp_rand.c51
-rw-r--r--libtommath/bn_mp_read_radix.c88
-rw-r--r--libtommath/bn_mp_read_signed_bin.c37
-rw-r--r--libtommath/bn_mp_read_unsigned_bin.c51
-rw-r--r--libtommath/bn_mp_reduce.c96
-rw-r--r--libtommath/bn_mp_reduce_2k.c57
-rw-r--r--libtommath/bn_mp_reduce_2k_l.c58
-rw-r--r--libtommath/bn_mp_reduce_2k_setup.c43
-rw-r--r--libtommath/bn_mp_reduce_2k_setup_l.c40
-rw-r--r--libtommath/bn_mp_reduce_is_2k.c48
-rw-r--r--libtommath/bn_mp_reduce_is_2k_l.c40
-rw-r--r--libtommath/bn_mp_reduce_setup.c30
-rw-r--r--libtommath/bn_mp_rshd.c68
-rw-r--r--libtommath/bn_mp_set.c25
-rw-r--r--libtommath/bn_mp_set_int.c44
-rw-r--r--libtommath/bn_mp_shrink.c36
-rw-r--r--libtommath/bn_mp_signed_bin_size.c23
-rw-r--r--libtommath/bn_mp_sqr.c54
-rw-r--r--libtommath/bn_mp_sqrmod.c37
-rw-r--r--libtommath/bn_mp_sqrt.c142
-rw-r--r--libtommath/bn_mp_sub.c55
-rw-r--r--libtommath/bn_mp_sub_d.c89
-rw-r--r--libtommath/bn_mp_submod.c38
-rw-r--r--libtommath/bn_mp_to_signed_bin.c29
-rw-r--r--libtommath/bn_mp_to_signed_bin_n.c27
-rw-r--r--libtommath/bn_mp_to_unsigned_bin.c44
-rw-r--r--libtommath/bn_mp_to_unsigned_bin_n.c27
-rw-r--r--libtommath/bn_mp_toom_mul.c280
-rw-r--r--libtommath/bn_mp_toom_sqr.c222
-rw-r--r--libtommath/bn_mp_toradix.c71
-rw-r--r--libtommath/bn_mp_toradix_n.c84
-rw-r--r--libtommath/bn_mp_unsigned_bin_size.c24
-rw-r--r--libtommath/bn_mp_xor.c47
-rw-r--r--libtommath/bn_mp_zero.c32
-rw-r--r--libtommath/bn_prime_tab.c57
-rw-r--r--libtommath/bn_reverse.c35
-rw-r--r--libtommath/bn_s_mp_add.c105
-rw-r--r--libtommath/bn_s_mp_exptmod.c248
-rw-r--r--libtommath/bn_s_mp_mul_digs.c86
-rw-r--r--libtommath/bn_s_mp_mul_high_digs.c77
-rw-r--r--libtommath/bn_s_mp_sqr.c80
-rw-r--r--libtommath/bn_s_mp_sub.c85
-rw-r--r--libtommath/bncore.c32
-rw-r--r--libtommath/booker.pl265
-rw-r--r--libtommath/callgraph.txt11913
-rw-r--r--libtommath/changes.txt403
-rw-r--r--libtommath/demo/demo.c736
-rw-r--r--libtommath/demo/timing.c315
-rw-r--r--libtommath/dep.pl123
-rw-r--r--libtommath/etc/2kprime.12
-rw-r--r--libtommath/etc/2kprime.c75
-rw-r--r--libtommath/etc/drprime.c59
-rw-r--r--libtommath/etc/drprimes.2825
-rw-r--r--libtommath/etc/drprimes.txt9
-rw-r--r--libtommath/etc/makefile50
-rw-r--r--libtommath/etc/makefile.icc67
-rw-r--r--libtommath/etc/makefile.msvc23
-rw-r--r--libtommath/etc/mersenne.c140
-rw-r--r--libtommath/etc/mont.c41
-rw-r--r--libtommath/etc/pprime.c396
-rw-r--r--libtommath/etc/prime.1024414
-rw-r--r--libtommath/etc/prime.512205
-rw-r--r--libtommath/etc/timer.asm37
-rw-r--r--libtommath/etc/tune.c138
-rw-r--r--libtommath/gen.pl17
-rw-r--r--libtommath/logs/README13
-rw-r--r--libtommath/logs/add.log16
-rw-r--r--libtommath/logs/addsub.pngbin0 -> 6253 bytes
-rw-r--r--libtommath/logs/expt.log7
-rw-r--r--libtommath/logs/expt.pngbin0 -> 6604 bytes
-rw-r--r--libtommath/logs/expt_2k.log5
-rw-r--r--libtommath/logs/expt_2kl.log4
-rw-r--r--libtommath/logs/expt_dr.log7
-rw-r--r--libtommath/logs/graphs.dem17
-rw-r--r--libtommath/logs/index.html24
-rw-r--r--libtommath/logs/invmod.log0
-rw-r--r--libtommath/logs/invmod.pngbin0 -> 4917 bytes
-rw-r--r--libtommath/logs/mult.log84
-rw-r--r--libtommath/logs/mult.pngbin0 -> 6769 bytes
-rw-r--r--libtommath/logs/mult_kara.log84
-rw-r--r--libtommath/logs/sqr.log84
-rw-r--r--libtommath/logs/sqr_kara.log84
-rw-r--r--libtommath/logs/sub.log16
-rw-r--r--libtommath/makefile186
-rw-r--r--libtommath/makefile.bcc44
-rw-r--r--libtommath/makefile.cygwin_dll51
-rw-r--r--libtommath/makefile.icc116
-rw-r--r--libtommath/makefile.msvc40
-rw-r--r--libtommath/makefile.shared102
-rw-r--r--libtommath/mess.sh4
-rw-r--r--libtommath/mtest/logtab.h19
-rw-r--r--libtommath/mtest/mpi-config.h85
-rw-r--r--libtommath/mtest/mpi-types.h15
-rw-r--r--libtommath/mtest/mpi.c3979
-rw-r--r--libtommath/mtest/mpi.h225
-rw-r--r--libtommath/mtest/mtest.c304
-rw-r--r--libtommath/pics/design_process.sxdbin0 -> 6950 bytes
-rw-r--r--libtommath/pics/design_process.tifbin0 -> 79042 bytes
-rw-r--r--libtommath/pics/expt_state.sxdbin0 -> 6869 bytes
-rw-r--r--libtommath/pics/expt_state.tifbin0 -> 87540 bytes
-rw-r--r--libtommath/pics/makefile35
-rw-r--r--libtommath/pics/primality.tifbin0 -> 85512 bytes
-rw-r--r--libtommath/pics/radix.sxdbin0 -> 6181 bytes
-rw-r--r--libtommath/pics/sliding_window.sxdbin0 -> 6787 bytes
-rw-r--r--libtommath/pics/sliding_window.tifbin0 -> 53880 bytes
-rw-r--r--libtommath/poster.out0
-rw-r--r--libtommath/poster.pdfbin0 -> 37822 bytes
-rw-r--r--libtommath/poster.tex35
-rw-r--r--libtommath/pre_gen/mpi.c9048
-rw-r--r--libtommath/pretty.build66
-rw-r--r--libtommath/tombc/grammar.txt35
-rw-r--r--libtommath/tommath.h579
-rw-r--r--libtommath/tommath.out139
-rw-r--r--libtommath/tommath.pdfbin0 -> 1194158 bytes
-rw-r--r--libtommath/tommath.src6350
-rw-r--r--libtommath/tommath.tex6691
-rw-r--r--libtommath/tommath_class.h995
-rw-r--r--libtommath/tommath_superclass.h72
-rw-r--r--license.terms2
-rw-r--r--mac/AppleScript.html312
-rw-r--r--mac/Background.doc90
-rwxr-xr-xmac/MW_TclAppleScriptHeader.h7
-rw-r--r--mac/MW_TclAppleScriptHeader.pch34
-rw-r--r--mac/MW_TclBuildLibHeader.h7
-rw-r--r--mac/MW_TclBuildLibHeader.pch33
-rwxr-xr-xmac/MW_TclHeader.h7
-rw-r--r--mac/MW_TclHeader.pch31
-rw-r--r--mac/MW_TclHeaderCommon.h52
-rw-r--r--mac/MW_TclStaticHeader.h7
-rw-r--r--mac/MW_TclStaticHeader.pch33
-rwxr-xr-xmac/MW_TclTestHeader.h7
-rwxr-xr-xmac/MW_TclTestHeader.pch39
-rw-r--r--mac/README79
-rw-r--r--mac/bugs.doc42
-rw-r--r--mac/libmoto.doc37
-rw-r--r--mac/morefiles.doc72
-rw-r--r--mac/porting.notes21
-rw-r--r--mac/tclMac.h26
-rw-r--r--mac/tclMacAETE.r56
-rw-r--r--mac/tclMacAlloc.c410
-rw-r--r--mac/tclMacAppInit.c211
-rw-r--r--mac/tclMacApplication.r113
-rw-r--r--mac/tclMacBOAAppInit.c255
-rw-r--r--mac/tclMacBOAMain.c302
-rw-r--r--mac/tclMacChan.c1273
-rwxr-xr-xmac/tclMacCommonPch.h69
-rw-r--r--mac/tclMacDNR.c21
-rw-r--r--mac/tclMacEnv.c534
-rw-r--r--mac/tclMacExit.c331
-rw-r--r--mac/tclMacFCmd.c1650
-rw-r--r--mac/tclMacFile.c1348
-rw-r--r--mac/tclMacInit.c805
-rw-r--r--mac/tclMacInt.h75
-rw-r--r--mac/tclMacInterupt.c287
-rw-r--r--mac/tclMacLibrary.c246
-rw-r--r--mac/tclMacLibrary.r207
-rw-r--r--mac/tclMacLoad.c378
-rw-r--r--mac/tclMacMath.h143
-rw-r--r--mac/tclMacNotify.c579
-rw-r--r--mac/tclMacOSA.c2956
-rw-r--r--mac/tclMacOSA.r76
-rw-r--r--mac/tclMacPanic.c170
-rw-r--r--mac/tclMacPort.h277
-rw-r--r--mac/tclMacProjects.sea.hqx3759
-rw-r--r--mac/tclMacResource.c2220
-rw-r--r--mac/tclMacResource.r42
-rw-r--r--mac/tclMacSock.c2788
-rw-r--r--mac/tclMacTclCode.r35
-rw-r--r--mac/tclMacTest.c211
-rw-r--r--mac/tclMacThrd.c869
-rw-r--r--mac/tclMacThrd.h18
-rw-r--r--mac/tclMacTime.c433
-rw-r--r--mac/tclMacUnix.c423
-rw-r--r--mac/tclMacUtil.c512
-rw-r--r--mac/tcltkMacBuildSupport.sea.hqx3970
-rw-r--r--macosx/GNUmakefile (renamed from macosx/Makefile)45
-rw-r--r--macosx/README75
-rw-r--r--macosx/Tcl-Common.xcconfig40
-rw-r--r--macosx/Tcl-Debug.xcconfig20
-rw-r--r--macosx/Tcl-Info.plist.in6
-rw-r--r--macosx/Tcl-Release.xcconfig20
-rw-r--r--macosx/Tcl.pbproj/default.pbxuser2
-rw-r--r--macosx/Tcl.pbproj/jingham.pbxuser2
-rw-r--r--macosx/Tcl.pbproj/project.pbxproj53
-rw-r--r--macosx/Tcl.xcode/default.pbxuser198
-rw-r--r--macosx/Tcl.xcode/project.pbxproj2792
-rw-r--r--macosx/Tcl.xcodeproj/default.pbxuser200
-rw-r--r--macosx/Tcl.xcodeproj/project.pbxproj3035
-rw-r--r--macosx/Tclsh-Info.plist.in6
-rw-r--r--macosx/configure.ac11
-rw-r--r--macosx/tclMacOSXBundle.c131
-rw-r--r--macosx/tclMacOSXFCmd.c696
-rw-r--r--macosx/tclMacOSXNotify.c1425
-rw-r--r--tests/all.tcl16
-rw-r--r--tests/append.test5
-rw-r--r--tests/appendComp.test21
-rw-r--r--tests/apply.test324
-rw-r--r--tests/assocd.test43
-rw-r--r--tests/async.test148
-rw-r--r--tests/basic.test501
-rw-r--r--tests/binary.test1108
-rw-r--r--tests/case.test16
-rw-r--r--tests/chan.test229
-rw-r--r--tests/chanio.test7705
-rw-r--r--tests/clock.test37101
-rw-r--r--tests/cmdAH.test809
-rw-r--r--tests/cmdIL.test480
-rw-r--r--tests/cmdInfo.test16
-rw-r--r--tests/cmdMZ.test206
-rw-r--r--tests/compExpr-old.test508
-rw-r--r--tests/compExpr.test177
-rw-r--r--tests/compile.test338
-rw-r--r--tests/concat.test12
-rw-r--r--tests/config.test60
-rw-r--r--tests/dcall.test31
-rw-r--r--tests/dict.test1254
-rw-r--r--tests/dstring.test150
-rw-r--r--tests/encoding.test92
-rw-r--r--tests/env.test40
-rw-r--r--tests/error.test98
-rw-r--r--tests/eval.test37
-rw-r--r--tests/event.test125
-rw-r--r--tests/exec.test51
-rw-r--r--tests/execute.test196
-rw-r--r--tests/expr-old.test536
-rw-r--r--tests/expr.test6826
-rw-r--r--tests/fCmd.test2500
-rw-r--r--tests/fileName.test868
-rw-r--r--tests/fileSystem.test808
-rw-r--r--tests/for-old.test12
-rw-r--r--tests/for.test130
-rw-r--r--tests/foreach.test29
-rw-r--r--tests/format.test108
-rw-r--r--tests/get.test115
-rw-r--r--tests/history.test235
-rw-r--r--tests/http.test94
-rw-r--r--tests/httpd40
-rw-r--r--tests/httpold.test12
-rw-r--r--tests/if.test82
-rw-r--r--tests/incr-old.test20
-rw-r--r--tests/incr.test127
-rw-r--r--tests/indexObj.test71
-rw-r--r--tests/info.test1221
-rw-r--r--tests/init.test46
-rw-r--r--tests/interp.test1175
-rw-r--r--tests/io.test655
-rw-r--r--tests/ioCmd.test3174
-rw-r--r--tests/ioUtil.test34
-rw-r--r--tests/iogt.test25
-rw-r--r--tests/join.test12
-rw-r--r--tests/lindex.test298
-rw-r--r--tests/link.test139
-rw-r--r--tests/linsert.test2
-rw-r--r--tests/list.test6
-rw-r--r--tests/listObj.test48
-rw-r--r--tests/llength.test12
-rw-r--r--tests/load.test35
-rw-r--r--tests/lrange.test8
-rw-r--r--tests/lrepeat.test77
-rw-r--r--tests/lreplace.test6
-rw-r--r--tests/lsearch.test105
-rw-r--r--tests/lset.test397
-rw-r--r--[-rwxr-xr-x]tests/lsetComp.test2
-rw-r--r--tests/macFCmd.test200
-rw-r--r--tests/macOSXFCmd.test181
-rw-r--r--tests/macOSXLoad.test33
-rw-r--r--tests/main.test139
-rw-r--r--tests/mathop.test1338
-rw-r--r--tests/misc.test25
-rw-r--r--tests/msgcat.test91
-rw-r--r--tests/namespace-old.test47
-rw-r--r--tests/namespace.test1408
-rw-r--r--[-rwxr-xr-x]tests/notify.test0
-rw-r--r--tests/obj.test290
-rw-r--r--tests/opt.test37
-rw-r--r--tests/osa.test46
-rw-r--r--tests/parse.test629
-rw-r--r--tests/parseExpr.test1110
-rw-r--r--tests/parseOld.test9
-rw-r--r--tests/pid.test30
-rw-r--r--tests/pkg.test295
-rw-r--r--tests/pkgMkIndex.test48
-rw-r--r--tests/platform.test8
-rw-r--r--tests/proc-old.test40
-rw-r--r--tests/proc.test125
-rw-r--r--tests/pwd.test21
-rw-r--r--tests/reg.test1468
-rw-r--r--tests/regexp.test318
-rw-r--r--tests/regexpComp.test168
-rw-r--r--tests/registry.test258
-rw-r--r--tests/rename.test118
-rw-r--r--tests/resource.test363
-rw-r--r--tests/result.test43
-rw-r--r--tests/safe.test197
-rw-r--r--tests/scan.test98
-rw-r--r--tests/security.test15
-rw-r--r--tests/set-old.test2
-rw-r--r--tests/set.test39
-rw-r--r--tests/socket.test278
-rw-r--r--tests/source.test200
-rw-r--r--tests/split.test12
-rw-r--r--tests/stack.test86
-rw-r--r--tests/string.test393
-rw-r--r--tests/stringComp.test27
-rw-r--r--tests/stringObj.test200
-rw-r--r--tests/subst.test30
-rw-r--r--tests/switch.test759
-rw-r--r--[-rwxr-xr-x]tests/tcltest.test180
-rw-r--r--tests/thread.test54
-rw-r--r--tests/timer.test53
-rw-r--r--tests/tm.test245
-rw-r--r--tests/trace.test256
-rw-r--r--tests/unixFCmd.test155
-rw-r--r--tests/unixFile.test21
-rw-r--r--tests/unixInit.test225
-rw-r--r--tests/unixNotfy.test90
-rw-r--r--tests/unknown.test12
-rw-r--r--tests/unload.test219
-rw-r--r--tests/uplevel.test12
-rw-r--r--tests/upvar.test271
-rw-r--r--tests/utf.test97
-rw-r--r--tests/util.test3730
-rw-r--r--tests/var.test186
-rw-r--r--tests/while-old.test14
-rw-r--r--tests/while.test40
-rw-r--r--tests/winConsole.test6
-rw-r--r--tests/winDde.test472
-rw-r--r--tests/winFCmd.test578
-rw-r--r--tests/winFile.test198
-rw-r--r--tests/winNotify.test43
-rw-r--r--tests/winPipe.test185
-rw-r--r--tests/winTime.test4
-rw-r--r--[-rwxr-xr-x]tools/checkLibraryDoc.tcl0
-rw-r--r--[-rwxr-xr-x]tools/configure2215
-rw-r--r--tools/configure.in3
-rw-r--r--tools/cvtEOL.tcl32
-rwxr-xr-xtools/findBadExternals.tcl53
-rwxr-xr-xtools/fix_tommath_h.tcl98
-rw-r--r--tools/genStubs.tcl535
-rw-r--r--tools/genWinImage.tcl155
-rw-r--r--tools/index.tcl2
-rw-r--r--tools/installData.tcl50
-rwxr-xr-xtools/loadICU.tcl619
-rwxr-xr-xtools/makeTestCases.tcl1180
-rw-r--r--tools/man2help.tcl7
-rw-r--r--tools/man2help2.tcl153
-rw-r--r--tools/man2html.tcl171
-rw-r--r--tools/man2html1.tcl32
-rw-r--r--tools/man2html2.tcl465
-rw-r--r--tools/man2tcl.c250
-rw-r--r--tools/mkdepend.tcl420
-rw-r--r--tools/tcl.hpj.in4
-rw-r--r--tools/tcl.wse.in76
-rw-r--r--tools/tclSplash.bmpbin162030 -> 162030 bytes
-rwxr-xr-xtools/tclZIC.tcl1375
-rw-r--r--tools/tclmin.wse4
-rwxr-xr-xtools/tcltk-man2html.tcl1107
-rw-r--r--tools/uniClass.tcl4
-rw-r--r--tools/uniParse.tcl6
-rw-r--r--unix/Makefile.in1197
-rw-r--r--unix/README222
-rw-r--r--unix/aclocal.m42
-rwxr-xr-xunix/configure21943
-rw-r--r--unix/configure.in495
-rw-r--r--unix/dltest/Makefile.in77
-rw-r--r--unix/dltest/README4
-rw-r--r--unix/dltest/pkga.c61
-rw-r--r--unix/dltest/pkgb.c79
-rw-r--r--unix/dltest/pkgc.c75
-rw-r--r--unix/dltest/pkgd.c72
-rw-r--r--unix/dltest/pkge.c25
-rw-r--r--unix/dltest/pkgf.c51
-rw-r--r--unix/dltest/pkgua.c332
-rwxr-xr-xunix/install-sh22
-rwxr-xr-xunix/installManPage131
-rwxr-xr-xunix/ldAix38
-rw-r--r--unix/tcl.m41151
-rw-r--r--unix/tcl.spec52
-rw-r--r--unix/tclAppInit.c96
-rw-r--r--unix/tclConfig.h.in505
-rw-r--r--unix/tclConfig.sh.in17
-rw-r--r--unix/tclLoadAix.c953
-rw-r--r--unix/tclLoadAout.c534
-rw-r--r--unix/tclLoadDl.c167
-rw-r--r--unix/tclLoadDld.c199
-rw-r--r--unix/tclLoadDyld.c8
-rw-r--r--unix/tclLoadNext.c148
-rw-r--r--unix/tclLoadOSF.c138
-rw-r--r--unix/tclLoadShl.c146
-rw-r--r--unix/tclUnixChan.c1865
-rw-r--r--unix/tclUnixCompat.c778
-rw-r--r--unix/tclUnixEvent.c57
-rw-r--r--unix/tclUnixFCmd.c1691
-rw-r--r--unix/tclUnixFile.c850
-rw-r--r--unix/tclUnixInit.c1470
-rw-r--r--unix/tclUnixNotfy.c680
-rw-r--r--unix/tclUnixPipe.c707
-rw-r--r--unix/tclUnixPort.h200
-rw-r--r--unix/tclUnixSock.c147
-rw-r--r--unix/tclUnixTest.c370
-rw-r--r--unix/tclUnixThrd.c580
-rw-r--r--unix/tclUnixTime.c355
-rw-r--r--unix/tclXtNotify.c352
-rw-r--r--unix/tclXtTest.c57
-rw-r--r--win/Makefile.in340
-rw-r--r--win/README10
-rw-r--r--win/README.binary141
-rw-r--r--[-rwxr-xr-x]win/buildall.vc.bat95
-rw-r--r--win/cat.c7
-rw-r--r--win/coffbase.txt10
-rwxr-xr-xwin/configure5910
-rw-r--r--win/configure.in165
-rw-r--r--win/makefile.bc94
-rw-r--r--win/makefile.vc525
-rw-r--r--win/nmakehlp.c266
-rw-r--r--win/rules.vc231
-rw-r--r--win/stub16.c65
-rw-r--r--win/tcl.dsp56
-rw-r--r--win/tcl.hpj.in4
-rw-r--r--win/tcl.m4120
-rw-r--r--win/tcl.rc8
-rw-r--r--win/tclAppInit.c282
-rw-r--r--win/tclWin32Dll.c760
-rw-r--r--win/tclWinChan.c942
-rw-r--r--win/tclWinConsole.c636
-rw-r--r--win/tclWinDde.c1896
-rw-r--r--win/tclWinFCmd.c1224
-rw-r--r--win/tclWinFile.c2918
-rw-r--r--win/tclWinInit.c667
-rw-r--r--win/tclWinInt.h89
-rw-r--r--win/tclWinLoad.c191
-rw-r--r--win/tclWinMtherr.c55
-rw-r--r--win/tclWinNotify.c286
-rw-r--r--win/tclWinPipe.c1447
-rw-r--r--win/tclWinPort.h168
-rw-r--r--win/tclWinReg.c546
-rw-r--r--win/tclWinSerial.c1994
-rw-r--r--win/tclWinSock.c1937
-rw-r--r--win/tclWinTest.c726
-rw-r--r--win/tclWinThrd.c708
-rw-r--r--win/tclWinTime.c1003
-rw-r--r--win/tclsh.rc10
1598 files changed, 413386 insertions, 165204 deletions
diff --git a/ChangeLog b/ChangeLog
index 6f7740b..bffb230 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,10 @@
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 on windows
+ * generic/tclFCmd.c: [Bug 2015723] duplicate inodes from file stat on
+ windows (but now for cygwin as well)
-2012-03-24 Jan Nijtmans <nijtmans@users.sf.net>
+2012-03-25 Jan Nijtmans <nijtmans@users.sf.net>
* generic/tclInt.decls: [Bug 3508771] load tclreg.dll in cygwin tclsh
* generic/tclIntPlatDecls.h: Implement TclWinConvertError, TclWinConvertWSAError,
@@ -13,21 +14,64 @@
* unix/configure:
* win/tclWinError.c:
+2012-03-23 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * generic/tclInt.decls Revert some cygwin-related signature changes from
+ * generic/tclIntPlatDecls.h [835f8e1e9d] (2010-02-01). They were an attempt to
+ * win/tclWinError.c make the cygwin port compile again, but since cygwin
+ is based on unix this serves no purpose any more.
+ * 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.h: [Bug 3288345] Wrong Tcl_StatBuf used on Cygwin
+ * generic/tcl.decls: [Bug 3508771] load tclreg.dll in cygwin tclsh
+ * generic/tclInt.decls: Implement TclWinGetPlatformId, Tcl_WinUtfToTChar,
+ * generic/tclIntPlatDecls.h: Tcl_WinTCharToUtf (and a dummy TclWinCPUID) for
+ * generic/tclPlatDecls.h: Cygwin, so win32 extensions using those can be
+ * generic/tclStubInit.c: loaded in the cygwin version of tclsh.
+ * unix/tclUnixCompat.c:
+
+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-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/tclWinFile.c Remove cygwin stuff no longer needed
+ * win/cat.c: Remove cygwin stuff no longer needed
+ * win/tclWinFile.c
* win/tclWinPort.h
- * generic/tcl.decls: [Bug 3508771] load tclreg.dll in cygwin tclsh
- * generic/tclInt.decls: Implement TclWinGetPlatformId, Tcl_WinUtfToTChar,
- * generic/tclIntPlatDecls.h: Tcl_WinTCharToUtf (and a dummy TclWinCPUID) for
- * generic/tclPlatDecls.h: Cygwin, so win32 extensions using those can be
- * generic/tclStubInit.c: loaded in the cygwin version of tclsh.
- * unix/tclUnixCompat.c:
-
2012-03-12 Jan Nijtmans <nijtmans@users.sf.net>
* win/tclWinFile.c: [Bug 3388350] mingw64 compiler warnings
@@ -36,18 +80,14 @@
* 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.5.7.
+ * tests/http.test: with RFC 3986. Bumped version to 2.7.9.
+ * 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 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
- * unix/tclUnixChan.c: TclUnixWaitForFile(): use FD_* macros
- * macosx/tclMacOSXNotify.c: to manipulate select masks (Cassoff).
- [Bug 3486554]. Backport of das' checkin [e496f9ef50]. Allows
- Tcl8.4 to have sane fileevents on x86_64 at last.
-
2012-03-04 Jan Nijtmans <nijtmans@users.sf.net>
* generic/tclLoad.c: Patch from the cygwin folks
@@ -60,20 +100,42 @@
* 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-15 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCompCmds.c (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: [Bug 3484402] Correct Off-By-One
+ * generic/tclStringObj.c: [Bug 3484402]: Correct Off-By-One
error appending unicode. Thanks to Poor Yorick. Also corrected test
- for when growth is needed.
+ for when growth is needed.
2012-02-06 Don Porter <dgp@users.sourceforge.net>
- * generic/tclCmdMZ.c: [Bug 3484621] Invalidate bytecode when exec
- * tests/trace.test: traces are added/removed from compiled cmd.
+ * generic/tclCompCmds.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: Fix for [Bug 3484621]: insure that
+ * tests/trace.test: execution traces on 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/tclUniData.c: [FRQ 3464401]: Support Unicode 6.1
* generic/regc_locale.c:
2012-02-02 Don Porter <dgp@users.sourceforge.net>
@@ -83,8 +145,17 @@
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. Patch cherrypicked off the fix-win-native-access
- branch.
+ on a Samba share. Patch merged from the fix-win-native-access branch.
+
+2012-02-01 Donal K. Fellows <dkf@users.sf.net>
+
+ * doc/AddErrInfo.3: [Bug 3482614]: Documentation nit.
+
+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-22 Jan Nijtmans <nijtmans@users.sf.net>
@@ -94,24 +165,38 @@
* generic/tclUtf.c: Done in all branches in order to simplify
* generic/regc_locale.c: merges for new Unicode versions (such as 6.1)
-2012-01-19 Jan Nijtmans <nijtmans@users.sf.net>
+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/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 then.
* generic/tclTest.c: Only keep _stat32i64 usage for cygwin, so it
* win/configure.in: will not conflict with cygwin's own struct stat.
* win/configure:
-2012-01-19 Don Porter <dgp@users.sourceforge.net>
+2012-01-21 Don Porter <dgp@users.sourceforge.net>
- * generic/tclCmdMZ.c: [Bug 3475667] Prevent buffer read overflow.
+ * 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-17 Don Porter <dgp@users.sourceforge.net>
- * library/http/http.tcl: Bump to 2.5.6.
+ * library/http/http.tcl: Bump to version 2.7.8
* library/http/pkgIndex.tcl:
+ * unix/Makefile.in:
+ * win/Makefile.in:
2012-01-13 Donal K. Fellows <dkf@users.sf.net>
@@ -120,12 +205,29 @@
2012-01-09 Jan Nijtmans <nijtmans@users.sf.net>
- * generic/tclUtf.c: [Bug 3464428] string is graph \u0120 is wrong
- * generic/regcomp.c: Remove some unused code
+ * generic/tclUtf.c: [Bug 3464428]: string is graph \u0120 is wrong
* generic/regc_locale.c: Add table for Unicode [:cntrl:] class
* tools/uniClass.tcl: Generate Unicode [:cntrl:] class table
* tests/utf.test:
- * doc/re_syntax: Fix [:print:] class description
+
+2012-01-08 Kevin B. Kenny <kennykb@acm.org>
+
+ * library/clock.tcl (ReadZoneinfoFile): Corrected a bug where loading
+ * tests/clock.test (clock-56.4): 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." [Bug 3470928]
+
+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>
@@ -136,6 +238,11 @@
* tools/uniParse.tcl: clean up some unused stuff, and be more robust
against changes in UnicodeData.txt syntax
+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
@@ -153,11 +260,52 @@
* doc/tclsh.1: Use the same shebang comment everywhere.
* tools/str2c
* tools/tcltk-man2html.tcl
+ * win/Makefile.in: don't install tommath_(super)?class.h
+ * unix/Makefile.in: don't install directories like 8.2 and 8.3
2011-11-22 Jan Nijtmans <nijtmans@users.sf.net>
- * generic/tclCmdAH.c: [Bug 2935503] Windows: file mtime
- * generic/tclIOUtil.c: sets wrong time
+ * win/tclWinPort.h: [Bug 2935503] Windows: file mtime
+ * win/tclWinFile.c: sets wrong time (VS2005+ only)
+ * generic/tclTest.c:
+
+2011-11-04 Don Porter <dgp@users.sourceforge.net>
+
+ *** 8.5.11 TAGGED FOR RELEASE ***
+
+ * generic/tcl.h: Bump to 8.5.11 for release.
+ * library/init.tcl:
+ * tools/tcl.wse.in:
+ * unix/configure.in:
+ * unix/tcl.spec:
+ * win/configure.in:
+ * README:
+
+ * unix/configure: autoconf-2.59
+ * win/configure:
+
+ * changes: Update for 8.5.11 release.
+
+2011-10-20 Don Porter <dgp@users.sourceforge.net>
+
+ * library/http/http.tcl: Bump to version 2.7.7
+ * library/http/pkgIndex.tcl:
+ * unix/Makefile.in:
+ * win/Makefile.in:
+
+ * changes: Updates for 8.5.11 release.
+
+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>
@@ -166,22 +314,42 @@
2011-10-07 Jan Nijtmans <nijtmans@users.sf.net>
- * win/tclWinChan.c: Fix various gcc warnings
- * win/tclWinConsole.c: (discovered with latest
- * win/tclWinNotify.c: mingw, based on gcc 4.6.1)
- * win/tclWinReg.c:
+ * generic/tclIORChan.c: Fix gcc warning
+ (discovered with latest mingw, based on gcc 4.6.1)
* tests/env.test: Fix env.test, when running
under wine 1.3 (partly backported from Tcl 8.6)
-2011-09-26 Jan Nijtmans <nijtmans@users.sf.net>
+2011-10-03 Venkat Iyer <venkat@comit.com>
- * win/rules.vc: Support Visual Studio 11
+ * 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-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>
+
+ * 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-13 Don Porter <dgp@users.sourceforge.net>
* generic/tclUtil.c: [Bug 3390638] Workaround broken solaris
@@ -195,86 +363,144 @@
* win/tclWinPort.h: [Bug 3407070] tclPosixStr.c won't build with
EOVERFLOW==E2BIG
-2011-09-06 Jan Nijtmans <nijtmans@users.sf.net>
+2011-09-07 Don Porter <dgp@users.sourceforge.net>
- * generic/tcl.decls: Tcl_HashStats does not return a CONST
- * generic/tclDecls.h: (Backported from Tcl 8.5)
- * generic/tclHash.c:
- * generic/tclVar.c:
- * unix/tcl.m4: Add --disable-rpath option to configure
- * unix/configure: script (backported from Tcl 8.5)
+ * 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-08-30 Jan Nijtmans <nijtmans@users.sf.net>
+2011-09-06 Venkat Iyer <venkat@comit.com>
- * unix/tcl.m4: Make SHLIB_LD_LIBS='${LIBS}' the default and
- * unix/configure: set to "" on per-platform necessary basis.
- Add Haiku support and better NetBSD/FreeBSD support.
- All of this backported from TEA resp. Tcl8.5, but kept all
- original platform code which was removed from TEA.
+ * 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-01 Don Porter <dgp@users.sourceforge.net>
-2011-08-22 Andreas Kupries <andreask@activestate.com>
+ * generic/tclStrToD.c: [Bug 3402540] Corrections to TclParseNumber()
+ * tests/binary.test: to make it reject invalid Nan(Hex) strings.
- * win/tclWinDde.c (Tcl_DdeObjCmd): Fixed use of the C99 feature
- (Variable declaration within statement block) rejected by
- MSVC6. Moved the declaration to the beginning of the block.
+ * 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-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 Jan Nijtmans <nijtmans@users.sf.net>
- * generic/tclUniData.c: [Bug 3393714] overflow in toupper delta
+ * generic/tclUniData.c: [Bug 3393714]: Overflow in toupper delta
* tools/uniParse.tcl
* tests/utf.test
+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 Jan Nijtmans <nijtmans@users.sf.net>
- * generic/tclCmdAH.c: [Bug 3388350] mingw64 compiler warnings
+ * generic/tclCmdAH.c: [Bug 3388350]: mingw64 compiler warnings
* generic/tclFCmd.c In mingw, sys/stat.h must be included
* generic/tclFileName.c before winsock2.h, so make sure of that.
* generic/tclIOUtil.c
+ * generic/tclBasic.c
+ * generic/tclBinary.c
+ * generic/tclHash.c
* generic/tclTest.c
- * win/tclWin32Dll.c
* win/tclWinChan.c
+ * win/tclWinConsole.c
* win/tclWinDde.c
- * win/tclWinFCmd.c
+ * win/tclWinFile.c
+ * win/tclWinReg.c
+ * win/tclWinSerial.c
+ * win/tclWinSock.c
+ * win/tclWinThrd.c
2011-08-15 Don Porter <dgp@users.sourceforge.net>
- * generic/tclBasic.c: [Bug 3390272] Leak of [info script] value.
+ * generic/tclBasic.c: [Bug 3390272]: Leak of [info script] value.
2011-08-15 Jan Nijtmans <nijtmans@users.sf.net>
- * win/tcl.m4: [Bug 3388350] mingw64 compiler warnings
+ * win/tclWinPort.h: [Bug 3388350]: mingw64 compiler warnings
+ * win/tclWinPipe.c
+ * win/tclWinSock.c
* win/configure.in
* win/configure
- * win/tclMtherr.c
- * win/tclWinPort.h
- * win/tclWinChan.c
+ * generic/tclPosixStr.c
+ * generic/tclStrToD.c
+
+2011-08-12 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclPathObj.c: [Bug 3389764]: Eliminate possibility that dup
+ of a "path" value can create reference cycle.
+
+2011-08-09 Jan Nijtmans <nijtmans@users.sf.net>
+
+ * win/tclWinConsole.c: [Bug 3388350]: mingw64 compiler warnings
* win/tclWinDde.c
- * win/tclWinFCmd.c
* win/tclWinPipe.c
- * win/tclWinReg.c
* win/tclWinSerial.c
- * win/tclWinSock.c
- * win/tclWinTest.c
- * win/tclWinTime.c
- * generic/tclPosixStr.c
- * unix/tcl.m4: Quoting and AC_DEFINE fixes (All backported from
- * unix/configure Tcl 8.5
+
+2011-08-05 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclStrToD.c: [Bug 3386975]: Plugged a memory leak in
+ double->string conversion.
+
+2011-07-28 Don Porter <dgp@users.sourceforge.net>
+
+ * library/tzdata/Asia/Anadyr: Update to Olson's tzdata2011h
+ * library/tzdata/Asia/Irkutsk:
+ * library/tzdata/Asia/Kamchatka:
+ * library/tzdata/Asia/Krasnoyarsk:
+ * library/tzdata/Asia/Magadan:
+ * library/tzdata/Asia/Novokuznetsk:
+ * library/tzdata/Asia/Novosibirsk:
+ * library/tzdata/Asia/Omsk:
+ * library/tzdata/Asia/Sakhalin:
+ * library/tzdata/Asia/Vladivostok:
+ * library/tzdata/Asia/Yakutsk:
+ * library/tzdata/Asia/Yekaterinburg:
+ * library/tzdata/Europe/Kaliningrad:
+ * library/tzdata/Europe/Moscow:
+ * library/tzdata/Europe/Samara:
+ * library/tzdata/Europe/Volgograd:
+ * library/tzdata/America/Kralendijk: (new)
+ * library/tzdata/America/Lower_Princes: (new)
2011-07-21 Jan Nijtmans <nijtmans@users.sf.net>
- * win/tclWinPort.h: [Bug 3372130] Fix hypot math function with MSVC10
+ * win/tclWinPort.h: [Bug 3372130]: Fix hypot math function with MSVC10
+
+2011-07-19 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclUtil.c: [Bug 3371644]: Repair failure to properly handle
+ * tests/util.test: (length == -1) scanning in TclConvertElement().
2011-07-15 Don Porter <dgp@users.sourceforge.net>
* generic/tclCompile.c: Avoid segfaults when RecordByteCodeStats()
is called in a deleted interp.
-2011-07-13 Don Porter <dgp@users.sourceforge.net>
+2011-07-08 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclProc.c: [Bug 3366265] Buffer for storing the command
- * tests/indexObj.test: name formatted as a list element is allocated
- * tests/proc.test: one byte too small, causing buffer overflow
- when the proc with the empty name raises a "wrong num args" error.
+ * doc/http.n: [FRQ 3358415]: State what RFC defines HTTP/1.1.
2011-07-03 Donal K. Fellows <dkf@users.sf.net>
@@ -282,11505 +508,9538 @@
stat'; that was always the time of the last metadata change, not the
time of creation.
-2011-06-22 Andreas Kupries <andreask@activestate.com>
-
- * library/platform/pkgIndex.tcl: Updated to platform 1.0.10. Added
- * library/platform/platform.tcl: handling of the DEB_HOST_MULTIARCH
- location change for libc.
-
-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
-
-2011-04-21 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclCompile.c: Make sure SetFooFromAny routines react
- * generic/tclIndexObj.c: reasonably when passed a NULL interp.
- * generic/tclNamesp.c:
- * generic/tclObj.c:
-
-2011-04-21 Jan Nijtmans <nijtmans@users.sf.net>
-
- * generic/tcl.h: fix for [Bug 3288345]: Wrong Tcl_StatBuf
- * generic/tclInt.h: used on MinGW. Make sure that all _WIN32
- * generic/tclIOUtil.c: compilers use exactly the same layout
- * win/tclWinFile.c: for Tcl_StatBuf - the one used by MSVC6 -
- * win/configure.in: in all situations.
- * win/configure:
-
-2011-04-20 Andreas Kupries <andreask@activestate.com>
-
- * tests/info.test: Fixed the shift in line numbers used for
- testing 'info frame' introduced by checkin [79367df0f0]
- (Mar 2, 2011).
-
-2011-04-13 Miguel Sofer <msofer@users.sf.net>
-
- * generic/tclVar.c: fix for [Bug 2662380], crash caused by
- appending to a variable with a write trace that unsets it.
-
-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.
- * unix/README: Still could use more eyeballs on the detailed build
- * win/README: advice on various plaforms. [Bug 3202030]
-
-2011-03-25 Jan Nijtmans <nijtmans@users.sf.net>
-
- * generic/tclHash.c: [Bug 3007895]: Tcl_(Find|Create)HashEntry
- stub entries can never be called. They still cannot be called
- (no change in functionality), but at least they now do
- exactly the same as the Tcl_(Find|Create)HashEntry macro's,
- so the confusion addressed in this Bug report is gone.
- Merged --cherrypick from Tcl8.5 (2010-12-31,e75735ef76)
-
-2011-03-24 Donal K. Fellows <dkf@users.sf.net>
-
- * generic/tclFCmd.c (TclFileAttrsCmd): Ensure that any reference to
- temporary index tables is squelched immediately rather than hanging
- around to trip us up in the future.
-
-2011-03-16 Jan Nijtmans <nijtmans@users.sf.net>
-
- * unix/configure, unix/tcl.m4: SHLIB_LD_LIBS='${LIBS}' for OSF1-V*.
- Add /usr/lib64 to set of auto-search dirs. [Bug 1230554]
- (SC_PATH_X): Correct syntax error when xincludes not found.
- Backported from Tcl 8.5
- * generic/tclCkalloc.c: [Bug #3197864] pointer truncation on Win64
- TCL_MEM_DEBUG builds
-
-2010-03-11 Jan Nijtmans <nijtmans@users.sf.net>
-
- * win/tclWin32Dll.c: #ifdef protections to permit builds with
- * win/tclWinChan.c: mingw on amd64 systems. Thanks to "mescalinum"
- * win/tclWinFCmd.c: for reporting and testing.
- Merged --cherrypick from Tcl8.5 (2010-09-08,48191d3979)
-
-2011-03-11 Jan Nijtmans <nijtmans@users.sf.net>
-
- * win/tcl.m4: handle --enable-64bit=ia64 for gcc.
- * win/configure: (autoconf-2.13)
- * win/tclWin32Dll.c: [Patch 3059922]: fixes for mingw64 - gcc4.5.1
- Merged --cherrypick from Tcl8.5 (2011-01-17, 6e410a115b)
-
-2011-03-08 Jan Nijtmans <nijtmans@users.sf.net>
-
- * generic/tclBasic.c: Fix gcc warnings: variable set but not used
-
-2011-03-06 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclBasic.c: More replacements of Tcl_UtfBackslash() calls
- * generic/tclCmdMZ.c: with TclParseBackslash() where possible.
- * generic/tclCompExpr.c:
- * generic/tclCompile.c:
- * generic/tclUtil.c (TclFindElement): Guard escape sequence scans
- to not overrun the string end. [Bug 3192636]
-
-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]
+2011-07-02 Kevin B. Kenny <kennykb@acm.org>
-2011-01-25 Jan Nijtmans <nijtmans@users.sf.net>
+ * generic/tclStrToD.c:
+ * generic/tclTomMath.decls:
+ * generic/tclTomMathDecls.h:
+ * macosx/Tcl.xcode/project.pbxproj:
+ * macosx/Tcl.xcodeproj/project.pbxproj:
+ * tests/util.test:
+ * 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]
- * generic/tclCkalloc.c: [Bug 3129448]: Possible over-allocation on 64-bit
- * generic/tclHash.c: platforms, part 2, backported strcpy->memcpy
- * generic/tclProc.c change but not change in any struct.
+2011-06-30 Reinhard Max <max@suse.de>
-2011-01-14 Jan Nijtmans <nijtmans@users.sf.net>
+ * unix/configure.in: Add a volatile declaration to the test for
+ TCL_STACK_GROWS_UP to prevent gcc 4.6 from producing invalid
+ results due to aggressive optimisation.
- * win/tclWinDde.c: Fix gcc-4.5.2 error: lvalue required as ...
- * win/tclWinReg.c: (backported from 8.5/8.6)
+2011-06-23 Don Porter <dgp@users.sourceforge.net>
-2010-12-05 Jan Nijtmans <nijtmans@users.sf.net>
+ *** 8.5.10 TAGGED FOR RELEASE ***
- * generic/tclCmdMZ.c: [Bug 3127687] Triggers FORTIFY_SOURCE
- buffer overflow detection
+ * changes: Update for 8.5.10 release.
-2010-11-03 Jeff Hobbs <jeffh@ActiveState.com>
+2011-06-22 Andreas Kupries <andreask@activestate.com>
- Backported from 8.6 (see 2010-08-04).
- * win/tclWin32Dll.c (asciiProcs, unicodeProcs):
- * win/tclWinLoad.c (TclpDlopen): 'load' use LoadLibraryEx with
- * win/tclWinInt.h (TclWinProcs): LOAD_WITH_ALTERED_SEARCH_PATH to
- prefer dependent DLLs in same dir as loaded DLL.
+ * library/platform/pkgIndex.tcl: Updated to platform 1.0.10. Added
+ * library/platform/platform.tcl: handling of the DEB_HOST_MULTIARCH
+ * unix/Makefile.in: location change for libc.
+ * win/Makefile.in:
-2010-10-31 Jan Nijtmans <nijtmans@users.sf.net>
+ * generic/tclInt.h: Fixed the inadvertently committed disabling of
+ stack checks, see my 2010-11-15 commit.
- * win/tcl.m4 Add -D_CRT_SECURE_NO_DEPRECATE and
- -D_CRT_NONSTDC_NO_DEPRECATE, reducing the number of
- deprecation warnings on later VC++ versions.
- * win/rules.vc Better VCVERSION determination
- * win/configure (regenerated with autoconf 2.13)
- All changes backported from Tcl8.5/8.6
+2011-06-21 Don Porter <dgp@users.sourceforge.net>
-2010-10-23 Jan Nijtmans <nijtmans@users.sf.net>
+ * changes: Update for 8.5.10 release.
- * tools/uniParse.tcl: [Bug 3085863]: tclUniData 9 years old
- * tools/uniClass.tcl: Upgrade everything to Unicode 6.0, except
- * tests/utf.test: non-BMP characters > 0xFFFF
- * generic/tclUniData.c: (re-generated)
- * generic/regc_locale.c:(re-generated)
- * generic/regcomp.c: fix comment/signatures referencing regc_locale
- * win/rules.vc Update for VS10
-
-2010-09-24 Andreas Kupries <andreask@activestate.com>
-
- * tclWinsock.c: [Bug 3056775]: Fixed race condition between thread
- and internal co-thread access of a socket's structure because of
- the thread not using the socketListLock in TcpAccept(). Added
- documentation on how the module works to the top.
+ * library/tcltest/tcltest.tcl (loadIntoSlaveInterpreter):
+ * library/tcltest/pkgIndex.tcl: Backport tcltest 2.3.3 for release
+ * unix/Makefile.in: with Tcl 8.5.*.
+ * win/Makefile.in:
-2010-09-01 Andreas Kupries <andreask@activestate.com>
+ * tests/init.test: Update test files to use new command.
+ * tests/pkg.test:
- * generic/tclExecute.c: [Bug 3057639]. Applied patch by Jeff to
- * generic/tclVar.c: make the behaviour of lappend in bytecompiled
- * tests/append.test: mode consistent with direct-eval and 'append'
- * tests/appendComp.test: generally. Added tests (append*-9.*)
- showing the difference.
+ * generic/tclLink.c: Prevent multiple links to a single Tcl
+ variable when calling Tcl_LinkVar(). [Bug 3317466]
-2010-07-25 Jan Nijtmans <nijtmans@users.sf.net>
+2011-06-13 Don Porter <dgp@users.sourceforge.net>
- * generic/tclInt.h: [Bug 3030870] make itcl 3.x built with pre-8.6
- * generic/tclBasic.c: work in 8.6 revert tclInt.h to what it was
- before, and relax the relation between Tcl_CallFrame and
- CallFrame.
+ * generic/tclStrToD.c: [Bug 3315098] Mem leak fix from Gustaf Neumann.
-2010-07-18 Jan Nijtmans <nijtmans@users.sf.net>
+2011-06-02 Don Porter <dgp@users.sourceforge.net>
- * generic/tcl.h: [Bug 3031278] fixed merge problem in previous
- commit.
+ * 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.
-2010-07-17 Jan Nijtmans <nijtmans@users.sf.net>
+2011-06-02 Donal K. Fellows <dkf@users.sf.net>
- * generic/tcl.h: [Bug 3030870] make itcl 3.x built with pre-8.6
- * generic/tclInt.h: work in 8.6
+ * generic/tclInt.h (TclInvalidateNsCmdLookup): [Bug 3185407]: Extend
+ the set of epochs that are potentially bumped when a command is
+ created, for a slight performance drop (in some circumstances) and
+ improved semantics.
-2010-07-16 Jan Nijtmans <nijtmans@users.sf.net>
+2011-06-01 Jan Nijtmans <nijtmans@users.sf.net>
- * generic/tcl.h: (Backport) take over definitions of _WIN32,
- DLLIMPORT, DLLEXPORT and TCL_LL_MODIFIER macros from Tcl8.5/8.6
+ * generic/tclUtil.c: Fix for [Bug 3309871]: Valgrind finds:
+ invalid read in TclMaxListLength()
-2010-06-28 Jan Nijtmans <nijtmans@users.sf.net>
+2011-05-25 Don Porter <dgp@users.sourceforge.net>
- * generic/tclPosixStr.c: [Bug 3019634] errno.h and tclWinPort.h
- have conflicting definitions.
+ * library/msgcat/msgcat.tcl: Backport improvements to msgcat
+ * library/msgcat/pkgIndex.tcl: package. Bump to 1.4.4
+ * unix/Makefile.in
+ * win/Makefile.in
-2010-06-09 Andreas Kupries <andreask@activestate.com>
+2011-05-24 Venkat Iyer <venkat@comit.com>
- * library/platform/platform.tcl: Added OSX Intel 64bit
- * library/platform/pkgIndex.tcl: Package updated to version 1.0.9.
+ * library/tzdata/Africa/Cairo: Update to Olson tzdata2011g
-2010-05-07 Andreas Kupries <andreask@activestate.com>
+2011-05-17 Andreas Kupries <andreask@activestate.com>
- * library/platform/platform.tcl: Fix cpu name for Solaris/Intel 64bit.
- * library/platform/pkgIndex.tcl: Package updated to version 1.0.8.
+ * 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.
-2010-04-29 Andreas Kupries <andreask@activestate.com>
+2011-05-10 Don Porter <dgp@users.sourceforge.net>
- * library/platform/platform.tcl: Another stab at getting the /lib,
- * library/platform/pkgIndex.tcl: /lib64 difference right for
- linux. Package updated to version 1.0.7.
+ * 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.
-2010-04-18 Donal K. Fellows <dkf@users.sf.net>
+ * generic/tclDictObj.c: Update all callers.
+ * generic/tclIndexObj.c:
+ * generic/tclListObj.c:
+ * generic/tclUtil.c:
+ * tests/list.test:
- * doc/unset.n: [Bug 2988940]: Fix typo.
+2011-05-09 Don Porter <dgp@users.sourceforge.net>
-2010-04-14 Andreas Kupries <andreask@activestate.com>
+ * generic/tclListObj.c: Revise empty string tests so that we avoid
+ potentially expensive string rep generations, especially for dicts.
- * library/platform/platform.tcl: Linux platform identification:
- * library/platform/pkgIndex.tcl: Check /lib64 for existence of
- files matching libc* before accepting it as base directory. This
- can happen on weirdly installed 32bit systems which have an empty
- or partially filled /lib64 without an actual libc. Bumped to
- version 1.0.6.
+2011-05-07 Miguel Sofer <msofer@users.sf.net>
-2010-04-06 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+ * generic/tclInt.h: fix USE_TCLALLOC so that it can be enabled
+ * unix/Makefile.in: without editing the Makefile
- * generic/tclCmdMZ.c (Tcl_RegexpObjCmd): fixed object leak.
+2011-05-05 Don Porter <dgp@users.sourceforge.net>
-2010-04-02 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+ * generic/tclListObj.c: Stop generating string rep of dict when
+ converting to list. Tolerate NULL interps more completely.
- * generic/tclStringObj.c: (SetStringFromAny): avoid trampling
- over the tclEmptyStringRep->bytes as it is thread-shared
- (thx to Gustaf Neumann for the (hard) work of locating this one).
+2011-05-03 Don Porter <dgp@users.sourceforge.net>
-2010-03-01 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+ * generic/tclUtil.c: Tighten Tcl_SplitList().
+ * generic/tclListObj.c: Tighten SetListFromAny().
+ * generic/tclDictObj.c: Tighten SetDictFromAny().
- * unix/tclUnixChan.c: [backported] Refrain from a possibly lengthy
- reverse-DNS lookup on 0.0.0.0 when calling [fconfigure -sockname]
- on an universally-bound (default) server socket.
+2011-05-02 Don Porter <dgp@users.sourceforge.net>
-2010-02-22 Jan Nijtmans <nijtmans@users.sf.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/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.
+ ***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
+ scenario. Simply looking for the braces where they must be is the
+ revision available to those callers, and it will backport cleanly.
- * generic/tclExecute.c: Fix [Bug 2954959] expr abs(-0.0) is -0.0
- * tests/expr.test Added some test cases, backported from 8.5
+ * tests/parse.test: Tests for expanded literals quoting detection.
-2010-02-11 Andreas Kupries <andreask@activestate.com>
+ * generic/tclCompCmds.c: New TclFindElement() is also a better
+ fit for the [switch] compiler.
- * generic/tclCompile.c: [Bug 2949302]: Fixed leak of support
- structures for [info frame] which occured when bytecode
- compilation fails.
+ * generic/tclInt.h: Replace TclCountSpaceRuns() with
+ * generic/tclListObj.c: TclMaxListLength() which is the function we
+ * generic/tclUtil.c: actually want.
+ * generic/tclCompCmds.c:
-2010-02-01 Donal K. Fellows <dkf@users.sf.net>
+ * generic/tclCompCmds.c: Rewrite of parts of the switch compiler to
+ better use the powers of TclFindElement() and do less parsing on
+ its own.
- * generic/regexec.c (ccondissect, crevdissect): [Bug 2942697]: Rework
- these functions so that certain pathological patterns are matched much
- more rapidly. Many thanks to Tom Lane for dianosing this issue and
- providing an initial patch.
+2011-04-28 Don Porter <dgp@users.sourceforge.net>
-2009-11-16 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+ * generic/tclInt.h: New utility routines:
+ * generic/tclParse.c: TclIsSpaceProc() and
+ * generic/tclUtil.c: TclCountSpaceRuns()
- * generic/tclEncoding.c: (Backport) Fix [Bug 2891556] and improve
- * tests/econding.test: test to detect similar manifestations in the
- future.
+ * generic/tclCmdMZ.c: Use new routines to replace calls to
+ * generic/tclListObj.c: isspace() and their /* INTL */ risk.
+ * generic/tclStrToD.c:
+ * generic/tclUtf.c:
+ * unix/tclUnixFile.c:
-2009-11-12 Andreas Kupries <andreask@activestate.com>
-
- * generic/tclIO.c (CopyData): [Bug 2895565]. Dropped bogosity
- * tests/io.test: which used the number of _written_ bytes or
- character to update the counters for the read bytes/characters.
- New test io-53.11. This is a backward port from the 8.5 branch.
-
-2009-11-10 Pat Thoyts <patthoyts@users.sourceforge.net>
-
- * tests/fCmd.test: Fixed a number of issues for Vista
- * tests/registry.test: and Win7 that are due to restricted
- * tests/tcltest.test: permissions under UAC.
- * tests/winFCmd.test:
+2011-04-27 Don Porter <dgp@users.sourceforge.net>
-2009-11-10 Stuart Cassoff <stwo@users.sf.net>
+ * generic/tclListObj.c: FreeListInternalRep() cleanup.
- * win/README: [bug 2459744]: Removed outdated Msys + Mingw info.
-
-2009-11-10 Andreas Kupries <andreask@activestate.com>
-
- * generic/tclObj.c: Plug memory leak in TclContinuationsEnter().
- [Bug 2895323]. Backport from Tcl 8.5 branch, change by Don Porter.
-
-2009-11-09 Andreas Kupries <andreask@activestate.com>
-
- * generic/tclBasic.c (TclEvalObjEx): Moved the #280 decrement of
- refCount for the file path out of the branch after the whole
- conditional, closing a memory leak. Added clause on structure type
- to prevent seg.faulting. Backport from valgrinding the Tcl 8.5
- branch.
-
- * tests/info.test: Resolve ambiguous resolution of variable
- "res". Backport from 8.5
-
-2009-10-23 Andreas Kupries <andreask@activestate.com>
-
- * generic/tclCompCmds.c: [Bug 2881263] (TclCompileForeachCmd,
- TclCompileLindexCmd): Fixed. Moved the use of
- DefineLineInformation after all regular variable declarations, so
- that an empty statement (-UTIP_280) doesn't confuse c89 compilers.
+ * generic/tclBinary.c: Backport fix for [Bug 2857044].
+ * generic/tclDictObj.c: All freeIntRepProcs set typePtr to NULL.
+ * generic/tclEncoding.c:
+ * generic/tclIndexObj.c:
+ * generic/tclListObj.c:
+ * generic/tclNamesp.c:
+ * generic/tclObj.c:
+ * generic/tclPathObj.c:
+ * generic/tclProc.c:
+ * generic/tclRegexp.c:
+ * generic/tclStringObj.c:
+ * generic/tclVar.c:
- * library/platform/pkgIndex.tcl: Backported the platform packages
- * library/platform/platform.tcl: from head and8.5 into the 8.4
- * library/platform/shell.tcl: branch. Updated makefiles to install
- * unix/Makfile.in: the packages.
- * win/Makefile.in:
+2011-04-21 Don Porter <dgp@users.sourceforge.net>
- * generic/tclIO.c (FlushChannel): Skip OutputProc for low-level
- 0-length writes. When closing pipes which have already been closed
- not skipping leads to spurious SIG_PIPE signals. Reported by
- Mikhail Teterin <mi+thun@aldan.algebra.com>.
+ * generic/tclInt.h: Use macro to set List intreps.
+ * generic/tclListObj.c:
-2009-10-21 Donal K. Fellows <dkf@users.sf.net>
+ * generic/tclCmdIL.c: Limits on list length were too strict.
+ * generic/tclInt.h: Revised panics to errors where possible.
+ * generic/tclListObj.c:
- * generic/tclPosixStr.c: [Bug 2882561]: Work around oddity on Haiku OS
- where SIGSEGV and SIGBUS are the same value.
-
-2009-10-18 Joe Mistachkin <joe@mistachkin.com>
+ * generic/tclCompile.c: Make sure SetFooFromAny routines react
+ * generic/tclIO.c: reasonably when passed a NULL interp.
+ * generic/tclIndexObj.c:
+ * generic/tclListObj.c:
+ * generic/tclNamesp.c:
+ * generic/tclObj.c:
+ * generic/tclProc.c:
+ * macosx/tclMacOSXFCmd.c:
- * 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.
+2011-04-21 Jan Nijtmans <nijtmans@users.sf.net>
-2009-10-04 Daniel Steffen <das@users.sourceforge.net>
+ * generic/tcl.h: fix for [Bug 3288345]: Wrong Tcl_StatBuf
+ * generic/tclInt.h: used on MinGW. Make sure that all _WIN32
+ * win/tclWinFile.c: compilers use exactly the same layout
+ * win/configure.in: for Tcl_StatBuf - the one used by MSVC6 -
+ * win/configure: in all situations.
- * macosx/tclMacOSXBundle.c: Workaround CF memory managment bug in
- * unix/tclUnixInit.c: Mac OS X 10.4 & earlier. [Bug 2569449]
+2011-04-20 Andreas Kupries <andreask@activestate.com>
-2009-09-28 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclFCmd.c (TclFileAttrsCmd): Added commands to reset the
+ typePtr of the Tcl_Obj* whose int-rep was just purged. Required to
+ prevent a dangling IndexRep* to reused, smashing the heap. See
+ also the entries at 2011-04-16 and 2011-03-24 for the history of
+ the problem.
- * generic/tclAlloc.c: Cleaned up various routines in the
- * generic/tclCkalloc.c: call stacks for memory allocation to
- * generic/tclParse.c: guarantee that any size values computed
- * generic/tclThreadAlloc.c: are within the domains of the routines
- they get passed to. [Bugs 2557696 and 2557796].
+2011-04-19 Don Porter <dgp@users.sourceforge.net>
-2009-09-18 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclConfig.c: Reduce internals access in the implementation
+ of [<foo>::pkgconfig list].
- * generic/tclCmdMZ.c (Tcl_SubstObj): Pass 'length' values to
- recursive parsing calls to convert O(N^2) operations of [subst]
- to O(N).
+2011-04-18 Don Porter <dgp@users.sourceforge.net>
-2009-08-25 Andreas Kupries <andreask@activestate.com>
+ * generic/tclCmdIL.c: Use ListRepPtr(.) and other cleanup.
+ * generic/tclConfig.c:
+ * generic/tclListObj.c:
- * generic/tclBasic.c (Tcl_CreateInterp, Tcl_EvalTokensStandard,
- (EvalTokensStandard, Tcl_EvalEx, EvalEx, TclAdvanceContinuations,
- (TclEvalObjEx):
- * generic/tclCmdMZ.c (Tcl_SwitchObjCmd, ListLines):
- * generic/tclCompCmds.c (*):
- * generic/tclCompile.c (TclSetByteCodeFromAny, TclInitCompileEnv,
- (TclFreeCompileEnv, TclCompileScript):
- * generic/tclCompile.h (CompileEnv):
- * generic/tclInt.h (ContLineLoc, Interp):
- * generic/tclObj.c (ThreadSpecificData, ContLineLocFree,
- (TclThreadFinalizeObjects, TclInitObjSubsystem,
- (TclContinuationsEnter, TclContinuationsEnterDerived,
- (TclContinuationsCopy, TclContinuationsGet, TclFreeObj):
- * generic/tclProc.c (TclCreateProc):
- * generic/tclVar.c (TclPtrSetVar):
- * tests/info.test (info-30.0-22):
-
- Extended parser, compiler, and execution with code and attendant
- data structures tracking the positions of continuation lines which
- are not visible in script's, to properly account for them while
- counting lines for #280, during direct and compiled execution.
-
-2009-08-17 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclFileName.c: Correct result from [glob */test] when *
- * tests/fileName.test: matches something like ~foo. [Bug 2837800]
-
-2009-07-23 Joe Mistachkin <joe@mistachkin.com>
-
- * generic/tclNotify.c: Fix for [Bug 2820349].
+ * generic/tclInt.h: Define and use macros that test whether
+ * generic/tclBasic.c: a Tcl list value is canonical.
+ * generic/tclUtil.c:
-2009-07-14 Andreas Kupries <andreask@activestate.com>
+2011-04-16 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclBasic.c (DeleteInterpProc,TclArgumentBCEnter,
- (TclArgumentBCRelease, TclArgumentGet):
- * generic/tclCompile.c (EnterCmdWordIndex, TclCleanupByteCode,
- (TclInitCompileEnv, TclCompileScript):
- * generic/tclCompile.h (ExtCmdLoc):
- * generic/tclExecute.c (TclExecuteByteCode):
- * generic/tclInt.h (ExtIndex, CFWordBC):
- * tests/info.test (info-39.0):
+ * generic/tclFCmd.c (TclFileAttrsCmd): Tidied up the memory management
+ a bit to try to ensure that the dynamic and static cases don't get
+ confused while still promoting caching where possible. Added a panic
+ to trap problems in the case where an extension is misusing the API.
- Backport of some changes made to the Tcl head, to handle literal
- sharing better. The code here is much simpler (trimmed down)
- compared to the head as the 8.4 branch is not bytecode compiling
- whole files, and doesn't compile eval'd code either.
-
- Reworked the handling of literal command arguments in bytecode to
- be saved (compiler) and used (execution) per command (See the
- TCL_INVOKE_STK* instructions), and not per the whole bytecode.
- This removes the problems with location data caused by literal
- sharing in proc bodies. Simplified the associated datastructures
- (ExtIndex is gone, as is the function EnterCmdWordIndex).
+2011-04-13 Don Porter <dgp@users.sourceforge.net>
-2009-06-13 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclUtil.c: [Bug 3285375]: Rewrite of Tcl_Concat*()
+ routines to prevent segfaults on buffer overflow. Build them out of
+ existing primitives already coded to handle overflow properly. Uses
+ the new TclTrim*() routines.
- * generic/tclCompile.c: The value stashed in iPtr->compiledProcPtr
- * generic/tclProc.c: when compiling a proc survives too long. We
- * tests/execute.test: only need it there long enough for the right
- TclInitCompileEnv() call to re-stash it into envPtr->procPtr. Once
- that is done, the CompileEnv controls. If we let the value of
- iPtr->compiledProcPtr linger, though, then any other bytecode compile
- operation that takes place will also have its CompileEnv initialized
- with it, and that's not correct. The value is meant to control the
- compile of the proc body only, not other compile tasks that happen
- along. Thanks to Carlos Tasada for discovering and reporting the
- problem. [Bug 2802881].
+ * generic/tclCmdMZ.c: New internal utility routines TclTrimLeft()
+ * generic/tclInt.h: and TclTrimRight(). Refactor the
+ * generic/tclUtil.c: [string trim*] implementations to use them.
-2009-04-28 Jeff Hobbs <jeffh@ActiveState.com>
+2011-04-13 Miguel Sofer <msofer@users.sf.net>
- * unix/tcl.m4, unix/configure (SC_CONFIG_CFLAGS): harden the check
- to add _r to CC on AIX with threads.
+ * generic/tclVar.c: [Bug 2662380]: Fix crash caused by appending to a
+ variable with a write trace that unsets it.
-2009-04-27 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+2011-04-12 Don Porter <dgp@users.sourceforge.net>
- * generic/tclInt.h: Backport fix for [Bug 1028264]: WSACleanup() too
- * generic/tclEvent.c: early. The fix introduces "late exit handlers"
- * win/tclWinSock.c: for similar late process-wide cleanups.
+ * generic/tclStringObj.c: [Bug 3285472]: Repair corruption in
+ * tests/string.test: [string reverse] when string rep invalidation
+ failed to also reset the bytes allocated for string rep to zero.
-2009-04-27 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+2011-04-12 Venkat Iyer <venkat@comit.com>
- * win/tclWinSock.c: Backport fix for [Bug 2446662]: resync Win
- behavior on RST with that of unix (EOF).
+ * library/tzdata/Atlantic/Stanley: Update to Olson tzdata2011f
-2009-04-22 Andreas Kupries <andreask@activestate.com>
+2011-04-06 Miguel Sofer <msofer@users.sf.net>
- * generic/tclStringObj.c (UpdateStringOfString): Added cast to fix
- signed/unsigned mismatch breaking win32 symbol/debug build.
+ * generic/tclExecute.c (TclCompEvalObj): Earlier return if Tip280
+ gymnastics not needed.
-2009-04-15 Don Porter <dgp@users.sourceforge.net>
+2011-04-05 Venkat Iyer <venkat@comit.com>
- * generic/tclStringObj.c: AppendUnicodeToUnicodeRep failed
- to set stringPtr->allocated to 0, leading to crashes.
+ * library/tzdata/Africa/Casablanca: Update to Olson's tzdata2011e
+ * library/tzdata/America/Santiago:
+ * library/tzdata/Pacific/Easter:
+ * library/tzdata/America/Metlakatla: (new)
+ * library/tzdata/America/North_Dakota/Beulah: (new)
+ * library/tzdata/America/Sitka: (new)
-2009-04-14 Stuart Cassoff <stwo@users.sourceforge.net>
+2011-04-04 Don Porter <dgp@users.sourceforge.net>
- * unix/tcl.m4: Removed -Wno-implicit-int from CFLAGS_WARNING.
+ * README: Updated README files, repairing broken URLs and
+ * macosx/README: 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]
-2009-04-08 Don Porter <dgp@users.sourceforge.net>
+2011-04-02 Kevin B. Kenny <kennykb@acm.org>
- * library/tcltest/tcltest.tcl: Fixed unsafe [eval]s in the tcltest
- * library/tcltest/pkgIndex.tcl: package. [Bug 2570363]
+ * generic/tclStrToD.c (QuickConversion): Replaced another couple of
+ 'double' declarations with 'volatile double' to work around
+ misrounding issues in mingw-gcc 3.4.5.
-2009-04-07 Don Porter <dgp@users.sourceforge.net>
+2011-03-24 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclStringObj.c: Completed backports of fixes for
- [Bug 2494093] and [Bug 2553906].
+ * generic/tclFCmd.c (TclFileAttrsCmd): Ensure that any reference to
+ temporary index tables is squelched immediately rather than hanging
+ around to trip us up in the future.
-2009-03-30 Don Porter <dgp@users.sourceforge.net>
+2011-03-21 Jan Nijtmans <nijtmans@users.sf.net>
- * doc/Alloc.3: Size argument is "unsigned int". [Bug 2556263]
+ * 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
- * 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]
+2011-03-16 Jan Nijtmans <nijtmans@users.sf.net>
-2009-03-27 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclCkalloc.c: [Bug #3197864]: pointer truncation on Win64
+ TCL_MEM_DEBUG builds
- * tests/fileName.test: Tests for [Bug 2710920] to guard against
- its appearance.
+2011-03-16 Don Porter <dgp@users.sourceforge.net>
-2009-03-20 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclBasic.c: Some rewrites to eliminate calls to
+ * generic/tclParse.c: isspace() and their /* INTL */ risk.
+ * generic/tclProc.c:
- * generic/tclStringObj.c: Test stringObj-6.9 checks that
- * tests/stringObj.test: Tcl_AppendStringsToObj() no longer
- crashes when operating on a pure unicode value. [Bug 2597185]
+2011-03-16 Jan Nijtmans <nijtmans@users.sf.net>
- * generic/tclExecute.c (INST_CONCAT1): Panic when appends overflow
- the max length of a Tcl value. [Bug 2669109]
+ * unix/tcl.m4: Make SHLIB_LD_LIBS='${LIBS}' the default and
+ * unix/configure: set to "" on per-platform necessary basis.
+ Backported from TEA, but kept all original platform code which was
+ removed from TEA.
-2009-03-18 Don Porter <dgp@users.sourceforge.net>
+2011-03-14 Kevin B. Kenny <kennykb@acm.org>
- * win/tclWinFile.c (TclpObjNormalizePath): Corrected Tcl_Obj leak.
- Thanks to Joe Mistachkin for detection and patch. [Bug 2688184].
+ * tools/tclZIC.tcl (onDayOfMonth): Allow for leading zeroes
+ in month and day so that tzdata2011d parses correctly.
+ * library/tzdata/America/Havana:
+ * library/tzdata/America/Juneau:
+ * library/tzdata/America/Santiago:
+ * library/tzdata/Europe/Istanbul:
+ * library/tzdata/Pacific/Apia:
+ * library/tzdata/Pacific/Easter:
+ * library/tzdata/Pacific/Honolulu: tzdata2011d
-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].
+ * unix/configure.in: [Bug 3205320]: stack space detection defeated by inlining
+ * unix/configure: (autoconf-2.59)
-2008-02-06 Daniel Steffen <das@users.sourceforge.net>
+2011-03-09 Don Porter <dgp@users.sourceforge.net>
- * generic/tcl.h (Darwin): workaround conflict between deprecated tcl
- panic macro and panic() function declaration in <mach/mach.h> header.
+ * 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]
-2009-02-05 Don Porter <dgp@users.sourceforge.net>
+ * doc/tclvars.n: Formatting fix. Thanks to Pat Thotys.
- * 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]
+2011-03-08 Jan Nijtmans <nijtmans@users.sf.net>
-2009-02-04 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclBasic.c: Fix gcc warnings: variable set but not used
- * 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.
+2011-03-08 Don Porter <dgp@users.sourceforge.net>
-2009-01-09 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclInt.h: Remove TclMarkList() routine, an experimental
+ * generic/tclUtil.c: dead-end from the 8.5 alpha days.
- * 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/tclResult.c (ResetObjResult): Correct failure to clear
+ invalid intrep. Thanks to Colin McDonald. [Bug 3202905]
-2009-01-08 Don Porter <dgp@users.sourceforge.net>
+2011-03-06 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/tclBasic.c: More replacements of Tcl_UtfBackslash() calls
+ * generic/tclCompile.c: with TclParseBackslash() where possible.
+ * generic/tclParse.c:
+ * generic/tclUtil.c:
-2008-12-04 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclUtil.c (TclFindElement): Guard escape sequence scans
+ to not overrun the string end. [Bug 3192636]
- * generic/tclIOUtil.c (Tcl_FSGetNormalizedPath): Added another
- flag value TCLPATH_NEEDNORM to mark those intreps which need more
- complete normalization attention for correct results. [Bug 2385549]
+2011-03-05 Don Porter <dgp@users.sourceforge.net>
-2008-12-03 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclParse.c (TclParseBackslash): Correct trunction checks in
+ * tests/parse.test: \x and \u substitutions. [Bug 3200987]
- * generic/tclFileName.c (TclDoGlob): One of the
- Tcl_FSMatchInDirectory() calls did not have its return code
- checked. Some VFS drivers can return TCL_ERROR, and when that's
- not checked, the error message gets converted into a list of
- matching files returned by [glob], with ridiculous results.
+2011-01-26 Donal K. Fellows <dkf@users.sf.net>
-2008-12-01 Don Porter <dgp@users.sourceforge.net>
+ * doc/RegExp.3: [Bug 3165108]: Corrected documentation of description
+ of subexpression info in Tcl_RegExpInfo structure.
- * generic/tclIO.c (TclFinalizeIOSubsystem): Revised latest commit to
- something that doesn't crash the test suite.
+2011-01-25 Jan Nijtmans <nijtmans@users.sf.net>
-2008-11-25 Andreas Kupries <andreask@activestate.com>
+ * generic/tclCkalloc.c: [Bug 3129448]: Possible over-allocation on
+ * generic/tclHash.c: 64-bit platforms, part 2, backported
+ * generic/tclProc.c: strcpy->memcpy change but not change in any
+ struct.
- * generic/tclIO.c (TclFinalizeIOSubsystem): Applied backport of
- Alexandre Ferrieux's patch for [Bug 2270477] to prevent infinite
- looping during finalization of channels not bound to
- interpreters.
+2011-01-19 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
-2008-11-23 Andreas Kupries <andreask@activestate.com>
+ * generic/tclExecute.c: [Bug 3138178]: Backport of Miguel's 2010-09-22
+ fix on 8.6 branch (decache stack info wherever ::errorInfo may be
+ updated, for trace sanity).
- * generic/tclIO.c: Backport of fix for [Bug 2333466].
+2011-01-19 Jan Nijtmans <nijtmans@users.sf.net>
-2008-11-04 Jeff Hobbs <jeffh@ActiveState.com>
+ * tools/genStubs.tcl: Make sure to use CONST/VOID in stead of
+ * generic/tclIntDecls.h: const/void when appropriate. This allows to
+ * generic/tclIntPlatDecls.h:use const/void in the *.decls file always,
+ * generic/tclTomMathDecls.h:genStubs will do the right thing.
- * generic/tclPort.h: remove the ../{win,unix}/ header dirs as the
- build system already has it, and it confuses builds when used with
- private headers installed.
+2011-01-18 Jan Nijtmans <nijtmans@users.sf.net>
-2008-09-25 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclBasic.c: Various mismatches between Tcl_Panic
+ * generic/tclCompCmds.c: format string and its arguments,
+ * generic/tclCompExpr.c: discovered thanks to [Bug 3159920]
+ * generic/tclPreserve.c: (Backported)
+ * generic/tclTest.c:
- * doc/global.n: Correct false claim about [info locals].
+2011-01-17 Jan Nijtmans <nijtmans@users.sf.net>
-2008-08-14 Don Porter <dgp@users.sourceforge.net>
+ * win/tcl.m4: handle --enable-64bit=ia64 for gcc. BACKPORT.
+ * win/configure: (autoconf-2.59)
+ * win/tclWin32Dll.c: [Patch 3059922]: fixes for mingw64 - gcc4.5.1
+ * generic/tclIOCmd.c: [Bug 3148192]: Commands "read/puts" incorrectly
+ * tests/chanio.test: interpret parameters. Improved error-message
+ * tests/io.test regarding legacy form.
+ * tests/ioCmd.test
- * tests/fileName.test: Revise new tests for portability to case
- insensitive filesystems.
+2011-01-15 Kevin B. Kenny <kennykb@users.sf.net>
-2008-08-14 Daniel Steffen <das@users.sourceforge.net>
+ * doc/tclvars.n:
+ * generic/tclStrToD.c:
+ * generic/tclUtil.c (Tcl_PrintDouble):
+ * tests/util.test (util-16.*): Restored full Tcl 8.4 compatibility
+ for the formatting of floating point numbers when $::tcl_precision
+ is not zero. Added compatibility tests to make sure that excess
+ trailing zeroes are suppressed for all eight major code paths.
+ [Bug 3157475]
- * generic/tclCompile.h: add support for debug logging of DTrace
- * generic/tclBasic.c: 'proc', 'cmd' and 'inst' probes (does
- _not_ require a platform with DTrace).
+2011-01-13 Miguel Sofer <msofer@users.sf.net>
- * unix/Makefile.in: ensure Makefile shell is /bin/bash for
- * unix/configure.in (SunOS): DTrace-enabled build on Solaris.
- (followup to 2008-06-12) [Bug 2016584]
+ * generic/tclExecute.c (GrowEvaluationStack): Off-by-one error in
+ sizing the new allocation - was ok in comment but wrong in the code.
+ Triggered by [Bug 3142026] which happened to require exactly one more
+ than what was in existence. BACKPORT.
- * unix/tcl.m4 (SC_PATH_X): check for libX11.dylib in addition to
- libX11.so et al.
+2011-01-03 Jan Nijtmans <nijtmans@users.sf.net>
- * unix/configure: autoconf-2.13
+ * tools/genStubs.tcl: Fix "make genstubs", which was broken
+ since 2010-11-30, the TclDoubleDigits backport.
-2008-08-13 Don Porter <dgp@users.sourceforge.net>
+2010-12-31 Jan Nijtmans <nijtmans@users.sf.net>
- * generic/tclFileName.c: Fix for errors handling -types {}
- * tests/fileName.test: option to [glob]. [Bug 1750300]
- Thanks to Matthias Kraft and George Peter Staplin.
+ * generic/tclHash.c: [Bug 3007895]: Tcl_(Find|Create)HashEntry
+ stub entries can never be called. They still cannot be called
+ (no change in functionality), but at least they now do
+ exactly the same as the Tcl_(Find|Create)HashEntry macro's,
+ so the confusion addressed in this Bug report is gone.
+ (Backported from Tcl 8.6)
-2008-08-11 Andreas Kupries <andreask@activestate.com>
+2010-12-17 Stuart Cassoff <stwo@users.sourceforge.net>
- * generic/tclProc.c (Tcl_ProcObjCmd): Fixed memory leak triggered
- * tests/proc.test: by procbody::test::proc. See [Bug 2043636].
- Added a test case demonstrating the leak before the fix. Fixed a
- few spelling errors in test descriptions as well.
+ * unix/Makefile.in: Remove unwanted/obsolete 'ddd' target.
-2008-07-28 Andreas Kupries <andreask@activestate.com>
+2010-12-17 Stuart Cassoff <stwo@users.sourceforge.net>
- * generic/tclBasic.c: Added missing release of extended command
- word index when deleting an interpreter (DeleteInterpProc). Added
- missing ref count when creating an empty string as path (EvalEx).
+ * unix/Makefile.in: [Bug 2446711]: Remove 'allpatch' target.
- * generic/tclCompile.c (TclInitCompileEnv): Made same change to
- control flow as in TclEvalObjEx. Not needed while uplevel and
- siblings go through the eval-direct code path, however if that
- changes (like it did in 8.5+) better to have this in place instead
- of re-searching why certain places are without absolute locations.
+2010-12-17 Stuart Cassoff <stwo@users.sourceforge.net>
- * tests/info.test: Added tests 38.*, exactly testing the tracking
- of location for uplevel scripts, and made the testsuite fully
- usable with and without -singleproc 1.
+ * unix/Makefile.in: Use 'rpmbuild', not 'rpm' [Bug 2537626].
-2008-07-25 Daniel Steffen <das@users.sourceforge.net>
+2010-12-13 Jan Nijtmans <nijtmans@users.sf.net>
- * tests/info.test: Add !singleTestInterp constraint to various tests;
- (info-22.8, info-23.0): switch to glob matching to avoid sensitivity
- to tcltest.tcl line number changes. [Bug 1605269]
+ * unix/tcl.m4: Cross-compile support for Win and UNIX (backported)
+ * unix/configure: (autoconf-2.59)
+ * win/tcl.m4:
+ * win/configure.in:
+ * win/configure: (autoconf-2.59)
-2008-07-24 Andreas Kupries <andreask@activestate.com>
+2010-12-12 Stuart Cassoff <stwo@users.sourceforge.net>
- * tests/info.test: Tests 38.* added, exactly testing the tracking
- of location for uplevel scripts.
+ * unix/tcl.m4: Better building on OpenBSD.
+ * unix/configure: (autoconf-2.59)
-2008-07-23 Andreas Kupries <andreask@activestate.com>
+2010-12-10 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
- * generic/tclBasic.c: Modified TclArgumentGet to reject pure lists
- * generic/tclCmdIL.c: immediately, without search. Reworked setup
- * generic/tclCompile.c: of eoFramePtr, doesn't need the line
- * tests/info.test: information, more sensible to have everything
- on line 1 when eval'ing a pure list. Updated the users of the line
- information to special case this based on the frame type (i.e.
- TCL_LOCATION_EVAL_LIST). Added a testcase demonstrating the new
- behaviour.
+ * generic/tclIO.c: [backport] Make sure [fcopy -size ... -command ...] always
+ * tests/io.test: calls the callback asynchronously, even for size zero.
-2008-07-22 Andreas Kupries <andreask@activestate.com>
+2010-12-03 Jeff Hobbs <jeffh@ActiveState.com>
- * generic/tclBasic.c: Added missing function comments.
+ * generic/tclUtil.c (TclReToGlob): add extra check for multiple
+ inner *s that leads to poor recursive glob matching, defer to
+ original RE instead. tclbench RE var backtrack.
- * generic/tclCompile.c: Made the new TclEnterCmdWordIndex
- * generic/tclCompile.h: static.
+2010-12-01 Kevin B. Kenny <kennykb@acm.org>
- * generic/tclBasic.c: Reworked the handling of bytecode literals
- * generic/tclCompile.c: for #280 to fix the abysmal performance
- * generic/tclCompile.h: for deep recursion, replaced the linear
- * generic/tclExecute.c: search through the whole stack with
- * generic/tclInt.h: another hashtable and simplified the data
- structure used by the compiler (array instead of hashtable).
- Incidentially this also fixes the memory leak reported via [Bug
- 2024937].
+ * generic/tclStrToD.c (SetPrecisionLimits, TclDoubleDigits):
+ Added meaningless initialization of 'i', 'ilim' and 'ilim1'
+ to silence warnings from the C compiler about possible use of
+ uninitialized variables, Added a panic to the 'switch' that
+ assigns them, to assert that the 'default' case is impossible.
+ [Bug 3124675]
-2008-07-21 Andreas Kupries <andreask@activestate.com>
+2010-11-30 Andreas Kupries <andreask@activestate.com>
- * generic/tclBasic.c: Extended the existing TIP #280 system (info
- * generic/tclCmdAH.c: frame), added the ability to track the
- * generic/tclCompCmds.c: absolute location of literal procedure
- * generic/tclCompile.c: arguments, and making this information
- * generic/tclCompile.h: available to uplevel, eval, and
- * generic/tclInterp.c: siblings. This allows proper tracking of
- * generic/tclInt.h: absolute location through custom (Tcl-coded)
- * generic/tclNamesp.c: control structures based on uplevel, etc.
- * generic/tclProc.c:
+ * generic/tclInt.decls: Backport of Kevin B. Kenny's work on
+ * generic/tclInt.h: the Tcl Head, with help from Jeff Hobbs.
+ * generic/tclStrToD.c:
+ * generic/tclTest.c:
+ * generic/tclTomMath.decls:
+ * generic/tclUtil.c:
+ * tests/util.test:
+ * unix/Makefile.in:
+ * win/Makefile.in:
+ * win/makefile.vc: Rewrite of Tcl_PrintDouble and TclDoubleDigits
+ that (a) fixes a severe performance problem with floating point
+ shimmering reported by Karl Lehenbauer, (b) allows TclDoubleDigits
+ to generate the digit strings for 'e' and 'f' format, so that it
+ can be used for tcl_precision != 0 (and possibly later for [format]),
+ (c) fixes [Bug 3120139] by making TclPrintDouble inherently
+ locale-independent, (d) adds test cases to util.test for
+ correct rounding in difficult cases of TclDoubleDigits where fixed-
+ precision results are requested. (e) adds test cases to util.test for
+ the controversial aspects of [Bug 3105247]. As a side effect, two
+ more modules from libtommath (bn_mp_set_int.c and bn_mp_init_set_int.c)
+ are brought into the build, since the new code uses them.
-2008-07-07 Andreas Kupries <andreask@activestate.com>
+ * generic/tclIntDecls.h:
+ * generic/tclStubInit.c:
+ * generic/tclTomMathDecls.h: Regenerated.
- * generic/tclCmdIL.c (InfoFrameCmd): Fixed unsafe idiom of setting
- the interp result found by Don Porter.
+2010-11-30 Jeff Hobbs <jeffh@ActiveState.com>
-2008-07-04 Joe English <jenglish@users.sourceforge.net>
+ * generic/tclInt.decls, generic/tclInt.h, generic/tclIntDecls.h:
+ * generic/tclStubInit.c: TclFormatInt restored at slot 24
+ * generic/tclUtil.c (TclFormatInt): restore TclFormatInt func from
+ 2005-07-05 macro-ization. Benchmarks indicate it is faster, as a
+ key int->string routine (e.g. int-indexed arrays).
- * generic/tclEncoding.c(UtfToUtfProc): Avoid unwanted sign extension
- when converting incomplete UTF-8 sequences. See [Bug 1908443] for
- details.
+2010-11-23 Andreas Kupries <andreask@activestate.com>
-2008-07-03 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclVar.c (VarHashInvalidateEntry): Removed obsolete
+ patch for AIX defining this macro as function. This is not
+ necessary anymore. See ChangeLog entry 2010-07-28 (Bug 3037525)
+ for the actual bug and fix the patch was a workaround for.
- * library/package.tcl: Removed [file readable] testing from
- [tclPkgUnknown] and friends. We find out soon enough whether a
- file is readable when we try to [source] it, and not testing
- before allows us to workaround the bugs on some common filesystems
- where [file readable] lies to us. [Patch 1969717]
+2010-11-19 Jan Nijtmans <nijtmans@users.sf.net>
-2008-06-28 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclInterp.c: fix gcc warning: passing argument 3 of
+ 'Tcl_GetIndexFromObj' discards qualifiers from pointer target type
+ * generic/tclWinInit.c: fix gcc warning: dereferencing pointer
+ 'oemId' does break strict-aliasing rules
+ * win/tclWin32Dll.c: fix gcc warnings: unused variable 'registration'
+ * win/tclWinChan.c:
+ * win/tclWinFCmd.c:
+ * win/configure.in: Allow cross-compilation by default. (backported)
+ * win/tcl.m4: Use -pipe for gcc on win32 (backported)
+ * win/configure: (regenerated)
- * generic/tclIOUtil.c: Plug memory leak in latest commit. Thanks
- Rolf Ade for detecting and Dan Steffen for the fix [Bug 2004654].
+2010-11-18 Donal K. Fellows <dkf@users.sf.net>
-2008-06-23 Don Porter <dgp@users.sourceforge.net>
+ * doc/file.n: [Bug 3111298]: Typofix.
- * generic/tclIOUtil.c: Fixed bug in Tcl_GetTranslatedPath() when
- operating on the "Special path" variant of the "path" Tcl_ObjType
- intrep. A full normalization was getting done, in particular, coercing
- relative paths to absolute, contrary to what the function of
- producing the "translated path" is supposed to do. [Bug 1972879].
+2010-11-16 Jan Nijtmans <nijtmans@users.sf.net>
-2008-06-20 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclPlatDecls.h: [Bug 3110161]: Extensions using TCHAR don't
+ compile on VS2005 SP1
- * tests/binary.test: Corrected flawed tests revealed by a -debug 1
- * tests/io.test: -singleproc 1 test suite run.
+2010-11-15 Andreas Kupries <andreask@activestate.com>
-2008-06-18 Don Porter <dgp@users.sourceforge.net>
+ * doc/interp.n: [Bug 3081184]: TIP #378 backport.
+ * doc/tclvars.n: Performance fix for TIP #280.
+ * generic/tclBasic.c:
+ * generic/tclExecute.c:
+ * generic/tclInt.h:
+ * generic/tclInterp.c:
+ * tests/info.test:
+ * tests/interp.test:
- * generic/tclParseExpr.c: Disabled attempts to support [expr]
- functions named eq(...) or ne(...). Any attempts to use such
- functions were panicking. [Bug 1971879].
+2010-11-03 Kevin B. Kenny <kennykb@acm.org>
-2008-06-16 Andreas Kupries <andreask@activestate.com>
+ * generic/tclCompCmds.c (TclCompileCatchCmd):
+ * tests/compile.test (compile-3.6): [Bug 3098302]: Reworked the
+ compilation of the [catch] command so as to avoid placing any code
+ that might throw an exception (specifically, any initial substitutions
+ or any stores to result or options variables) between the BEGIN_CATCH
+ and END_CATCH but outside the exception range. Added a test case that
+ panics on a stack smash if the change is not made.
- * generic/tclCmdIL.c (InfoFrameCmd): Backport of fix made on the
- * tests/info.test: head branch :: Moved the code looking up the
- information for key 'proc' out of the TCL_LOCATION_BC branch to
- after the switch, this is common to all frame types. Updated the
- testsuite to match. This was exposed by the 2008-06-08 commit
- (Miguel), switching uplevel from direct eval to compilation. Fixes
- [Bug 1987851].
+2010-11-01 Stuart Cassoff <stwo@users.sourceforge.net>
-2008-06-12 Andreas Kupries <andreask@activestate.com>
+ * library/safe.tcl: Improved handling of non-standard module
+ * tests/safe.test: path lists, empty path lists in particular.
- * generic/tclCmdIL.c (InfoFrameCmd): TIP #280 conditional
- feature. Added checks to validate HashEntry and HashTable
- information gotten from Command structures. This seems to be
- needed to handle structures managed by Itcl.
+2010-11-01 Kevin B. Kenny <kennykb@acm.org>
-2008-06-12 Daniel Steffen <das@users.sourceforge.net>
+ * library/tzdata/Asia/Hong_Kong:
+ * library/tzdata/Pacific/Apia:
+ * library/tzdata/Pacific/Fiji: Olson's tzdata2010o.
- * unix/Makefile.in: add complete deps on tclDTrace.h.
+2010-10-23 Jan Nijtmans <nijtmans@users.sf.net>
- * unix/Makefile.in: clean generated tclDTrace.h file.
- * unix/configure.in (SunOS): fix static DTrace-enabled build.
+ * tools/uniParse.tcl: [Bug 3085863]: tclUniData 9 years old
+ * tools/uniClass.tcl: Upgrade everything to Unicode 6.0, except
+ * tests/utf.test: non-BMP characters > 0xFFFF
+ * generic/tclUniData.c: (re-generated)
+ * generic/regc_locale.c:(re-generated)
+ * generic/regcomp.c: fix comment
+ * win/rules.vc Update for VS10
- * unix/tcl.m4 (SunOS-5.11): fix 64bit amd64 support with gcc & Sun cc.
- * unix/configure: autoconf-2.13
+2010-10-09 Miguel Sofer <msofer@users.sf.net>
-2008-05-26 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclExecute.c: fix overallocation of exec stack in TEBC
+ (mixing numwords and numbytes)
- * tests/io.test (io-53.9): need to close chan before removing file.
+2010-10-01 Jeff Hobbs <jeffh@ActiveState.com>
-2008-05-23 Andreas Kupries <andreask@activestate.com>
+ * generic/tclExecute.c (EvalStatsCmd): change 'evalstats' to
+ return data to interp by default, or if given an arg, use that as
+ filename to output to (accepts 'stdout' and 'stderr').
+ Fix output to print used inst count data.
+ * generic/tclCkalloc.c: change TclDumpMemoryInfo sig to allow
+ * generic/tclInt.decls: objPtr as well as FILE* as output.
+ * generic/tclIntDecls.h:
- * win/tclWinChan.c (FileWideSeekProc): Accepted a patch by
- Alexandre Ferrieux <ferrieux@users.sourceforge.net> to fix the
- [Bug 1965787]. 'tell' now works for locations > 2 GB as well
- instead of going negative.
+2010-09-24 Andreas Kupries <andreask@activestate.com>
- * generic/tclIO.c (Tcl_SetChannelBufferSize): Accepted a patch by
- * tests/io.test: Alexandre Ferrieux <ferrieux@users.sourceforge.net>
- to fix the [Bug 1969953]. Buffersize outside of the supported
- range are now clipped to nearest boundary instead of ignored.
+ * tclWinsock.c: [Bug 3056775]: Fixed race condition between thread
+ and internal co-thread access of a socket's structure because of
+ the thread not using the socketListLock in TcpAccept(). Added
+ documentation on how the module works to the top.
-2008-04-26 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+2010-09-23 Don Porter <dgp@users.sourceforge.net>
- * generic/tclAsync.c: Tcl_AsyncDelete(): panic if attempt
- to locate handler token fails. Happens when some other
- thread attempts to delete somebody else's token.
+ * generic/tclCmdAH.c: Fix cases where value returned by
+ * generic/tclEvent.c: Tcl_GetReturnOptions() was leaked.
+ * generic/tclMain.c: Thanks to Jeff Hobbs for discovery of the
+ anti-pattern to seek and destroy.
- Also, panic early if we find out the wrong thread attempting
- to delete the async handler (common trap). As, only the one
- that created the handler is allowed to delete it.
+2010-09-19 Donal K. Fellows <dkf@users.sf.net>
-2008-04-17 Andreas Kupries <andreask@activestate.com>
+ * doc/file.n (file readlink): [Bug 3070580]: Typofix.
- *** 8.4.19 TAGGED FOR RELEASE ***
+2010-09-10 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclCompExpr.c (CompileMathFuncCall): Added
- * tests/compExpr.test (compExpr-5.10): Tcl_ResetResult before
- appending error message, to clear out possible sharing. Added test
- case demonstrating the crash (abort on shared object) without the
- fix.
+ * doc/regsub.n: [Bug 3063568]: Fix for gotcha in example due to Tcl's
+ special handling of backslash-newline. Makes example slightly less
+ pure, but more useful.
-2008-04-15 Andreas Kupries <andreask@activestate.com>
+2010-09-08 Andreas Kupries <andreask@activestate.com>
- * generic/tclIO.c (CopyData): Applied another patch by Alexandre
- * io.test (io-53.8a): Ferrieux <ferrieux@users.sourceforge.net>,
- to shift EOF handling to the async part of the command if a
- callback is specified, should the channel be at EOF already when
- fcopy is called. Testcase by myself.
+ *** 8.5.9 TAGGED FOR RELEASE ***
-2008-04-14 Kevin B. Kenny <kennykb@acm.org>
+ * doc/tm.n: Added underscore to the set of characters accepted in
+ module names. This is true for quite some time in the code, this
+ change catches up the documentation.
- * unix/tclUnixTime.c (TclpGetClicks, Tcl_GetTime): Removed
- obsolete use of 'struct timezone' in the call to 'gettimeofday'.
- [Bug 1942197].
-
-2008-04-14 Don Porter <dgp@users.sourceforge.net>
+2010-09-08 Don Porter <dgp@users.sourceforge.net>
- * generic/tclExecute.c: Plug memory leak introduced in the
- 2008-03-07 commit. [Bug 1940433]
+ * changes: Update for 8.5.9 release.
-2008-04-11 Don Porter <dgp@users.sourceforge.net>
+ * win/tclWin32Dll.c: #ifdef protections to permit builds with
+ * win/tclWinChan.c: mingw on amd64 systems. Thanks to "mescalinum"
+ * win/tclWinFCmd.c: for reporting and testing.
- * README: Bump version number to 8.4.19
- * generic/tcl.h:
- * tools/tcl.wse.in:
- * unix/configure.in:
- * unix/tcl.spec:
- * win/README.binary:
- * win/configure.in:
+2010-09-06 Stuart Cassoff <stwo@users.sourceforge.net>
- * unix/configure: autoconf-2.13
- * win/configure:
+ * unix/configure.in, generic/tclIOUtil.c (Tcl_Stat): Updated so that
+ we do not assume that all unix systems have the POSIX blkcnt_t type,
+ since OpenBSD apparently does not. Backported from HEAD (2010-02-16).
+ * unix/configure: autoconf-2.59
- * changes: updates for 8.4.19 release.
+2010-09-02 Andreas Kupries <andreask@activestate.com>
-2008-04-10 Andreas Kupries <andreask@activestate.com>
+ * doc/glob.n: Fixed documentation ambiguity regarding the handling
+ of -join.
- * generic/tclIOCmd.c (Tcl_FcopyObjCmd): Keeping check for negative
- values, changed to not be an error, but behave like the special
- value -1 (copy all, default).
+ * library/safe.tcl (::safe::AliasGlob): Fixed another problem, the
+ option -join does not stop option processing in the core builtin,
+ so the emulation must not do that either.
- * tests/iocmd.test (iocmd-15.{12,13}): Removed.
+2010-09-01 Andreas Kupries <andreas_kupries@users.sourceforge.net>
- * tests/io.test (io-52.5{,a,b}): Reverted last change, added
- comment regarding the meaning of -1, added two more testcases for
- other negative values, and input wrapped to negative.
+ * library/safe.tcl (::safe::AliasGlob): Moved the command
+ extending the actual glob command with a -directory flag to when
+ we actually have a proper untranslated path,
-2008-04-09 Andreas Kupries <andreask@activestate.com>
+2010-09-01 Don Porter <dgp@users.sourceforge.net>
- * tests/io.test (io-52.5): Removed '-size -1' from test, does not
- seem to have any bearing, and was an illegal value. Test case is
- not affected by the value of -size, test flag restoration and that
- everything was properly copied.
+ * changes: Update for 8.5.9 release.
- * generic/tclIOCmd.c (Tcl_FcopyObjCmd): Added checking of -size
- * tests/ioCmd.test (iocmd-15.{13,14}): value to reject negative
- values, and values overflowing 32-bit signed. [Bug 1557855]. Basic
- patch by Alexandre Ferrieux <ferrieux@users.sourceforge.net>, with
- modifications from me to separate overflow from true negative
- value. Extended testsuite.
+2010-09-01 Andreas Kupries <andreask@activestate.com>
-2008-04-08 Andreas Kupries <andreask@activestate.com>
+ * generic/tclExecute.c: [Bug 3057639]. Applied patch by Jeff to
+ * generic/tclVar.c: make the behaviour of lappend in bytecompiled
+ * tests/append.test: mode consistent with direct-eval and 'append'
+ * tests/appendComp.test: generally. Added tests (append*-9.*)
+ showing the difference.
+ ***POTENTIAL INCOMPATIBILITY***
- * tests/io.test (io-53.8,53.9,53.10): Backported das' fix of typo
- and quoting for spaces in builddir path.
-
-2008-04-07 Andreas Kupries <andreask@activestate.com>
+2010-09-01 Donal K. Fellows <dkf@users.sf.net>
- * tests/io.test (io-53.10): Testcase for bi-directionaly fcopy.
- * generic/tclIO.c: Additional changes to data structures for fcopy
- * generic/tclIO.h: and channels to perform proper cleanup in case
- of a channel having two background copy operations running as is
- now possible.
+ * tools/tcltk-man2html.tcl: Improve handling of cross-links for
+ options between Ttk manual pages.
- * generic/tclIO.c (BUSY_STATE, CheckChannelErrors,
- TclCopyChannel): New macro, and the places using it. This change
- allows for bi-directional fcopy on channels. [Bug 1350564].
- Thanks to Alexandre Ferrieux <ferrieux@users.sourceforge.net>
- for the patch.
+ * doc/Tcl.n: Avoid nroff hazards when generating documentation.
- * tests/io.test (io-53.9): Made test cleanup robust against the
- possibility of slow process shutdown on Windows. Backported from
- Kevin Kenny's change to the same test on the 8.5 and head
- branches.
+2010-08-31 Andreas Kupries <andreask@activestate.com>
-2008-04-04 Andreas Kupries <andreask@activestate.com>
+ * win/tcl.m4: Applied patch by Jeff fixing issues with the
+ manifest handling on Win64.
+ * win/configure: Regenerated.
- * tests/io.test (io-53.9): Added testcase for [Bug 780533], based
- on Alexandre's test script. Also fixed problem with timer in
- preceding test, was not canceled properly in the ok case.
+2010-08-29 Donal K. Fellows <dkf@users.sf.net>
-2008-04-03 Andreas Kupries <andreask@activestate.com>
+ * doc/dict.n: [Bug 3046999]: Corrected cross reference to array
+ manpage to refer to (correct) existing subcommand.
- * generic/tclIO.c (CopyData): Applied patch [Bug 1932639] to
- * tests/io.test: prevent fcopy from calling -command synchronously
- the first time. Thanks to Alexandre Ferrieux
- <ferrieux@users.sourceforge.net> for report and patch.
+2010-08-26 Jeff Hobbs <jeffh@ActiveState.com>
-2008-04-02 Andreas Kupries <andreask@activestate.com>
+ * unix/configure, unix/tcl.m4: SHLIB_LD_LIBS='${LIBS}' for OSF1-V*.
+ Add /usr/lib64 to set of auto-search dirs. [Bug 1230554]
+ (SC_PATH_X): Correct syntax error when xincludes not found.
- * generic/tclIO.c (CopyData): Applied patch for the fcopy problem
- [Bug 780533], with many thanks to Alexandre Ferrieux
- <ferrieux@users.sourceforge.net> for tracking it down and
- providing a solution. Still have to convert his test script into
- a proper test case.
+ * win/Makefile.in (VC_MANIFEST_EMBED_DLL VC_MANIFEST_EMBED_EXE):
+ * win/configure, win/configure.in, win/tcl.m4: SC_EMBED_MANIFEST
+ macro and --enable-embedded-manifest configure arg added to
+ support manifest embedding where we know the magic. Help prevents
+ DLL hell with MSVC8+.
-2008-03-27 Daniel Steffen <das@users.sourceforge.net>
+2010-08-24 Don Porter <dgp@users.sourceforge.net>
- * unix/tcl.m4 (SunOS-5.1x): fix 64bit support for Sun cc. [Bug 1921166]
+ * changes: Update for 8.5.9 release.
- * unix/dltest/Makefile.in: support use of LDFLAGS in SHLIB_LD.
+2010-08-23 Kevin B. Kenny <kennykb@acm.org>
- * unix/configure: autoconf-2.13
+ * library/tzdata/Africa/Cairo:
+ * library/tzdata/Asia/Gaza: Olson's tzdata2010l.
-2008-03-24 Pat Thoyts <patthoyts@users.sourceforge.net>
+2010-08-19 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclBinary.c: bug #1923966 - crash in binary format
- * tests/binary.test: Added tests for the above crash condition.
+ * generic/tclTrace.c (TraceExecutionObjCmd, TraceCommandObjCmd)
+ (TraceVariableObjCmd): [Patch 3048354]: Use memcpy() instead of
+ strcpy() to avoid buffer overflow; we have the correct length of data
+ to copy anyway since we've just allocated the target buffer.
-2008-03-11 Daniel Steffen <das@users.sourceforge.net>
+2010-08-15 Donal K. Fellows <dkf@users.sf.net>
- * macosx/tclMacOSXNotify.c: avoid using CoreFoundation after fork() on
- Darwin 9 even when TclpCreateProcess() uses vfork().
+ * generic/tclProc.c (ProcWrongNumArgs): [Bug 3045010]: Make the
+ handling of passing the wrong number of arguments to [apply] somewhat
+ less verbose when a lambda term is present.
-2008-03-07 Don Porter <dgp@users.sourceforge.net>
+2010-08-12 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclExecute.c (Tcl_ExprObj): Revised expression bytecode
- compiling so that bytecodes invalid due to changing context or due
- to the difference between expressions and scripts are not reused.
- [Bug 1899164].
+ * generic/tclCmdMZ.c (Tcl_RegexpObjCmd): [Bug 2826551, Patch 2948425]:
+ Backport of updates to make handling of RE line anchors correct.
- * generic/tclTest.c: Backport the [testexprlongobj] testing command.
+2010-08-11 Jeff Hobbs <jeffh@ActiveState.com>
- * tests/execute.test (execute-6.8): Added tests checking that
- bytecode is invalidates in the right situations.
+ * unix/ldAix: Remove ancient (pre-4.2) AIX support
+ * unix/configure: regen with ac-2.59
+ * unix/configure.in, unix/tclConfig.sh.in, unix/Makefile.in:
+ * unix/tcl.m4 (AIX): Remove the need for ldAIX, replace with
+ -bexpall/-brtl. Remove TCL_EXP_FILE (export file) and other baggage
+ that went with it. Remove pre-4 AIX build support.
-2008-03-03 Reinhard Max <max@suse.de>
+2010-08-10 Jeff Hobbs <jeffh@ActiveState.com>
- * unix/tclUnixChan.c: Fix mark and space parity on Linux, which
- uses CMSPAR instead of PAREXT.
+ * generic/tclUtil.c (TclByteArrayMatch): Patterns may not be
+ null-terminated, so account for that.
-2008-02-27 Pat Thoyts <patthoyts@users.sourceforge.net>
+2010-08-05 Don Porter <dgp@users.sourceforge.net>
- * library/http/pkgIndex.tcl: Backported 2.5.5 changes from
- * library/http/http.tcl: 8.5 version.
- * doc/http.n: Document the meta accessor.
+ * changes: Update for 8.5.9 release.
-2008-02-26 Jeff Hobbs <jeffh@ActiveState.com>
+2010-08-04 Jeff Hobbs <jeffh@ActiveState.com>
- * generic/tclIOCmd.c (Tcl_GetsObjCmd): do not reuse resultObj as
- it may be shared (crash condition).
+ * unix/tclUnixFCmd.c: Adjust license header as per
+ ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
-2008-02-22 Pat Thoyts <patthoyts@users.sourceforge.net>
+ * license.terms: Fix DFARs note for number-adjusted rights clause
- * library/http/pkgIndex.tcl: Set version 2.5.4
- * library/http/http.tcl: Fix for bug #1818565. Always check that
- the state array exists in the http::status command.
+ * win/tclWin32Dll.c (asciiProcs, unicodeProcs):
+ * win/tclWinLoad.c (TclpDlopen): 'load' use LoadLibraryEx with
+ * win/tclWinInt.h (TclWinProcs): LOAD_WITH_ALTERED_SEARCH_PATH to
+ prefer dependent DLLs in same dir as loaded DLL.
+ ***POTENTIAL INCOMPATIBILITY***
-2008-02-06 Don Porter <dgp@users.sourceforge.net>
+ * win/Makefile.in (%.${OBJEXT}): better implicit rules support
- *** 8.4.18 TAGGED FOR RELEASE ***
+2010-08-04 Don Porter <dgp@users.sourceforge.net>
- * README: Bump version number to 8.4.18
- * generic/tcl.h:
+ * generic/tcl.h: Bump to 8.5.9 for release.
+ * library/init.tcl:
* tools/tcl.wse.in:
* unix/configure.in:
* unix/tcl.spec:
- * win/README.binary:
* win/configure.in:
+ * README:
- * unix/configure: autoconf-2.13
+ * unix/configure: autoconf-2.59
* win/configure:
- * changes: updates for 8.4.18 release.
+ * changes: Update for 8.5.9 release.
-2008-02-02 Daniel Steffen <das@users.sourceforge.net>
-
- * unix/configure.in (Darwin): correct Info.plist year substitution in
- non-framework builds.
+2010-08-04 Andreas Kupries <andreask@activestate.com>
- * unix/configure: autoconf-2.13
-
-2008-01-30 Miguel Sofer <msofer@users.sf.net>
-
- * generic/tclInterp.c (Tcl_GetAlias): fix for [Bug 1882373]
-
-2008-01-13 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclIORChan.c: [Bug 3034840]: Fixed reference counting
+ * tests/ioCmd.test: in InvokeTclMethod and callers.
- * win/tclWinSerial.c (SerialCloseProc, TclWinOpenSerialChannel):
- use critical section for read & write side. [Bug 1353846] (newman)
+2010-08-03 Andreas Kupries <andreask@activestate.com>
-2007-12-31 Don Porter <dgp@users.sourceforge.net>
+ * tests/var.test (var-19.1): [Bug 3037525]: Added test demonstrating
+ the local hashtable deletion crash and fix.
- *** 8.4.17 TAGGED FOR RELEASE ***
+ * tests/info.test (info-39.1, test_info_frame): Changed absolute to
+ relative frame adressing to handle difference between testing with
+ -singleproc 1 vs. the default -singleproc 0. Plus comment fix. The
+ test and issue are not relevant to the trunk, forward porting is not
+ required.
- * changes: updates for 8.4.17 release.
- * doc/filename.n: Typo
-
-2007-12-18 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
-
- * generic/regguts.h, generic/regc_color.c, generic/regc_nfa.c:
- Fixes for problems created when processing regular expressions that
- generate very large automata. An enormous number of thanks to Will
- Drewry <wad@google.com>, Tavis Ormandy <taviso@google.com>, and Tom
- Lane <tgl@sss.pgh.pa.us> from the Postgresql crowd for their help in
- tracking these problems down. [Bug 1810264]
-
-2007-12-14 Jeff Hobbs <jeffh@ActiveState.com>
-
- * win/README: updated notes
+2010-08-03 Don Porter <dgp@users.sourceforge.net>
-2007-12-14 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+ * changes: Update for 8.5.9 release.
- * unix/tclUnixCompat.c (TclpGetHostByName): Really applied
- the change noted on 2007-11-13 by dkf below.
+2010-08-02 Kevin B. Kenny <kennykb@users.sf.net>
-2007-12-13 Jeff Hobbs <jeffh@ActiveState.com>
+ * library/tzdata/America/Bahia_Banderas:
+ * library/tzdata/Pacific/Chuuk:
+ * library/tzdata/Pacific/Pohnpei:
+ * library/tzdata/Africa/Cairo:
+ * library/tzdata/Europe/Helsinki:
+ * library/tzdata/Pacific/Ponape:
+ * library/tzdata/Pacific/Truk:
+ * library/tzdata/Pacific/Yap: Olson's tzdata2010k.
- * generic/tclIOUtil.c (TclGetOpenMode): Only set the O_APPEND flag
- * tests/ioUtil.test (ioUtil-4.1): on a channel for the 'a'
- mode and not for 'a+'. [Bug 1773127] (backport from HEAD)
+2010-07-28 Miguel Sofer <msofer@users.sf.net>
-2007-12-05 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * generic/tclVar.c: [Bug 3037525]: lose fickle optimisation in
+ TclDeleteVars (used for runtime-created locals) that caused crashes.
- * generic/tclCmdIL.c (Tcl_LsearchObjCmd): Prevent shimmering crash
- when -exact and -integer/-real are mixed. [Bug 1844789]
-
-2007-11-28 Jeff Hobbs <jeffh@ActiveState.com>
-
- * win/tclWinSock.c (Tcl_GetHostName): update to previous fix to
- set hostname length appropriately, clean up check overall.
-
-2007-11-27 Don Porter <dgp@users.sourceforge.net>
-
- * win/tclWinSock.c: Add missing encoding conversion of the
- [info hostname] value from the system encoding to Tcl's internal
- encoding. This is important now that ICANN no longer limits host
- names to ASCII. [Bug 1823552]
-
-2007-11-26 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
-
- * generic/tclThread.c: Back-port locking changes from Tcl8.5
- in Tcl_Mutex/ConditionFinlize. Now we properly master-lock
- the finalization of sync primitives.
-
-2007-11-15 Don Porter <dgp@users.sourceforge.net>
-
- * generic/regc_nfa.c: Fixed infinite loop in the regexp compiler
- * generic/regcomp.c: [Bug 1810038]. Corrected looping logic in
- * tests/regexp.test: fixempties() to avoid wasting time walking a
- list of dead states [Bug 1832612]. Convert optst() from expensive
- no-op to a cheap no-op. Improve newline usage in debug output.
+2010-07-25 Jan Nijtmans <nijtmans@users.sf.net>
-2007-11-13 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * generic/tclInt.h: [Bug 3030870]: Make itcl 3.x built with pre-8.6
+ * generic/tclBasic.c: work in 8.6 revert tclInt.h to what it was
+ before, and relax the relation between Tcl_CallFrame and CallFrame.
- * unix/tclUnixCompat.c (TclpGetHostByName): The six-argument form of
- getaddressbyname_r() uses the fifth argument to indicate whether the
- lookup succeeded or not on at least one platform. [Bug 1618235]
+2010-07-17 Jan Nijtmans <nijtmans@users.sf.net>
-2007-10-30 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * generic/tcl.h: [Bug 3030870]: Make itcl 3.x built with pre-8.6
+ * generic/tclInt.h: work in 8.6
- * generic/regc_lex.c (lexescape): Ensure that backreference numbers
- can't overflow a signed int in a way that breaks things. [Bug 1810264]
+2010-07-02 Donal K. Fellows <dkf@users.sf.net>
-2007-10-15 Miguel Sofer <msofer@users.sf.net>
+ * generic/tclExecute.c (IllegalExprOperandType): [Bug 3024379]: Made
+ sure that errors caused by an argument to an operator being outside
+ the domain of the operator all result in ::errorCode being ARITH
+ DOMAIN and not NONE.
- * generic/tclParse.c (Tcl_ParseBraces): fix for possible read
- after the end of buffer, [Bug 1813528] (Joe Mistachkin).
+2010-07-02 Jan Nijtmans <nijtmans@users.sf.net>
-2007-10-03 Miguel Sofer <msofer@users.sf.net>
+ * generic/tclIntDecls.h: [Bug 803489]: Tcl_FindNamespace problem in
+ the Stubs table.
- * generic/tclObj.c (Tcl_FindCommandFromObj): fix finding a deleted
- command; cannot trigger this from Tcl itself, but crash reported
- on xotcl. This check is new to 8.4 but exists in 8.5, so this is a
- backport or something. Thanks Gustaf Neumann.
+2010-07-01 Donal K. Fellows <dkf@users.sf.net>
-2007-10-02 Jeff Hobbs <jeffh@ActiveState.com>
+ * doc/mathop.n: [Bug 3023165]: Fix typo that was preventing proper
+ rendering of the exclusive-or operator.
- * generic/tcl.h (Tcl_DecrRefCount): Update change from 2006-05-29
- to make macro more warning-robust in unbraced if code.
-
-2007-10-02 Don Porter <dgp@users.sourceforge.net>
+2010-06-28 Jan Nijtmans <nijtmans@users.sf.net>
- * README: Bump version number to 8.4.17
- * generic/tcl.h:
- * tools/tcl.wse.in:
- * unix/configure.in:
- * unix/tcl.spec:
- * win/README.binary:
- * win/configure.in:
+ * generic/tclPosixStr.c: [Bug 3019634]: errno.h and tclWinPort.h have
+ conflicting definitions.
- * unix/configure: autoconf-2.13
- * win/configure:
+2010-06-22 Donal K. Fellows <dkf@users.sf.net>
-2007-09-20 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclCmdIL.c (Tcl_LsetObjCmd): [Bug 3019351]: Corrected wrong
+ args message.
- *** 8.4.16 TAGGED FOR RELEASE ***
+2010-06-18 Donal K. Fellows <dkf@users.sf.net>
- * doc/load.n: Backport corrected example.
+ * library/init.tcl (auto_execok): [Bug 3017997]: Add .cmd to the
+ default list of extensions that we can execute interactively.
-2007-09-19 Don Porter <dgp@users.sourceforge.net>
+2010-06-16 Jan Nijtmans <nijtmans@users.sf.net>
- * unix/Makefile.in: Update `make dist` so that tclDTrace.d is
- included in the source code distribution.
+ * tools/loadICU.tcl: [Bug 3016135]: Traceback using clock format
+ * library/msgs/he.msg: with locale of he_IL
- * generic/tclPkg.c: Backport fix for [1573844] to the
- * tests/pkg.test: TCL_TIP268 sections.
+2010-06-09 Andreas Kupries <andreask@activestate.com>
-2007-09-18 Don Porter <dgp@users.sourceforge.net>
+ * library/platform/platform.tcl: Added OSX Intel 64bit
+ * library/platform/pkgIndex.tcl: Package updated to version 1.0.9.
+ * unix/Makefile.in:
+ * win/Makefile.in:
- * changes: updates for 8.4.16 release.
+2010-05-26 Donal K. Fellows <dkf@users.sf.net>
-2007-09-15 Daniel Steffen <das@users.sourceforge.net>
+ * doc/socket.n: [Bug 3007442]: Server sockets never took a host
+ argument, so the list of options must precede the port argument.
- * unix/tcl.m4 (SunOS-5.1x): replace direct use of '/usr/ccs/bin/ld'
- in SHLIB_LD by 'cc' compiler driver.
- * unix/configure: autoconf-2.13
+2010-05-25 Jan Nijtmans <nijtmans@users.sf.net>
-2007-09-14 Daniel Steffen <das@users.sourceforge.net>
+ * unix/tclUnixPort.h: [Bug 2991415]: tclport.h #included before
+ * win/tclWinPort.h: limits.h
+ * generic/tclInt.h:
- * generic/tclDTrace.d (new file): add DTrace provider for Tcl; allows
- * generic/tclCompile.h: tracing of proc and command entry &
- * generic/tclBasic.c: return, bytecode execution, object
- * generic/tclExecute.c: allocation and more; with essentially
- * generic/tclInt.h: zero cost when tracing is inactive;
- * generic/tclObj.c: enable with --enable-dtrace configure
- * generic/tclProc.c: arg (disabled by default, will only
- * unix/Makefile.in: enable if DTrace is present).
- * unix/configure.in: [Patch 1793984]
+2010-05-21 Jan Nijtmans <nijtmans@users.sf.net>
- * macosx/Makefile: enable DTrace support.
+ * tools/installData.tcl: Make sure that copyDir only receives
+ normalized paths. Backported from trunk.
+ * generic/tclPlatDecls.h: Fix <tchar.h> inclusion for CYGWIN.
+ Backported from trunk (although for trunk this was moved to
+ tclWinPort.h)
+ * generic/tclPathObj.c: Fix Tcl_SetStringObj usage for CYGWIN. This
+ function can only be used with unshared objects. This causes a crash
+ on CYGWIN. (backported from trunk)
+ * generic/tclFileName.c: Don't declare cygwin_conv_to_win32_path here
+ * win/tclWinChan.c: Fix various minor other gcc warnings, like
+ * win/tclWinConsole.c: signed<->unsigned mismatch. Backported from
+ * win/tclWinDde.c: trunk.
+ * win/tclWinNotify.c:
+ * generic/tclStrToD.c: [Bug 3005233]: fix for build on OpenBSD vax
- * unix/configure: autoconf-2.13
+2010-05-19 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
-2007-09-11 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclDictObj.c: Backport of fix for [Bug 3004007], EIAS
+ * tests/dict.test: violation in list-dict conversions.
- * library/tcltest/tcltest.tcl: Accept underscores and colons in
- * library/tcltest/pkgIndex.tcl: constraint names. Properly handle
- constraint expressions that return non-numeric boolean results like
- "false". Bump to tcltest 2.2.9. [Bug 1772989; RFE 1071322]
+2010-05-07 Andreas Kupries <andreask@activestate.com>
-2007-09-11 Pat Thoyts <patthoyts@users.sourceforge.net>
+ * library/platform/platform.tcl: Fix cpu name for Solaris/Intel 64bit.
+ * library/platform/pkgIndex.tcl: Package updated to version 1.0.8.
+ * unix/Makefile.in:
+ * win/Makefile.in:
- * win/makefile.vc: AMD64 target fixes for symbols builds.
- * win/rules.vc:
+2010-04-30 Don Porter <dgp@users.sourceforge.net>
-2007-09-10 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclBinary.c (UpdateStringOfByteArray): [Bug 2994924]: Add
+ panic when the generated string representation would grow beyond Tcl's
+ size limits.
- * generic/tclLink.c (Tcl_UpdateLinkedVar): guard against var being
- unlinked. [Bug 1740631] (maros)
+2010-04-29 Andreas Kupries <andreask@activestate.com>
-2007-08-25 Kevin Kenny <kennykb@acm.org>
+ * library/platform/platform.tcl: Another stab at getting the /lib,
+ * library/platform/pkgIndex.tcl: /lib64 difference right for linux.
+ * unix/Makefile.in: Package updated to version 1.0.7.
+ * win/Makefile.in:
- * generic/tclClock.c (FormatClock): Claimed additional space for
- the %c format code to avoid a buffer overrun when formatting
- (for example) a Friday in February in the Portuguese locale.
- [Bug 1751117]
+2010-04-29 Kevin B. Kenny <kennykb@acm.org>
+
+ * library/tzdata/Antarctica/Macquarie:
+ * library/tzdata/Africa/Casablanca:
+ * library/tzdata/Africa/Tunis:
+ * library/tzdata/America/Santiago:
+ * library/tzdata/America/Argentina/San_Luis:
+ * library/tzdata/Antarctica/Casey:
+ * library/tzdata/Antarctica/Davis:
+ * library/tzdata/Asia/Anadyr:
+ * library/tzdata/Asia/Damascus:
+ * library/tzdata/Asia/Dhaka:
+ * library/tzdata/Asia/Gaza:
+ * library/tzdata/Asia/Kamchatka:
+ * library/tzdata/Asia/Karachi:
+ * library/tzdata/Asia/Taipei:
+ * library/tzdata/Europe/Samara:
+ * library/tzdata/Pacific/Apia:
+ * library/tzdata/Pacific/Easter:
+ * library/tzdata/Pacific/Fiji: Olson's tzdata2010i.
-2007-08-24 Miguel Sofer <msofer@users.sf.net>
-
- * generic/tclCompile.c: replaced copy loop that tripped some
- compilers with memmove [Bug 1780870]
+2010-04-19 Jan Nijtmans <nijtmans@users.sf.net>
-2007-08-14 Don Porter <dgp@users.sourceforge.net>
+ * win/tclWinPort.h: [Patch 2986105]: Conditionally defining
+ * win/tclWinFile.c: strcasecmp/strncasecmp
- * tests/trace.test: Backport some tests.
-
-2007-08-14 Daniel Steffen <das@users.sourceforge.net>
+2010-04-18 Donal K. Fellows <dkf@users.sf.net>
- * unix/tclLoadDyld.c: use dlfcn API on Mac OS X 10.4 and later; fix
- issues with loading from memory on intel and 64bit; add debug messages.
+ * doc/unset.n: [Bug 2988940]: Fix typo.
- * tests/load.test: add test load-10.1 for loading from vfs.
+2010-04-14 Andreas Kupries <andreask@activestate.com>
-2007-08-07 Daniel Steffen <das@users.sourceforge.net>
+ * library/platform/platform.tcl: Linux platform identification:
+ * library/platform/pkgIndex.tcl: Check /lib64 for existence of
+ * unix/Makefile.in: files matching libc* before accepting it as
+ * win/Makefile.in: base directory. This can happen on weirdly
+ installed 32bit systems which have an empty or partially filled
+ /lib64 without an actual libc. Bumped to version 1.0.6.
- * generic/tclEnv.c: improve environ handling on Mac OS X (adapted
- * unix/tclUnixPort.h: from Apple changes in Darwin tcl-64).
+2010-04-03 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
- * unix/Makefile.in: add support for compile flags specific to
- object files linked directly into executables.
+ * generic/tclStringObj.c: (SetStringFromAny): avoid trampling
+ over the tclEmptyStringRep as it is thread-shared.
- * unix/configure.in (Darwin): only use -seg1addr flag when prebinding;
- use -mdynamic-no-pic flag for object files linked directly into exes;
- support overriding TCL_PACKAGE_PATH in environment.
+ * generic/tclThreadStorage.c (ThreadStorageGetHashTable):
+ avoid accessing shared table index w/o mutex protection
+ if VALGRIND defined on compilation time. This rules out
+ helgrind complains about potential race-conditions at
+ that place.
- * unix/configure: autoconf-2.13
+ Thanks to Gustaf Neumann for the (hard) work.
-2007-07-19 Don Porter <dgp@users.sourceforge.net>
+2010-03-31 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclParse.c: In contexts where interp and parsePtr->interp
- might be different, be sure to use the latter for error reporting.
+ * doc/package.n: [Bug 2980210]: Document the arguments taken by
+ the [package present] command correctly.
-2007-07-05 Don Porter <dgp@users.sourceforge.net>
+2010-03-30 Andreas Kupries <andreask@activestate.com>
- * library/init.tcl (unknown): Corrected inconsistent error message
- in interactive [unknown] when empty command is invoked. [Bug 1743676]
+ * generic/tclIORChan.c (ReflectClose, ReflectInput, ReflectOutput,
+ ReflectSeekWide, ReflectWatch, ReflectBlock, ReflectSetOption,
+ ReflectGetOption, ForwardProc): [Bug 2978773]: Preserve
+ ReflectedChannel* structures across handler invokations, to avoid
+ crashes when the handler implementation induces nested callbacks
+ and destruction of the channel deep inside such a nesting.
-2007-06-30 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+2010-03-30 Don Porter <dgp@users.sourceforge.net>
- * generic/tclBinary.c (Tcl_BinaryObjCmd): De-fang an instance of the
- shared-result anti-pattern. [Bug 1716704]
+ * generic/tclObj.c (Tcl_GetCommandFromObj): [Bug 2979402]: Reorder
+ the validity tests on internal rep of a "cmdName" value to avoid
+ invalid reads reported by valgrind.
-2007-06-30 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+2010-03-29 Don Porter <dgp@users.sourceforge.net>
- * generic/tclThread.c: Prevent RemeberSyncObj() from growing the sync
- object lists by reusing already free'd slots, if possible.
- See discussion on Bug 1726873 for more information.
+ * generic/tclStringObj.c: Fix array overrun in test format-1.12
+ caught by valgrind testing.
-2007-06-29 Daniel Steffen <das@users.sourceforge.net>
+2010-03-25 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclAlloc.c: on Darwin, ensure memory allocated by
- * generic/tclThreadAlloc.c: the custom TclpAlloc()s is aligned to
- 16 byte boundaries (as is the case with the Darwin system malloc).
+ * unix/tclUnixFCmd.c (TclUnixCopyFile): [Bug 2976504]: Corrected
+ number of arguments to fstatfs() call.
-2007-06-27 Don Porter <dgp@users.sourceforge.net>
+2010-03-24 Don Porter <dgp@users.sourceforge.net>
- * generic/tclCmdMZ.c: Corrected broken trace reversal logic in
- * generic/tclTest.c: TclCheckInterpTraces that led to infinite loop
- * tests/basic.test: when multiple Tcl_CreateTrace traces were set
- and one of them did not fire due to level restrictions. [Bug 1743941].
+ * generic/tclResult.c: [Bug 2383005]: Revise [return -errorcode] so
+ * tests/result.test: that it rejects illegal non-list values.
-2007-06-23 Daniel Steffen <das@users.sourceforge.net>
+2010-03-20 Donal K. Fellows <dkf@users.sf.net>
- * macosx/tclMacOSXNotify.c (AtForkChild): don't call CoreFoundation
- APIs after fork() on systems where that would lead to an abort().
+ * generic/tclIO.c (CopyData): Allow the total number of bytes copied
+ by [fcopy] to exceed 2GB. Can happen when no -size parameter given.
-2007-06-10 Jeff Hobbs <jeffh@ActiveState.com>
+2010-03-18 Don Porter <dgp@users.sourceforge.net>
- * README: updated links. [Bug 1715081]
+ * generic/tclListObj.c: [Bug 2971669]: Prevent in overflow trouble in
+ * generic/tclTestObj.c: ListObjReplace operations. Thanks to kbk for
+ * tests/listObj.test: fix and test.
-2007-06-06 Daniel Steffen <das@users.sourceforge.net>
+2010-03-12 Jan Nijtmans <nijtmans@users.sf.net>
- * unix/configure.in (Darwin): add plist for tclsh; link the
- * unix/Makefile.in (Darwin): Tcl and tclsh plists into their
- * macosx/Tclsh-Info.plist.in (new): binaries in all cases.
+ * win/makefile.vc: Fix [Bug 2967340]: Static build failure
+ * win/.cvsignore
- * unix/tcl.m4 (Darwin): fix CF checks in fat 32&64bit builds.
- * unix/configure: autoconf-2.13
+2010-03-09 Andreas Kupries <andreask@activestate.com>
-2007-06-05 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclIORChan.c: [Bug 2936225]: Thanks to Alexandre Ferrieux
+ * doc/refchan.n: <ferrieux@users.sourceforge.net> for debugging
+ * tests/ioCmd.test: and fixing the problem. It is the write-side
+ equivalent to the bug fixed 2009-08-06.
- * tests/result.test (result-6.2): Add test for [Bug 1649062] so that
- 8.4 and 8.5 both test the same outcome and we verify compatibility.
+2010-03-09 Don Porter <dgp@users.sourceforge.net>
-2007-05-30 Don Porter <dgp@users.sourceforge.net>
+ * library/tzdata/America/Matamoros: New locale
+ * library/tzdata/America/Ojinaga: New locale
+ * library/tzdata/America/Santa_Isabel: New locale
+ * library/tzdata/America/Asuncion:
+ * library/tzdata/America/Tijuana:
+ * library/tzdata/Antarctica/Casey:
+ * library/tzdata/Antarctica/Davis:
+ * library/tzdata/Antarctica/Mawson:
+ * library/tzdata/Asia/Dhaka:
+ * library/tzdata/Pacific/Fiji:
+ Olson tzdata2010c.
- * README: Bump version number to 8.4.16
- * generic/tcl.h:
- * tools/tcl.wse.in:
- * unix/configure.in:
- * unix/tcl.spec:
- * win/README.binary:
- * win/configure.in:
+2010-03-01 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
- * unix/configure: autoconf-2.13
- * win/configure:
+ * unix/tclUnixChan.c: [backported] Refrain from a possibly lengthy
+ reverse-DNS lookup on 0.0.0.0 when calling [fconfigure -sockname]
+ on an universally-bound (default) server socket.
-2007-05-29 Jeff Hobbs <jeffh@ActiveState.com>
+2010-02-27 Donal K. Fellows <dkf@users.sf.net>
- * unix/tclUnixThrd.c (Tcl_JoinThread): fix for 64-bit handling of
- pthread_join exit return code storage. [Bug 1712723]
+ * generic/tclCmdMZ.c (StringFirstCmd, StringLastCmd): [Bug 2960021]:
+ Only search for the needle in the haystack when the needle isn't
+ larger than the haystack. Prevents an odd crash from sometimes
+ happening when things get mixed up (a common programming error).
-2007-05-24 Don Porter <dgp@users.sourceforge.net>
+2010-02-21 Jan Nijtmans <nijtmans@users.sf.net>
- *** 8.4.15 TAGGED FOR RELEASE ***
+ * generic/tclBasic.c: Fix [Bug 2954959] expr abs(0.0) is -0.0
+ * tests/expr.test
- * generic/tclIO.c: Backport memleak fix in TclFinalizeIOSubsystem.
+2010-02-19 Stuart Cassoff <stwo@users.sourceforge.net>
-2007-05-17 Don Porter <dgp@users.sourceforge.net>
+ * tcl.m4: Correct compiler/linker flags for threaded builds on OpenBSD
+ * configure: (regenerated).
- * tests/fCmd.test: Backport the notNetworkFilesystem constraint.
+2010-02-19 Donal K. Fellows <dkf@users.sf.net>
-2007-05-15 Don Porter <dgp@users.sourceforge.net>
+ * unix/installManPage: [Bug 2954638]: Correct behaviour of manual page
+ installer. Also added armouring to check that assumptions about the
+ initial state are actually valid (e.g., look for existing input file).
- * generic/tclNamesp.c: Plugged memory leak related to
- [namespace delete ::]. [Bug 1716782]
+2010-02-11 Donal K. Fellows <dkf@users.sf.net>
- * changes: updates for 8.4.15 release.
+ * generic/tclIOCmd.c (Tcl_OpenObjCmd): [Bug 2949740]: Make sure that
+ we do not try to put a NULL pipeline channel into binary mode.
- * win/tclWinReg.c: Bump to registry 1.1.5 to account
- * library/reg/pkgIndex.tcl: for [Bug 1682211] fix.
+2010-02-07 Jan Nijtmans <nijtmans@users.sf.net>
-2007-05-10 Don Porter <dgp@users.sourceforge.net>
+ * tools/genStubs.tcl Backport various formatting (spacing)
+ * generic/tcl*.decls changes from HEAD, so diffing
+ * generic/tcl*Decls.h between 8.5.x and 8.6 shows the
+ * generic/tclStubInit.c real structural differences again.
+ (any signature change not backported!)
- * generic/tclInt.h: TclFinalizeThreadAlloc() is always defined,
- so make sure it is also always declared.
+2010-02-03 Donal K. Fellows <dkf@users.sf.net>
- [Tcl Bug 1706140]
+ * generic/tclVar.c (Tcl_ArrayObjCmd): More corrections for the 'unset'
+ subcommand.
- * generic/tclCmdMZ.c (Trace*Proc): Update Tcl_VarTraceProcs so
- * generic/tclLink.c (LinkTraceProc): that they call
- * generic/tclUtil.c (TclPrecTraceProc): Tcl_InterpDeleted() for
- themselves, and do not rely on (frequently buggy) setting of the
- TCL_INTERP_DESTROYED flag by the trace core.
+2010-02-02 Andreas Kupries <andreask@activestate.com>
- * generic/tclVar.c: Update callers of CallVarTraces to not
- pass in the TCL_INTERP_DESTROYED flag. Also apply filters so that
- public routines only pass documented flag values down to lower level
- routines.
+ * generic/tclCompile.c: [Bug 2933089]: A literal sharing problem with
+ * generic/tclCompile.h: 'info frame' affects not only 8.6 but 8.5 as
+ * generic/tclExecute.h: well. Backported the fix done in 8.6, without
+ * tests/info.test: changes. New testcase info-39.1.
- * generic/tclVar.c (CallVarTraces): The setting of the
- TCL_INTERP_DESTROYED flag is now done entirely within the
- CallVarTraces routine, the only place it can be done right.
+2010-02-02 Donal K. Fellows <dkf@users.sf.net>
-2007-04-30 Daniel Steffen <das@users.sourceforge.net>
+ * generic/tclVar.c (Tcl_ArrayObjCmd): [Bug 2939073]: Stop the [array
+ unset] command from having dangling pointer problems when an unset
+ trace deletes the element that is going to be processed next. Many
+ thanks to Alexandre Ferrieux for the bulk of this fix.
- * unix/Makefile.in: add 'tclsh' dependency to install targets that rely
- on tclsh, fixes parallel 'make install' from empty build dir.
+2010-02-01 Donal K. Fellows <dkf@users.sf.net>
-2007-04-29 Daniel Steffen <das@users.sourceforge.net>
+ * generic/regexec.c (ccondissect, crevdissect): [Bug 2942697]: Rework
+ these functions so that certain pathological patterns are matched much
+ more rapidly. Many thanks to Tom Lane for dianosing this issue and
+ providing an initial patch.
- * unix/tclUnixFCmd.c: add workaround for crashing bug in fts_open()
- * unix/tclUnixInit.c: without FTS_NOSTAT on 64bit Darwin 8 or earlier.
+2010-02-01 Jan Nijtmans <nijtmans@users.sf.net>
- * unix/tclLoadDyld.c (TclpLoadMemory): fix (void*) arithmetic.
+ * generic/tclInt.decls: Various CYGWIN-related fixes
+ * generic/tclInt.h: backported from HEAD. Still
+ * generic/tclIntPlatDecls.h: configure script not modified,
+ * generic/tclPort.h: so CYGWIN build is still
+ * generic/tclTest.c: disabled. Reason: although the
+ * win/cat.c: build succeeds with those changes,
+ * win/tclWinDde.c: many tests still fail.
+ * win/tclWinError.c:
+ * win/tclWinFile.c:
+ * win/tclWinPipe.c:
+ * win/tclWinPort.h:
+ * win/tclWinReg.c:
+ * win/tclWinSerial.c:
+ * win/tclWinSock.c:
+ * win/tclWinTest.c:
+ * win/tclWinThrd.c:
- * macosx/tclMacOSXNotify.c: fix warnings.
+2010-01-29 Jan Nijtmans <nijtmans@users.sf.net>
- * macosx/README: sync whitespace/formatting with HEAD.
- * macosx/tclMacOSXBundle.c:
- * macosx/tclMacOSXNotify.c:
- * unix/tclLoadDyld.c:
+ * generic/tcl.h: Use correct TCL_LL_MODIFIER for CYGWIN.
+ Formatting (all backported from HEAD)
+ * generic/rege_dfa.c: Fix macro conflict on CYGWIN: don't use
+ "small".
+ * generic/tclTest.c: Fix gcc 4.4 warning: ignoring return value of
+ * unix/tclUnixPipe.c: 'write'
+ * unix/tclUnixNotify.c:
- * macosx/Makefile: fix/add copyright and license refs.
- * macosx/tclMacOSXBundle.c:
- * macosx/Tcl-Info.plist.in:
+2010-01-19 Donal K. Fellows <dkf@users.sf.net>
- * unix/Makefile.in (dist): copy license.terms to dist macosx dir.
- * unix/configure.in: install license.terms into Tcl.framework.
- * unix/configure: autoconf-2.13
-
-2007-04-21 Kevin B. Kenny <kennyb@acm.org>
-
- * generic/tclClock.c: Restored Cygwin buildability [Bug 1387154]
- * generic/tclInt.decls: Yet another round of attempting
- * generic/tclInt.h: to get the correct type signature
- * unix/tclUnixPort.h: for TclpLocaltime and TclpGmtime.
- * unix/tclUnixTime.c: CONST TclpTime_t is a 'time_t *CONST'
- * win/tclWinTime.c: and not a 'CONST time_t*' [Bug 1677275]
- * generic/tclIntDecls.h:
- * generic/tclIntPlatDecls.h: Regenerated.
-
-2007-03-24 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+ * doc/dict.n: [Bug 2929546]: Clarify just what [dict with] and [dict
+ update] are doing with variables.
- * win/tclWinThrd.c: Thread exit handler marks the current
- thread as un-initialized. This allows exit handlers that
- are registered later to re-initialize this subsystem in
- case they need to use some sync primitives (cond variables)
- from this file again.
+2010-01-18 Andreas Kupries <andreask@activestate.com>
-2007-03-19 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclIO.c (CreateScriptRecord): [Bug 2918110]: Initialize
+ the EventScriptRecord (esPtr) fully before handing it to
+ Tcl_CreateChannelHandler for registration. Otherwise a reflected
+ channel calling 'chan postevent' (== Tcl_NotifyChannel) in its
+ 'watchProc' will cause the function 'TclChannelEventScriptInvoker'
+ to be run on an uninitialized structure.
- * generic/tclEvent.c (Tcl_CreateThread): Replaced some calls to
- * generic/tclPkg.c (CheckVersion): Tcl_Alloc() with calls to
- * unix/tclUnixTime.c (SetTZIfNecessary): ckalloc(), which better
- * win/tclAppInit.c (setargv): supports memory debugging.
+2010-01-18 Donal K. Fellows <dkf@users.sf.net>
-2007-03-17 Kevin Kenny <kennykb@acm.org>
-
- * win/tclWinReg.c (GetKeyNames): Size the buffer for enumerating
- key names correctly, so that Unicode names exceeding 127 chars
- can be retrieved without crashing. [Bug 1682211]
- * tests/registry.test (registry-4.9): Added test case for the
- above bug.
+ * generic/tclStringObj.c (Tcl_AppendFormatToObj): [Bug 2932421]: Stop
+ the [format] command from causing argument objects to change their
+ internal representation when not needed. Thanks to Alexandre Ferrieux
+ for this fix.
-2007-03-13 Don Porter <dgp@users.sourceforge.net>
+2010-01-06 Jan Nijtmans <nijtmans@users.sf.net>
- * generic/tclExecute.c (INST_FOREACH_STEP4): Re-fetch pointers for
- * tests/foreach.test (foreach-10.1): the value list each iteration
- of the loop as defense against shimmers. [Bug 1671087]
+ * generic/tclCompExpr.c: Warning: array subscript has type 'char'
+ * generic/tclPkg.c:
+ * libtommath/bn_mp_read_radix.c:
+ * unix/tclUnixCompat.c: Fix gcc warning: signed and unsigned type
+ in conditional expression.
+ * unix/tcl.m4: Add support for Haiku and CYGWIN dynamical loading
+ * unix/configure: (regenerated)
+ * unix/Makefile.in:
+ * unix/.cvsignore:
+ * tests/stack.test: Reduced minimum required C-stack size to 2034:
+ CYGWIN has this stack size and the test runs fine!
+ * generic/tclEnv.c: Fix environment tests under CYGWIN
+ * generic/tclPort.h:
+ * tests/env.test:
- * generic/tclVar.c (TclArraySet): Re-fetch pointers for the list
- * tests/var.test (var-17.1): argument of [array set] each time
- through the loop as defense against possible shimmer issues.
- [Bug 1669489].
+2010-01-05 Don Porter <dgp@users.sourceforge.net>
-2007-03-10 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * generic/tclPathObj.c (TclPathPart): [Bug 2918610]: Correct
+ * tests/fileName.test (filename-14.31): inconsistency between the
+ string rep and the intrep of a path value created by [file rootname].
+ Thanks to Vitaly Magerya for reporting.
- * generic/tclCmdIL.c (Tcl_LsortObjCmd): Handle tricky case with loss
- * tests/cmdIL.test (cmdIL-1.29):of list rep during sorting due
- to shimmering. [Bug 1675116]
+2010-01-03 Donal K. Fellows <dkf@users.sf.net>
-2007-03-07 Daniel Steffen <das@users.sourceforge.net>
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): [Bug 1636685]: Use the configuration
+ for modern FreeBSD suggested by the FreeBSD porter.
- * macosx/tclMacOSXNotify.c: add spinlock debugging and sanity checks.
+2009-12-30 Donal K. Fellows <dkf@users.sf.net>
- * unix/tcl.m4 (Darwin): s/CFLAGS/CPPFLAGS/ in macosx-version-min check.
- * unix/configure: autoconf-2.13
+ * library/safe.tcl (AliasSource): [Bug 2923613]: Make the safer
+ * tests/safe.test (safe-8.9): [source] handle a [return] at the
+ end of the file correctly.
-2007-03-01 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+2009-12-29 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclCompCmds.c (TclCompileForeachCmd): Prevent an unexpected
- * tests/foreach.test (foreach-9.1): infinite loop when the
- variable list is empty and the foreach is compiled. [Bug 1671138]
+ * generic/tclInterp.c (Tcl_MakeSafe): [Bug 2895741]: Make sure that
+ the min() and max() functions are supported in safe interpreters.
-2007-02-22 Andreas Kupries <andreask@activestate.com>
+2009-12-28 Donal K. Fellows <dkf@users.sf.net>
- * tests/pkg.test: Added tests for the case of an alpha package
- satisfying a require for the regular package, demonstrating a
- corner case specified in TIP#280. More notes in the comments to
- the test.
+ * unix/configure.in: [Bug 942170]: Detect the st_blocks field of
+ * generic/tclCmdAH.c (StoreStatData): 'struct stat' correctly.
+ * generic/tclIOUtil.c (Tcl_Stat, Tcl_FSStat):
+ * generic/tclTest.c (PretendTclpStat):
-2007-02-20 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclInterp.c (TimeLimitCallback): [Bug 2891362]: Ensure that
+ * tests/interp.test (interp-34.13): the granularity ticker is
+ reset when we check limits because of the time limit event firing.
- * doc/tcltest.n: Typo fix. [Bug 1663539]
+2009-12-27 Donal K. Fellows <dkf@users.sf.net>
-2007-02-19 Jeff Hobbs <jeffh@ActiveState.com>
+ * doc/namespace.n (SCOPED SCRIPTS): [Bug 2921538]: Updated example to
+ not be quite so ancient.
- * generic/tclIOUtil.c (Tcl_FSEvalFile): safe incr of objPtr ref.
+2009-12-23 Donal K. Fellows <dkf@users.sf.net>
- * unix/tcl.m4: use SHLIB_SUFFIX=".so" on HP-UX ia64 arch.
- * unix/configure: autoconf-2.13
+ * library/safe.tcl (AliasSource, AliasExeName): [Bug 2913625]: Stop
+ information about paths from leaking through [info script] and [info
+ nameofexecutable].
-2007-02-12 Andreas Kupries <andreask@activestate.com>
+2009-12-16 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclEncoding.c (EscapeFromUtfProc): Applied patch
- supplied by Mo DeJong to fix [Bug 1516109]. Backport from Tcl
- 8.5. Mo's description: Clear the TCL_ENCODING_END flag when end
- bytes are written. This fix keep this method from writing escape
- bytes for an encoding like iso2022-jp multiple times when the
- escape byte overlap with the end of the IO buffer.
- * tests/io.test: Add test case for escape byte overlap case.
+ * library/safe.tcl (::safe::AliasGlob): Upgrade to correctly support a
+ larger fraction of [glob] functionality, while being stricter about
+ directory management.
-2007-02-04 Daniel Steffen <das@users.sourceforge.net>
+ * doc/tm.n: [Bug 1911342]: Formatting rewrite to avoid bogus crosslink
+ to the list manpage when generating HTML.
- * unix/configure.in: add caching to -pipe check.
- * unix/configure: autoconf-2.13
+ * library/msgcat/msgcat.tcl (Init): [Bug 2913616]: Do not use platform
+ tests that are not needed and which don't work in safe interpreters.
-2007-01-30 Jeff Hobbs <jeffh@ActiveState.com>
+2009-12-12 Donal K. Fellows <dkf@users.sf.net>
- * win/Makefile.in (install-private-headers): added target
+ * generic/tclTest.c (TestconcatobjCmd): [Bug 2895367]: Stop memory
+ leak when testing. We don't need extra noise of this sort when
+ tracking down real problems!
-2007-01-29 Don Porter <dgp@users.sourceforge.net>
+2009-12-10 Andreas Kupries <andreask@activestate.com>
- * doc/fcopy.n: Typo fix. [Bug 1630627]
+ * generic/tclObj.c (TclContinuationsEnter): [Bug 2895323]: Updated
+ comments to describe when the function can be entered for the same
+ Tcl_Obj* multiple times. This is a continuation of the 2009-11-10
+ entry where a memory leak was plugged, but where not sure if that was
+ just a band-aid to paper over some other error. It isn't, this is a
+ legal situation.
-2007-01-25 Daniel Steffen <das@users.sourceforge.net>
+2009-12-09 Andreas Kupries <andreask@activestate.com>
- * unix/tcl.m4: integrate CPPFLAGS into CFLAGS as late as possible
- * unix/configure.in: and move (rather than duplicate) -isysroot flags
- from CFLAGS to CPPFLAGS to avoid errors about multiple -isysroot flags
- from some older gcc builds.
+ * library/safe.tcl: Backport of the streamlined safe base from
+ * tests/safe.test: head to the 8.5 branch (See head changelog entries
+ 2009-11-05, 2009-11-06, 2009-12-03).
- * unix/configure: autoconf-2.13
+2009-12-07 Don Porter <dgp@users.sourceforge.net>
-2007-01-22 Andreas Kupries <andreask@activestate.com>
+ * generic/tclStrToD.c: [Bug 2902010]: Correct conditional compile
+ directives to better detect the toolchain that needs extra work for
+ proper underflow treatment instead of merely detecting the MIPS
+ platform.
- * compat/memcmp.c (memcmp): Fixed the VOID / CONST typo introduced
- by the last checkin.
+2009-12-02 Jan Nijtmans <nijtmans@users.sf.net>
-2007-01-22 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * tools/genStubs.tcl: Add support for win32 CALLBACK functions (needed
+ for Tk bugfix).
- * compat/memcmp.c (memcmp): Reworked so that arithmetic is never
- performed upon void pointers, since that is illegal. [Bug 1631017]
+2009-11-30 Donal K. Fellows <dkf@users.sf.net>
-2006-01-19 Daniel Steffen <das@users.sourceforge.net>
+ * doc/Tcl.n: [Bug 2901433]: Improved description of expansion to
+ mention that it is using list syntax.
- * macosx/tclMacOSXNotify.c: accommodate changes to prototypes of
- OSSpinLock(Un)Lock API.
-
- * tests/env.test: add extra system env vars that need to be preserved
- on some Mac OS X versions for testsuite to work.
+2009-11-27 Donal K. Fellows <dkf@users.sf.net>
- * unix/tcl.m4: ensure CPPFLAGS env var is used when set. [Bug 1586861]
- (Darwin): add -isysroot and -mmacosx-version-min flags to CPPFLAGS when
- present in CFLAGS to avoid discrepancies between what headers configure
- sees during preprocessing tests and compiling tests.
+ * doc/BoolObj.3, doc/CrtChannel.3, doc/DictObj.3, doc/DoubleObj.3:
+ * doc/Ensemble.3, doc/Environment.3, doc/FileSystem.3, doc/Hash.3:
+ * doc/IntObj.3, doc/Limit.3, doc/ObjectType.3, doc/PkgRequire.3:
+ * doc/SetChanErr.3, doc/SetResult.3: [Patch 2903921]: Many small
+ spelling fixes from Larry Virden.
- * unix/configure: autoconf-2.13
+2009-11-25 Stuart Cassoff <stwo@users.sf.net>
-2006-12-19 Daniel Steffen <das@users.sourceforge.net>
+ * unix/configure.in: [Patch 2892871]: Remove unneeded
+ * unix/tcl.m4: AC_STRUCT_TIMEZONE and use
+ * unix/tclConfig.h.in: AC_CHECK_MEMBERS([struct stat.st_blksize])
+ * unix/tclUnixFCmd.c: instead of AC_STRUCT_ST_BLKSIZE.
+ * unix/configure: Regenerated with autoconf-2.59.
- * unix/tclUnixThrd.c (TclpInetNtoa): fix for 64 bit.
+2009-11-16 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
- * unix/tcl.m4 (Darwin): --enable-64bit: verify linking with 64bit -arch
- flag succeeds before enabling 64bit build.
- * unix/configure: autoconf-2.13
+ * generic/tclEncoding.c: Fix [Bug 2891556] and improve test to detect
+ * tests/decoding.test: similar manifestations in the future.
+
+2009-11-12 Don Porter <dgp@users.sourceforge.net>
-2006-12-14 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ *** 8.5.8 TAGGED FOR RELEASE ***
- * doc/string.n: Fix example. [Bug 1615277]
+ * changes: Update for 8.5.8 release.
-2006-12-05 Andreas Kupries <andreask@activestate.com>
+ * generic/tclClock.c (TclClockInit): Do not create [clock] support
+ commands in safe interps.
- * tests/pkg.test: Backport to 8.4 (Don Porter's work):
- * generic/tclPkg.c: When no requirements are supplied to a [package
- require $pkg] and [package unknown] is invoked to find a satisfying
- package, pass the requirement argument "0-" (which means all versions
- are acceptable). This permits a registered [package unknown] command
- to call [package vsatisfies $testVersion {*}$args] without any special
- handling of the empty $args case. This fixes/avoids a bug in
- [::tcl::tm::UnknownHandler] that was causing old TM versions to be
- provided in preference to newer TM versions. Thanks to Julian Noble
- for discovering the issue.
+ * tests/io.test: New test io-53.11 to test for [Bug 2895565].
-2006-12-04 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+2009-11-12 Andreas Kupries <andreask@activestate.com>
- * doc/file.n: Fix confusing wording for [file pathtype]. [Bug 1606454]
+ * generic/tclIO.c (CopyData): [Bug 2895565]: Dropped bogosity which
+ used the number of _written_ bytes or character to update the counters
+ for the read bytes/characters. See last entry for the test case.
-2006-11-28 Andreas Kupries <andreask@activestate.com>
+2009-11-11 Pat Thoyts <patthoyts@users.sourceforge.net>
- * generic/tclBasic.c: TIP #280 implementation, conditional on the
- * generic/tclCmdAH.c: define TCL_TIP280.
- * generic/tclCmdIL.c:
- * generic/tclCmdMZ.c:
- * generic/tclCompCmds.c:
- * generic/tclCompExpr.c:
- * generic/tclCompile.c:
- * generic/tclCompile.h:
- * generic/tclExecute.c:
- * generic/tclIOUtil.c:
- * generic/tclInt.h:
- * generic/tclInterp.c:
- * generic/tclNamesp.c:
- * generic/tclObj.c:
- * generic/tclProc.c:
- * tests/compile.test:
- * tests/info.test:
- * tests/platform.test:
- * tests/safe.test:
+ * tests/fCmd.test: Fixed a number of issues for Vista and Win7
+ * tests/registry.test: that are due to restricted permissions.
+ * tests/winFCmd.test:
-2006-11-27 Kevin Kenny <kennykb@acm.org>
+2009-11-11 Don Porter <dgp@users.sourceforge.net>
- * unix/tclUnixChan.c (TclUnixWaitForFile):
- * tests/event.test (event-14.*): Corrected a bug where
- TclUnixWaitForFile would present select() with the wrong mask on an
- LP64 machine if a fd number exceeds 32. Thanks to Jean-Luc Fontaine
- for reporting and diagnosing [Bug 1602208]
+ * library/http/http.tcl: [Bug 2891171]: Update the URL syntax
+ check to RFC 3986 compliance on the subject of non-encoded question
+ mark characters.
-2006-11-26 Daniel Steffen <das@users.sourceforge.net>
+ * library/http/pkgIndex.tcl: Bump to http 2.7.5 to avoid any
+ * unix/Makefile.in: confusion with snapshot "releases"
+ * win/Makefile.in: that might be in ActiveTcl, etc.
- * unix/tcl.m4 (Linux): --enable-64bit support. [Patch 1597389]
- * unix/configure: autoconf-2.13 [Bug 1230558]
+2009-11-11 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
-2006-11-07 Andreas Kupries <andreask@activestate.com>
+ * generic/tclIO.c: Backported fix for [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.
- * unix/tclUnixFCmd.c (CopyFile): Added code to fall back to a
- hardwired default block size should the filesystem report a bogus
- value. [Bug 1586470]
+2009-11-10 Don Porter <dgp@users.sourceforge.net>
-2006-11-03 Miguel Sofer <msofer@users.sf.net>
+ * generic/tclBasic.c: Plug another leak in TCL_EVAL_DIRECT
+ evaluation.
- * generic/tclBasic.c (TEOVI): fix for possible leak of a Command in
- the presence of execution traces that delete it.
+ * generic/tclObj.c: Plug memory leak in TclContinuationsEnter().
+ [Bug 2895323]
- * generic/tclBasic.c (TEOVI):
- * tests/trace.test (trace-21.11): fix for [Bug 1590232], execution
- traces may cause a second command resolution in the wrong
- namespace.
+2009-11-09 Stuart Cassoff <stwo@users.sf.net>
-2006-11-01 Daniel Steffen <das@users.sourceforge.net>
+ * win/README: [bug 2459744]: Removed outdated Msys + Mingw info.
- * generic/tclEnv.c (Darwin): mark _environ symbol as unexported.
+2009-11-09 Don Porter <dgp@users.sourceforge.net>
-2006-10-31 Pat Thoyts <patthoyts@users.sourceforge.net>
+ * generic/tclBasic.c (TclEvalObjEx): Plug memory leak in
+ TCL_EVAL_DIRECT evaluation.
- * rules.vc: Fix [Bug 1582769] build with VC2003 and correct i386 arch
+ * tests/info.test: Resolve ambiguous resolution of variable "res".
-2006-10-23 Don Porter <dgp@users.sourceforge.net>
+2009-11-03 Don Porter <dgp@users.sourceforge.net>
- * README: Bump version number to 8.4.15
- * generic/tcl.h:
+ * generic/tcl.h: Bump to 8.5.8 for release.
+ * library/init.tcl:
* tools/tcl.wse.in:
* unix/configure.in:
* unix/tcl.spec:
- * win/README.binary:
* win/configure.in:
+ * README:
- * unix/configure: autoconf-2.13
+ * unix/configure: autoconf-2.59
* win/configure:
-2006-10-18 Pat Thoyts <patthoyts@users.sourceforge.net>
+ * changes: Update for 8.5.8 release.
- *** 8.4.14 TAGGED FOR RELEASE ***
+2009-11-03 Andreas Kupries <andreask@activestate.com>
- * win/nmakehlp.c: Ensure builds with VC6 without Platform SDK.
- * win/rules.vc: Pickup MACHINE from environment.
+ * library/safe.tcl (::safe::InterpSetConfig): [Bug 2854929]: Added
+ code to recursively find deeper paths which may contain modules.
+ Required to handle modules with names like 'platform::shell', which
+ translate into 'platform/shell-X.tm', i.e arbitrarily deep
+ subdirectories.
-2006-10-17 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclIOUtil.c: Cleaned up some code flagged by a
- * generic/tclInt.h: `make checkexports` test.
- * win/tclWin32Dll.c:
- * win/tclWinFile.c:
+2009-11-03 Kevin B. Kenny <kennykb@acm.org>
-2006-10-16 Daniel Steffen <das@users.sourceforge.net>
-
- * changes: updates for 8.4.14 release.
-
- * macosx/Makefile: don't redo prebinding of non-prebound binaires.
-
-2006-10-11 Andreas Kupries <andreask@activestate.com>
-
- * generic/tclPkg.c (Tcl_PkgRequireEx): Corrected crash when argument
- version==NULL passed in. Backport of the fix for the same problem in
- 8.5.
+ * library/tzdata/Asia/Novokuznetsk: New tzdata locale for Kemerovo
+ oblast', which now keeps Novosibirsk time and not Kranoyarsk time.
+ * library/tzdata/Asia/Damascus: Syrian DST changes.
+ * library/tzdata/Asia/Hong_Kong: Hong Kong historic DST corrections.
+ Olson tzdata2009q.
-2006-10-10 Don Porter <dgp@users.sourceforge.net>
+2009-11-03 Pat Thoyts <patthoyts@users.sourceforge.net>
- * changes: changes updated for 8.4.14 release.
+ * tests/tcltest.test: Backport permissions fix for Win7.
-2006-10-06 Jeff Hobbs <jeffh@ActiveState.com>
+2009-10-31 Donal K. Fellows <dkf@users.sf.net>
- * tests/http.test: update tests to handle strictness change.
+ * generic/tclBasic.c (ExprRoundFunc): [Bug 2889593]: Correctly report
+ the expected number of arguments when generating an error for round().
-2006-10-06 Pat Thoyts <patthoyts@users.sourceforge.net>
+2009-10-29 Don Porter <dgp@users.sourceforge.net>
- * win/rules.vc: avoid /RTCc flag with MSVC8. [Bug 1571954]
+ * generic/tcl.h: [Bug 2800740]: Changed the typedef for the
+ mp_digit type from:
+ typedef unsigned long mp_digit;
+ to:
+ typedef unsigned int mp_digit;
+ 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.
-2006-10-05 Jeff Hobbs <jeffh@ActiveState.com>
-
- * library/http/http.tcl (http::geturl): only do geturl url rfc 3986
- validity checking if $::http::strict is true (default false for 8.4).
- [Bug 1560506]
-
- * generic/tcl.h: note limitation on changing Tcl_UniChar size
- * generic/tclEncoding.c (UtfToUnicodeProc, UnicodeToUtfProc):
- * tests/encoding.test (encoding-16.1): fix alignment issues in
- unicode <> utf conversion procs. [Bug 1122671]
-
-2006-10-05 Miguel Sofer <msofer@users.sf.net>
-
- * generic/tclVar.c (Tcl_LappendObjCmd):
- * tests/append.test(4.21-22): fix for longstanding [Bug 1570718],
- lappending nothing to non-list. Reported by lvirden
-
-2006-10-02 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclFileName.c (TclGlob): Prevent doubling of directory
- separators by [glob]. [Bug 1569042]
-
-2006-10-01 Pat Thoyts <patthoyts@users.sourceforge.net>
-
- * win/tclWinFile.c: Handle possible missing define.
- * win/tclWinFile.c: Backported fix for [Bug 1420432] (cannot set
- * tests/cmdAH.test: mtime for directories on windows).
+ ***POTENTIAL INCOMPATIBILITY***
+ For 64-bit builds, callers of routines with (mp_digit) or (mp_digit *)
+ arguments *will*, and callers of routines with (mp_int *) arguments
+ *may* suffer both binary and stubs incompatibilities with Tcl releases
+ 8.5.0 - 8.5.7. Such possibilities should be checked, and if such
+ incompatibilities are present, suitable [package require] requirements
+ on the Tcl release should be put in place to keep such built code
+ [load]-ing only in Tcl interps that are compatible.
+
+2009-10-29 Kevin B. Kenny <kennykb@acm.org>
+
+ * library/clock.tcl (LocalizeFormat):
+ * tests/clock.test (clock-67.1): [Bug 2819334]:
+ Corrected a problem where '%%' followed by a letter in a format group
+ could expand recursively: %%R would turn into %%H:%M:%S.
+
+2009-10-28 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclLiteral.c: Backport fix for [Bug 2888044].
+
+2009-10-28 Kevin B. Kenny <kennykb@acm.org>
+
+ * tests/fileName.test (fileName-20.[78]): Corrected poor test
+ hygiene (failure to save and restore the working directory) that
+ caused these two tests to fail on Windows (and [Bug 2806250] to be
+ reopened).
+
+2009-10-27 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclPathObj.c: [Bug 2884203]: Missing refcount on cached
+ normalized path caused crashes.
+
+2009-10-27 Kevin B. Kenny <kennykb@acm.org>
+
+ * library/clock.tcl (ParseClockScanFormat): [Bug 2886852]:
+ Corrected a problem where [clock scan] didn't load the timezone soon
+ enough when processing a time format that lacked a complete date.
+ * tests/clock.test (clock-66.1):
+ Added a test case for the above bug.
+ * library/tzdata/America/Argentina/Buenos_Aires:
+ * library/tzdata/America/Argentina/Cordoba:
+ * library/tzdata/America/Argentina/San_Luis:
+ * library/tzdata/America/Argentina/Tucuman:
+ New DST rules for Argentina. (Olson's tzdata2009p.)
+
+2009-10-24 Kevin B. Kenny <kennykb@acm.org>
+
+ * library/clock.tcl (ProcessPosixTimeZone):
+ Corrected a regression in the fix to [Bug 2207436] that caused [clock]
+ to apply EU daylight saving time rules in the US. Thanks to Karl
+ Lehenbauer for reporting this regression.
+ * tests/clock.test (clock-52.4):
+ Added a regression test for the above regression.
+ * library/tzdata/Asia/Dhaka:
+ * library/tzdata/Asia/Karachi:
+ New DST rules for Bangladesh and Pakistan. (Olson's tzdata2009o.)
-2006-09-30 Miguel Sofer <msofer@users.sf.net>
+2009-10-23 Andreas Kupries <andreask@activestate.com>
- * generic/tclUtil.c (Tcl_SplitList): optimisation, [Patch 1344747]
- by dgp.
+ * generic/tclIO.c (FlushChannel): Skip OutputProc for low-level
+ 0-length writes. When closing pipes which have already been closed not
+ skipping leads to spurious SIG_PIPE signals. Reported by Mikhail
+ Teterin <mi+thun@aldan.algebra.com>.
-2006-09-26 Pat Thoyts <patthoyts@users.sourceforge.net>
+2009-10-21 Donal K. Fellows <dkf@users.sf.net>
- * win/makefile.vc: Updated MSVC build to properly deal with
- * win/nmakehlp.c: MSVC8 and AMD64 target. Backport from 8.5
- * win/rules.vc:
- * generic/tcl.h: Fixed stat definition for MSVC8 AMD64.
- * win/tclWinSock.c: Casting type police.
- * win/tclWinTime.c:
+ * generic/tclPosixStr.c: [Bug 2882561]: Work around oddity on Haiku OS
+ where SIGSEGV and SIGBUS are the same value.
-2006-09-26 Don Porter <dgp@users.sourceforge.net>
+2009-10-19 Don Porter <dgp@users.sourceforge.net>
- * generic/tcl.h: As 2006-09-22 commit from Donal K. Fellows
- demonstrates, "#define NULL 0" is just wrong, and as a quotable chat
- figure observed, "If NULL isn't defined, we're not using a C compiler."
- Improper fallback definition of NULL removed.
+ * generic/tclIO.c: Revised ReadChars and FilterInputBytes
+ routines to permit reads to continue up to the string limits of Tcl
+ values. Before revisions, large read attempts could panic when as
+ little as half the limiting value length was reached. [Patch 2107634]
+ Thanks to Sean Morrison and Bob Parker for their roles in the fix.
-2006-09-25 Andreas Kupries <andreask@activestate.com>
+2009-10-18 Joe Mistachkin <joe@mistachkin.com>
- * generic/tclIO.c (Tcl_StackChannel): Fixed [SF Tcl Bug 1564642], aka
- coverity #51. Extended loop condition, added checking for NULL to
- prevent seg.fault.
+ * 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.
-2006-09-25 Andreas Kupries <andreask@activestate.com>
+ * doc/memory.n: [Bug 988703]: Add mechanism for finding what Tcl_Objs
+ * generic/tclCkalloc.c (MemoryCmd): are allocated when built for
+ * generic/tclInt.decls: memory debugging. This was previously
+ * generic/tclInt.h: backported from Tcl 8.6 with the corrections to
+ * generic/tclObj.c (ObjData, TclFinalizeThreadObjects): fix [Bug
+ 2871908]. However, there were key elements missing. These changes make
+ things consistent between branches.
- * generic/tclBasic.c: Reverted exposure of patchlevel in registered
- core version when TIP#268 features are activated. Better compatibility
- with existing packages. Like Tk.
+2009-10-17 Donal K. Fellows <dkf@users.sf.net>
-2006-09-24 Miguel Sofer <msofer@users.sf.net>
+ * generic/tclVar.c (TclDeleteCompiledLocalVars, UnsetVarStruct)
+ (TclDeleteNamespaceVars):
+ * generic/tclTrace.c (Tcl_UntraceVar2): [Bug 2629338]: Stop traces
+ that are deleted part way through (a feature used by tdom) from
+ causing freed memory to be accessed.
- * generic/tclParse.c (Tcl_ParseCommand): also return an error if
- start==NULL and numBytes<0. This is coverity's bug #20
+2009-10-08 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclStringObj.c (STRING_SIZE): fix allocation for 0-length
- strings. This is coverity's bugs #54-5
-
-2006-09-22 Andreas Kupries <andreask@activestate.com>
+ * generic/tclDictObj.c (DictIncrCmd): [Bug 2874678]: Don't leak any
+ bignums when doing [dict incr] with a value.
+ * tests/dict.test (dict-19.3): Memory leak detection code.
- * generic/tclInt.h: Moved TIP#268's field 'packagePrefer' to the end
- of the structure, for better backward compatibility.
+2009-10-07 Andreas Kupries <andreask@activestate.com>
-2006-09-22 Andreas Kupries <andreask@activestate.com>
+ * generic/tclObj.c: [Bug 2871908]: Plug memory leaks of the
+ objThreadMap and lineCLPtr hashtables. Also make the names of the
+ continuation line information initialization and finalization
+ functions more consistent. Patch supplied by Joe Mistachkin
+ <joe@mistachkin.com>.
- * generic/tclPkg.c (Tcl_PkgRequireEx): Changes handling of the return
- information from 'Tcl_PkgRequireProc'. Keep the interpreter result
- empty. Backport of fix for problem found while testing #268 under 8.5.
- More details in the comments.
+ * generic/tclIORChan.c (ErrnoReturn): Replace the hardwired constant
+ 11 with the proper errno define, EAGAIN. What was I thinking? The
+ BSD's have a different errno assignment and break with the hardwired
+ number. Reported by emiliano on the chat.
-2006-09-22 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+2009-10-06 Don Porter <dgp@users.sourceforge.net>
- * generic/tclThreadTest.c (TclCreateThread): Use NULL instead of 0 as
- end-of-strings marker to Tcl_AppendResult; the difference matters on
- 64-bit machines. [Bug 1562528]
+ * generic/tclTomMathInt.h (new): Public header tclTomMath.h had
+ * generic/tclTomMath.h: dependence on private headers, breaking use
+ * generic/tommath.h: by extensions [Bug 1941434].
-2006-09-21 Andreas Kupries <andreask@activestate.com>
+2009-10-05 Don Porter <dgp@users.sourceforge.net>
- * generic/tcl.decls: Implemented TIP #268, conditionally.
- * generic/tclBasic.c: Define TCL_TIP268 to activate the new
- * generic/tclDecls.h: features.
- * generic/tclInt.h:
- * generic/tclPkg.c:
- * generic/tclStubInit.c:
- * generic/tclTest.c:
- * library/init.tcl
- * library/package.tcl:
- * tests/pkg.test:
- * tests/platform.test:
- * tests/safe.test:
- * doc/PkgRequire.3:
+ * changes: Update for 8.5.8 release.
-2006-09-15 Jeff Hobbs <jeffh@ActiveState.com>
+2009-10-04 Daniel Steffen <das@users.sourceforge.net>
- * library/http/http.tcl: Change " " -> "+" url encoding mapping
- * library/http/pkgIndex.tcl: to " " -> "%20" as per RFC 3986.
- * tests/http.test (http-5.1): bump http to 2.5.3 for 8.4.14
+ * macosx/tclMacOSXBundle.c: Workaround CF memory managment bug in
+ * unix/tclUnixInit.c: Mac OS X 10.4 & earlier. [Bug 2569449]
-2006-09-12 Andreas Kupries <andreask@activestate.com>
+2009-10-02 Kevin B. Kenny <kennykb@acm.org>
- * unix/configure.in (HAVE_MTSAFE_GETHOST*): Modified to recognize
- HP-UX 11.00 and beyond as having mt-safe implementations of the
- gethost functions.
- * unix/configure: Regenerated, using autoconf 2.13
+ * library/tzdata/Africa/Cairo:
+ * library/tzdata/Asia/Gaza:
+ * library/tzdata/Asia/Karachi:
+ * library/tzdata/Pacific/Apia: Olson's tzdata2009n.
- * unix/tclUnixCompat.c (PadBuffer): Fixed bug in calculation of the
- increment needed to align the pointer, and added documentation
- explaining why the macro is implemented as it is.
+2009-09-29 Don Porter <dgp@users.sourceforge.net>
-2006-09-11 Andreas Kupries <andreask@activestate.com>
+ * generic/tclAlloc.c: Cleaned up various routines in the
+ * generic/tclCkalloc.c: call stacks for memory allocation to
+ * generic/tclInt.h: guarantee that any size values computed
+ * generic/tclThreadAlloc.c: are within the domains of the routines
+ they get passed to. [Bugs 2557696 and 2557796].
- * tests/msgcat.test: Bumped version in auxiliary files as well.
- * doc/msgcat.n:
+2009-09-11 Don Porter <dgp@users.sourceforge.net>
-2006-09-11 Daniel Steffen <das@users.sourceforge.net>
+ * library/http/http.tcl: Bump to http 2.7.4 to account for
+ * library/http/pkgIndex.tcl: [Bug 2849860] fix.
+ * unix/Makefile.in:
+ * win/Makefile.in:
- * unix/tclUnixCompat.c: make compatLock static and only declare it
- when it will actually be used; #ifdef parts of TSD that are not always
- needed; adjust #ifdefs to cover all possible cases; fix whitespace.
+2009-09-10 Donal K. Fellows <dkf@users.sf.net>
-2006-09-10 Don Porter <dgp@users.sourceforge.net>
+ * library/http/http.tcl (http::Event): [Bug 2849860]: Handle charset
+ names in double quotes; some servers like generating them like that.
- * library/msgcat/msgcat.tcl: Bump to version msgcat 1.3.4 to account
- * library/msgcat/pkgIndex.tcl: for modifications.
+2009-09-01 Don Porter <dgp@users.sourceforge.net>
-2006-09-10 Daniel Steffen <das@users.sourceforge.net>
+ * library/tcltest/tcltest.tcl: Bump to tcltest 2.3.2 after revision
+ * library/tcltest/pkgIndex.tcl: to verbose error message.
+ * unix/Makefile.in:
+ * win/Makefile.in:
- * library/msgcat/msgcat.tcl (msgcat::Init): on Darwin, add fallback of
- * tests/msgcat.test: default msgcat locale to
- * unix/tclUnixInit.c (TclpSetVariables): current CFLocale
- identifier if available (via private ::tcl::mac::locale global, set at
- interp init when on Mac OS X 10.3 or later with CoreFoundation).
+2009-08-27 Don Porter <dgp@users.sourceforge.net>
- * unix/tcl.m4: add caching to new SC_TCL_* macros for MT-safe wrappers
- * unix/configure: autoconf-2.13
+ * generic/tclStringObj.c: [Bug 2845535]: A few more string
+ overflow cases in [format].
-2006-09-08 Andreas Kupries <andreask@activestate.com>
+2009-08-25 Andreas Kupries <andreask@activestate.com>
- * unix/tclUnixCompat.c: Fixed conditions for CopyArray/CopyString, and
- CopyHostent. Also fixed bad var names in TclpGetHostByName.
+ * generic/tclBasic.c (Tcl_CreateInterp, Tcl_EvalTokensStandard)
+ (EvalTokensStandard, Tcl_EvalEx, EvalEx, TclAdvanceContinuations)
+ (TclEvalObjEx):
+ * generic/tclCmdMZ.c (Tcl_SwitchObjCmd, TclListLines):
+ * generic/tclCompCmds.c (*):
+ * generic/tclCompile.c (TclSetByteCodeFromAny, TclInitCompileEnv)
+ (TclFreeCompileEnv, TclCompileScript):
+ * generic/tclCompile.h (CompileEnv):
+ * generic/tclInt.h (ContLineLoc, Interp):
+ * generic/tclObj.c (ThreadSpecificData, ContLineLocFree)
+ (TclThreadFinalizeObjects, TclInitObjSubsystem, TclContinuationsEnter)
+ (TclContinuationsEnterDerived, TclContinuationsCopy)
+ (TclContinuationsGet, TclFreeObj):
+ * generic/tclParse.c (TclSubstTokens, Tcl_SubstObj):
+ * generic/tclProc.c (TclCreateProc):
+ * generic/tclVar.c (TclPtrSetVar):
+ * tests/info.test (info-30.0-24):
-2006-09-08 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+ Extended parser, compiler, and execution with code and attendant data
+ structures tracking the positions of continuation lines which are not
+ visible in script Tcl_Obj*'s, to properly account for them while
+ counting lines for #280.
- * unix/tclUnixCompat.c: Added fallback to gethostbyname() and
- gethostbyaddr() if the implementation is known to be MT-safe
- (currently for Darwin 6 or later only).
+2009-08-24 Daniel Steffen <das@users.sourceforge.net>
- * unix/configure.in: Assume gethostbyname() and gethostbyaddr() are
- MT-safe starting with Darwin 6 (Mac OSX 10.2).
+ * macosx/tclMacOSXNotify.c: Fix multiple issues with nested event
+ loops when CoreFoundation notifier is running in embedded mode. (Fixes
+ problems in TkAqua Cocoa reported by Youness Alaoui on tcl-mac)
- * unix/configure: Regenerated with autoconf V2.13
+2009-08-21 Don Porter <dgp@users.sourceforge.net>
-2006-09-07 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+ * generic/tclFileName.c: Correct regression in [Bug 2837800] fix.
+ * tests/fileName.test:
- * unix/tclUnixFCmd.c: Removed some false tests added (and left by
- mistake) by fixing [Bug 999544]
+2009-08-20 Don Porter <dgp@users.sourceforge.net>
- * unix/tclUnixCompat.c: Added fallback to MT-unsafe library calls if
- TCL_THREADS is not defined. Fixed alignment of arrays copied by
- CopyArrayi() to be on the sizeof(char *) boundary.
+ * generic/tclFileName.c: [Bug 2837800]: Get the correct result from
+ [glob */test] when * matches something like ~foo.
-2006-09-07 Andreas Kupries <andreask@activestate.com>
+ * generic/tclPathObj.c: [Bug 2806250]: Prevent the storage of strings
+ starting with ~ in the "tail" part (normPathPtr field) of the path
+ intrep when PATHFLAGS != 0. This establishes the assumptions relied
+ on elsewhere that the name stored there is a relative path. Also
+ refactored to make an AppendPath() routine instead of the cut/paste
+ stanzas that were littered throughout.
- * unix/configure: Regenerated using autoconf 2.13.
+2009-08-20 Donal K. Fellows <dkf@users.sf.net>
-2006-09-07 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+ * generic/tclCmdIL.c (Tcl_LsortObjCmd): Plug memory leak.
- * unix/tclUnixChan.c Rewritten MT-safe wrappers to
- * unix/tclUnixCompat.c return ptrs to TSD storage
- * unix/tclUnixFCmd.c making them all look like their
- * unix/tclUnixPort.h MT-unsafe pendants API-wise.
- * unix/tclUnixSock.c
+2009-08-18 Don Porter <dgp@users.sourceforge.net>
-2006-09-06 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+ * generic/tclPathObj.c: [Bug 2837800]: Added NULL check to prevent
+ * tests/fileName.test: crashes during [glob].
- * unix/tclUnixChan.c: Added TCL_THREADS ifdef'ed usage
- * unix/tclUnixFCmd.c: of MT-safe calls like:
- * unix/tclUnixSock.c: getpwuid, getpwnam, getgrgid, getgrnam,
- * unix/tclUnixPort.h: gethostbyname and gethostbyaddr.
- * unix/Makefile.in: See Tcl Bug: 999544
- * unix/configure.in:
- * unix/tcl.m4:
- * unix/configure: Regenerated.
+2009-08-06 Andreas Kupries <andreask@activestate.com>
- * unix/tclUnixCompat.c: New file containing MT-safe implementation of
- some library calls.
+ * doc/refchan.n [Bug 2827000]: Extended the implementation of
+ * generic/tclIORChan.c: reflective channels (TIP 219, method 'read'),
+ * tests/ioCmd.test: enabling handlers to signal EAGAIN to indicate 'no
+ data, but not at EOF either', and other system errors. Updated
+ documentation, extended testsuite (New test cases iocmd*-23.{9,10}).
-2006-09-04 Don Porter <dgp@users.sourceforge.net>
+2009-08-02 Donal K. Fellows <dkf@users.sf.net>
- * tests/main.text (Tcl_Main-4.4): Test corrected to not be
- timing sensitive to the Bug 1481986 fix. [Bug 1550858]
+ * unix/tclUnixFCmd.c (GetOwnerAttribute, SetOwnerAttribute)
+ (GetGroupAttribute, SetGroupAttribute): [Bug 1942222]: Stop calling
+ * unix/tclUnixFile.c (TclpGetUserHome): endpwent() and endgrent();
+ they've been unnecessary for ages.
-2006-09-04 Jeff Hobbs <jeffh@ActiveState.com>
+2009-07-31 Don Porter <dgp@users.sourceforge.net>
- * doc/package.n: correct package example
+ * generic/tclStringObj.c: [Bug 2830354]: Corrected failure to
+ * tests/format.test: grow buffer when format spec request
+ large width floating point values. Thanks to Clemens Misch.
-2006-08-30 Jeff Hobbs <jeffh@ActiveState.com>
+2009-07-24 Andreas Kupries <andreask@activestate.com>
- * win/tclWinChan.c: [Bug 819667] Improve logic for identifying COM
- ports.
+ * generic/tclIO.c (Tcl_GetChannelHandle): [Bug 2826248]: Do not crash
+ * generic/tclPipe.c (FileForRedirect): for getHandleProc == NULL, this
+ is allowed. Provide a nice error message in the bypass area. Updated
+ caller to check the bypass for a mesage. Bug reported by Andy
+ Sonnenburg <andy22286@users.sourceforge.net>. Backported from CVS
+ head.
- * win/tclWinFCmd.c: [Bug 1548263] Added test for NULL return
- * generic/tclIOUtil.c: from Tcl_FSGetNormalizedPath which was
- causing segv's
+2009-07-23 Joe Mistachkin <joe@mistachkin.com>
- * generic/tclFileName.c (TclDoGlob): match incr with existing decr.
+ * generic/tclNotify.c: [Bug 2820349]: Ensure that queued events are
+ freed once processed.
- * unix/Makefile.in: add valgrindshell target and update default
- VALGRINDARGS. User can override, or add to it with VALGRIND_OPTS env
- var.
+2009-07-21 Kevin B. Kenny <kennykb@acm.org>
- * generic/tclBasic.c (Tcl_CreateInterp): init iPtr->threadId
+ * library/tzdata/Asia/Dhaka:
+ * library/tzdata/Indian/Mauritius: Olson's tzdata2009k.
- * generic/tclIOGT.c (ExecuteCallback):
- * generic/tclPkg.c (Tcl_PkgRequireEx): replace Tcl_GlobalEval(Obj)
- with more efficient Tcl_Eval(Obj)Ex
+2009-07-20 Donal K. Fellows <dkf@users.sf.net>
-2006-08-22 Andreas Kupries <andreask@activestate.com>
+ * generic/tclCmdMZ.c (StringIsCmd): Reorganize so that [string is] is
+ more efficient when parsing things that are correct, at a cost of
+ making the empty string test slightly more costly. With this, the cost
+ of doing [string is integer -strict $x] matches [catch {expr {$x+0}}]
+ in the successful case, and greatly outstrips it in the failing case.
- * unix/tclUnixNotfy.c (Tcl_WaitForEvent): Fixed broken if syntax
- committed 2006-08-21 by Daniel. The broken syntax is visible to all
- unix platforms, but not on OSX for machines which HAVE_COREFOUNDATION.
+2009-07-16 Don Porter <dgp@users.sourceforge.net>
-2006-08-21 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclCmdIL.c: Removed unused variables.
+ * generic/tclCompile.c:
+ * generic/tclVar.c:
+ * unix/tclUnixChan.c:
- * generic/tclIOUtil.c: Revisions to complete the thread finalization
- of the cwdPathPtr. [Bug 1536142]
+ * generic/tclScan.c: Typo in ACCEPT_NAN configuration.
-2006-08-21 Daniel Steffen <das@users.sourceforge.net>
+ * generic/tclStrToD.c: [Bug 2819200]: Set floating point control
+ register on MIPS systems so that the gradual underflow expected by Tcl
+ is in effect.
- * macosx/tclMacOSXNotify.c (Tcl_WaitForEvent): if the run loop is
- already running (e.g. if Tcl_WaitForEvent was called recursively),
- re-run it in a custom run loop mode containing only the source for the
- notifier thread, otherwise wakeups from other sources added to the
- common run loop modes might get lost; sync panic msg changes from
- HEAD.
+2009-07-14 Andreas Kupries <andreask@activestate.com>
- * unix/tclUnixNotfy.c (Tcl_WaitForEvent): on 64-bit Darwin,
- pthread_cond_timedwait() appears to have a bug that causes it to wait
- forever when passed an absolute time which has already been exceeded
- by the system time; as a workaround, when given a very brief timeout,
- just do a poll on that platform. [Bug 1457797]
+ * generic/tclBasic.c (DeleteInterpProc,TclArgumentBCEnter,
+ (TclArgumentBCRelease, TclArgumentGet):
+ * generic/tclCompile.c (EnterCmdWordIndex, TclCleanupByteCode,
+ (TclInitCompileEnv, TclCompileScript):
+ * generic/tclCompile.h (ExtCmdLoc):
+ * generic/tclExecute.c (TclExecuteByteCode):
+ * generic/tclInt.h (ExtIndex, CFWordBC):
+ * tests/info.test (info-39.0):
- * unix/tclUnixPort.h (Darwin): override potentially faulty configure
- detection of termios availability in all cases, since termios is known
- to be present on all Mac OS X releases since 10.0. [Bug 497147]
+ Backport of some changes made to the Tcl head, to handle literal
+ sharing better. The code here is much simpler (trimmed down) compared
+ to the head as the 8.5 branch is not bytecode compiling whole files,
+ and doesn't compile eval'd code either.
-2006-08-18 Daniel Steffen <das@users.sourceforge.net>
+ Reworked the handling of literal command arguments in bytecode to be
+ saved (compiler) and used (execution) per command (see the
+ TCL_INVOKE_STK* instructions), and not per the whole bytecode. This
+ removes the problems with location data caused by literal sharing in
+ proc bodies. Simplified the associated datastructures (ExtIndex is
+ gone, as is the function EnterCmdWordIndex).
- * unix/tcl.m4 (Darwin): add support for --enable-64bit on x86_64, for
- universal builds including x86_64, for 64-bit CoreFoundation on
- Leopard and for use of -mmacosx-version-min instead of
- MACOSX_DEPLOYMENT_TARGET.
- * unix/configure: autoconf-2.13
+2009-07-01 Pat Thoyts <patthoyts@users.sourceforge.net>
- * generic/tcl.h: add fixes for building on Leopard and support
- * unix/tclUnixPort.h: for 64-bit CoreFoundation on Leopard.
+ * win/tclWinInt.h: [Bug 2806622]: Handle the GetUserName API call
+ * win/tclWin32Dll.c: via the tclWinProcs indirection structure. This
+ * win/tclWinInit.c: fixes a problem obtaining the username when the
+ USERNAME environment variable is unset.
- * unix/tclUnixPort.h: on Darwin x86_64, disable use of vfork as it
- causes execve to fail intermittently. (rdar://4685553)
-
- * macosx/README: updates for x86_64 support and Xcode 2.4.
+2009-06-15 Don Porter <dgp@users.sourceforge.net>
- * unix/tclUnixChan.c (TclUnixWaitForFile): with timeout < 0, if
- select() returns early (e.g. due to a signal), call it again instead
- of returning a timeout result. Fixes intermittent event-13.8 failures.
+ * generic/tclStringObj.c: sprintf() -> Tcl_ObjPrintf() conversion.
-2006-08-09 Don Porter <dgp@users.sourceforge.net>
+2009-06-13 Don Porter <dgp@users.sourceforge.net>
- * generic/tclEncoding.c: Replace buffer copy in for loop with
- call to memcpy(). Thanks to afredd. [Patch 1530262]
+ * generic/tclCompile.c: The value stashed in iPtr->compiledProcPtr
+ * generic/tclProc.c: when compiling a proc survives too long. We
+ * tests/execute.test: only need it there long enough for the right
+ TclInitCompileEnv() call to re-stash it into envPtr->procPtr. Once
+ that is done, the CompileEnv controls. If we let the value of
+ iPtr->compiledProcPtr linger, though, then any other bytecode compile
+ operation that takes place will also have its CompileEnv initialized
+ with it, and that's not correct. The value is meant to control the
+ compile of the proc body only, not other compile tasks that happen
+ along. Thanks to Carlos Tasada for discovering and reporting the
+ problem. [Bug 2802881].
-2006-08-03 Daniel Steffen <das@users.sourceforge.net>
+2009-06-10 Don Porter <dgp@users.sourceforge.net>
- * unix/tclUnixPipe.c (TclpCreateProcess): for USE_VFORK: ensure
- standard channels are initialized before vfork() so that the child
- doesn't potentially corrupt global state in the parent's address
- space.
+ * generic/tclStringObj.c: Revised [format] to not overflow the
+ integer calculations computing the length of the %ll formats of
+ really big integers. Also added protections so that [format]s that
+ would produce results overflowing the maximum string length of Tcl
+ values throw a normal Tcl error instead of a panic. [Bug 2801413]
-2006-07-30 Kevin Kenny <kennykb@acm.org>
+2006-06-09 Kevin B. Kenny <kennykb@acm.org>
- * tests/clock.test: Allowed UTC as a synonym for GMT in two tests that
- indirectly invoke 'strftime' with the result of 'gmtime' to fix a
- bogus test failure on FreeBSD systems. [Bug 1513489]
-
-2006-07-30 Joe English <jenglish@users.sourceforge.net>
+ * generic/tclGetDate.y: Fixed a thread safety bug in the generated
+ * library/clock.tcl: Bison parser (needed a %pure-parser
+ * tests/clock.test: declaration to avoid static variables).
+ Discovered that the %pure-parser declaration
+ allowed for returning the Bison error message
+ to the Tcl caller in the event of a syntax
+ error, so did so.
+ * generic/tclDate.c: bison 2.3
- * doc/AppInit.3: Fix typo [Bug 1496886]
+2006-06-08 Kevin B. Kenny <kennykb@acm.org>
-2006-07-20 Daniel Steffen <das@users.sourceforge.net>
+ * library/tzdata/Asia/Dhaka: New DST rule for Bangladesh.
+ (Olson's tzdata2009i.)
- * macosx/tclMacOSXNotify.c (Tcl_InitNotifier, Tcl_WaitForEvent):
- create notifier thread lazily upon first call to Tcl_WaitForEvent()
- rather than in Tcl_InitNotifier(). Allows calling exeve() in processes
- where the event loop has not yet been run (Darwin's execve() fails in
- processes with more than one thread), in particular allows embedders
- to call fork() followed by execve(), previously the pthread_atfork()
- child handler's call to Tcl_InitNotifier() would immediately recreate
- the notifier thread in the child after a fork.
+2009-06-02 Don Porter <dgp@users.sourceforge.net>
- * macosx/tclMacOSXNotify.c (Tcl_InitNotifier): add support for
- * unix/tclUnixFCmd.c (DoRenameFile, CopyFileAtts): weakly importing
- * unix/tclUnixInit.c (TclpSetInitialEncodings): symbols not
- available on OSX 10.2 or 10.3, enables binaires built on later OSX
- versions to run on earlier ones.
- * macosx/README: document how to enable weak-linking; cleanup.
- * unix/tclUnixPort.h: add support for weak-linking; conditionalize
- AvailabilityMacros.h inclusion; only disable realpath on 10.2 or
- earlier when threads are enabled.
- * unix/tclLoadDyld.c (TclpLoadMemoryGetBuffer): change runtime Darwin
- * unix/tclUnixInit.c (TclpInitPlatform): release check to use
- global initialized once
- * unix/tclUnixFCmd.c (DoRenameFile, TclpObjNormalizePath): add runtime
- Darwin release check to determine if realpath is threadsafe.
- * unix/configure.in: add check on Darwin for compiler support of weak
- * unix/tcl.m4: import and for AvailabilityMacros.h header; move
- Darwin specific checks & defines that are only relevant to the tcl
- build out of tcl.m4; restrict framework option to Darwin; cleanup
- quoting.
- * unix/configure: autoconf-2.13
+ * generic/tclExecute.c: Replace dynamically-initialized table with
+ a table of static constants in the lookup table for exponent operator
+ computations that fit in a 64 bit integer result.
- * unix/tclLoadDyld.c (TclpLoadMemory):
- * unix/tclUnixPipe.c (TclpCreateProcess): fix signed-with-unsigned
- comparison and other warnings from gcc4 -Wextra.
+ * generic/tclExecute.c: Corrected implementations and selection
+ logic of the INST_EXPON instruction to fix [Bug 2798543].
-2006-07-13 Andreas Kupries <andreask@activestate.com>
+2009-06-01 Don Porter <dgp@users.sourceforge.net>
- * unix/tclUnixPort.h: Added the inclusion of <AvailabilityMacros.h>.
- The missing header caused the upcoming #if conditions to wrongly
- exclude realpath, causing file normalize to ignore symbolic links in
- the path.
+ * tests/expr.test: Added many tests demonstrating the broken
+ cases of [Bug 2798543].
-2006-07-11 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+2009-05-30 Kevin B. Kenny <kennykb@acm.org>
- * generic/tclAsync.c: Made Tcl_AsyncDelete() more tolerant when called
- after all thread TSD has been garbage-collected.
+ * library/tzdata/Africa/Cairo:
+ * library/tzdata/Asia/Amman: Olson's tzdata2009h.
-2006-07-10 Jeff Hobbs <jeffh@ActiveState.com>
+2009-05-29 Andreas Kupries <andreask@activestate.com>
- * generic/tclIO.c (Tcl_CreateChannel): allow Tcl std channel
- inheritance to be #defined out (default remains in).
+ * library/platform/platform.tcl: Fixed handling of cpu ia64,
+ * library/platform/pkgIndex.tcl: taking ia64_32 into account
+ * unix/Makefile.in: now. Bumped version to 1.0.5. Updated the
+ * win/Makefile.in: installation commands.
-2006-06-15 Don Porter <dgp@users.sourceforge.net>
+2009-05-07 Miguel Sofer <msofer@users.sf.net>
- * changes: changes to start prep for an 8.4.14 release.
+ * generic/tclObj.c (Tcl_GetCommandFromObj): fix for bug [2785893],
+ insure that a command in a deleted namespace cannot be found
+ through a cached name.
-2006-06-14 Daniel Steffen <das@users.sourceforge.net>
+2009-05-06 Don Porter <dgp@users.sourceforge.net>
- * unix/tclUnixPort.h (Darwin): support for MAC_OS_X_VERSION_MAX_ALLOWED
- define from AvailabilityMacros.h: override configure detection and only
- use API available in the indicated OS version or earlier.
+ * generic/tclCmdMZ.c: Improve overflow error message from
+ [string repeat]. [Bug 2582327]
-2006-06-14 Pat Thoyts <patthoyts@users.sourceforge.net>
+2009-04-28 Jeff Hobbs <jeffh@ActiveState.com>
- * generic/regerror.c: Enable building Tcl with Microsoft's latest
- * generic/tcl.h: compiler offering (VS2005). We have to handle
- * generic/tclDate.c: a number of oddities as they have deprecated
- * tests/env.test: most of the standard C library and now
- * win/makefile.vc: generate manifest files to be linked into the
- * win/nmakehlp.c: binaries. [Bug 1424909]
- * win/rules.vc:
- * win/tclWinTime.c:
+ * unix/tcl.m4, unix/configure (SC_CONFIG_CFLAGS): harden the check
+ to add _r to CC on AIX with threads.
-2006-06-13 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+2009-04-27 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
- * unix/tclLoadDl.c (TclpDlopen): Workaround for a compiler bug in Sun
- Forte 6. [Bug 1503729]
+ * generic/tclInt.h: Backport fix for [Bug 1028264]: WSACleanup() too early.
+ * generic/tclEvent.c: The fix introduces "late exit handlers"
+ * win/tclWinSock.c: for similar late process-wide cleanups.
-2006-06-06 Don Porter <dgp@users.sourceforge.net>
+2009-04-27 Alexandre Ferrieux <ferrieux@users.sourceforge.net>
- * doc/GetStdChan.3: Added recommendation that each call to
- Tcl_SetStdChannel() be accompanied by a call to Tcl_RegisterChannel().
+ * win/tclWinSock.c: Backport fix for [Bug 2446662]: resync Win
+ behavior on RST with that of unix (EOF).
-2006-05-31 Jeff Hobbs <jeffh@ActiveState.com>
+2009-04-27 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclNamesp.c (NamespaceInscopeCmd): revert [Bug 1400572]
- fix of 2006-01-09 for [namespace inscope] as it seems to mess with
- itcl scope decoding. Leaving namespace-29.6 test failure until final
- cause it determined.
+ * doc/concat.n (EXAMPLES): [Bug 2780680]: Rewrote so that the spacing
+ of result messages is correct. (The exact way they were wrong was
+ different when rendered through groff or as HTML, but it was still
+ wrong both ways.)
-2006-05-29 Jeff Hobbs <jeffh@ActiveState.com>
+2009-04-24 Stuart Cassoff <stwo@users.sf.net>
- * generic/tcl.h (Tcl_DecrRefCount): use if/else construct to allow
- placement in unbraced outer if/else conditions. (jcw)
+ * unix/Makefile.in: [Patch 2769530]: Don't chmod/exec installManPage.
-2006-05-27 Daniel Steffen <das@users.sourceforge.net>
+2009-04-15 Don Porter <dgp@users.sourceforge.net>
- * macosx/tclMacOSXNotify.c: implemented pthread_atfork() handler that
- * unix/tcl.m4 (Darwin): recreates CoreFoundation state and notifier
- thread in the child after a fork(). Note that pthread_atfork() is
- available starting with Tiger only. Because vfork() is used by the core
- on Darwin, [exec]/[open] are not affected by this fix, only extensions
- or embedders that call fork() directly (such as TclX). However, this
- only makes fork() safe from corefoundation tcl with --disable-threads;
- as on all platforms, forked children may deadlock in threaded tcl due
- to the potential for stale locked mutexes in the child. [Patch 923072]
- * unix/configure: autoconf-2.59
+ *** 8.5.7 TAGGED FOR RELEASE ***
-2006-05-24 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+ * generic/tclStringObj.c: AppendUnicodeToUnicodeRep failed
+ to set stringPtr->allocated to 0, leading to crashes.
- * unix/tcl.m4 (SC_CONFIG_SYSTEM): Fixed quoting of command script to
- awk; it was a rarely used branch, but it was wrong. [Bug 1494160]
+ * changes: Update for 8.5.7 release.
-2006-05-13 Don Porter <dgp@users.sourceforge.net>
+2009-04-14 Stuart Cassoff <stwo@users.sourceforge.net>
- * generic/tclFileName.c (TclDoGlob): Disabled the partial
- normalization done by the recursive glob routine, since changing the
- precise string of the pathname broke [glob] on some Tcl_Filesystems.
- [Bug 943995]
+ * unix/tcl.m4: Removed -Wno-implicit-int from CFLAGS_WARNING.
- * generic/tclProc.c (ProcCompileProc): When a bump of the compile
- epoch forces the re-compile of a proc body, take care not to
- overwrite any Proc struct that may be referred to on the active
- call stack. This fixes [Bug 1482718]. Note that the fix will not be
- effective for code that calls the private routine TclProcCompileProc()
- directly.
+2008-04-14 Kevin B. Kenny <kennykb@acm.org>
-2006-05-05 Don Porter <dgp@users.sourceforge.net>
+ * library/tzdata/Asia/Karachi: Updated rules for Pakistan Summer
+ Time (Olson's tzdata2009f)
- * generic/tclMain.c (Tcl_Main): Corrected flaw that required
- * tests/main.test: (Tcl_Main-4.5): processing of one interactive
- command before passing control to the loop routine registered with
- Tcl_SetMainLoop() [Bug 1481986]
+2009-04-10 Don Porter <dgp@users.sourceforge.net>
-2006-05-04 Don Porter <dgp@users.sourceforge.net>
+ * changes: Update for 8.5.7 release.
- * README: Bump version number to 8.4.14
- * generic/tcl.h:
+ * generic/tcl.h: Bump to 8.5.7 for release.
+ * library/init.tcl:
* tools/tcl.wse.in:
* unix/configure.in:
* unix/tcl.spec:
- * win/README.binary:
* win/configure.in:
+ * README:
- * unix/configure: autoconf-2.13
+ * unix/configure: autoconf-2.59
* win/configure:
- * generic/tclExecute.c (ExprSrandFunc): Restore acceptance of wide
- * tests/expr-old.test: integer values by srand() [Bug 1480509]
-
-2006-04-12 Don Porter <dgp@users.sourceforge.net>
-
- *** 8.4.13 TAGGED FOR RELEASE ***
+ * generic/tclStringObj.c (UpdateStringOfString): Fix bug detected
+ by compiler warning about undefined "dst".
- * changes: updates for another RC.
+ * tests/httpd: Backport new tests for http 2.7.3.
+ * tests/http.tcl:
-2006-04-11 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclCmdMZ.c: Stop some interference between enter traces
- * tests/trace.test: and enterstep traces. [Bug 1458266]
+2009-04-10 Daniel Steffen <das@users.sourceforge.net>
-2006-04-10 Don Porter <dgp@users.sourceforge.net>
+ * unix/tclUnixChan.c: TclUnixWaitForFile(): use FD_* macros
+ * macosx/tclMacOSXNotify.c: to manipulate select masks (Cassoff).
+ [Freq 1960647] [Bug 3486554]
- * changes: updates for another RC.
+ * unix/tclLoadDyld.c: use RTLD_GLOBAL instead of RTLD_LOCAL.
+ [Bug 1961211]
-2006-04-06 Jeff Hobbs <jeffh@ActiveState.com>
+ * macosx/tclMacOSXNotify.c: revise CoreFoundation notifier to allow
+ embedding into applications that
+ already have a CFRunLoop running and
+ want to run the tcl event loop via
+ Tcl_ServiceModeHook(TCL_SERVICE_ALL).
- * generic/tclRegexp.c (FinalizeRegexp): full reset data to indicate
- readiness for reinitialization.
+ * macosx/tclMacOSXNotify.c: add CFRunLoop based Tcl_Sleep() and
+ * unix/tclUnixChan.c: TclUnixWaitForFile() implementations
+ * unix/tclUnixEvent.c: and disable select() based ones in
+ CoreFoundation builds.
-2006-04-06 Don Porter <dgp@users.sourceforge.net>
+ * unix/tclUnixNotify.c: simplify, sync with tclMacOSXNotify.c.
- * generic/tclIndexObj.c (Tcl_GetIndexFromObjStruct): It seems there
- * tests/indexObj.test: are extensions that rely on the prior behavior
- * doc/GetIndex.3: that the empty string cannot succeed as a
- unique prefix matcher, so I'm restoring Donal Fellows's solution.
- Added mention of this detail to the documentation. [Bug 1464039]
+ * generic/tclInt.decls: add TclMacOSXNotifierAddRunLoopMode()
+ * generic/tclIntPlatDecls.h: internal API, regen.
+ * generic/tclStubInit.c:
-2006-04-06 Daniel Steffen <das@users.sourceforge.net>
+ * unix/configure.in (Darwin): use Darwin SUSv3 extensions if
+ available; remove /Network locations
+ from default tcl package search path
+ (NFS mounted locations and thus slow).
+ * unix/configure: autoconf-2.59
+ * unix/tclConfig.h.in: autoheader-2.59
- * unix/tcl.m4: removed TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
- define on Darwin. [Bug 1457515]
- * unix/configure: autoconf-2.13
+ * macosx/tclMacOSXBundle.c: on Mac OS X 10.4 and later, replace
+ deprecated NSModule API by dlfcn API.
-2006-04-05 Don Porter <dgp@users.sourceforge.net>
+2009-04-09 Kevin B. Kenny <kennykb@acm.org>
- * library/reg/pkgIndex.tcl: Long overlooked bump to registry
- * win/tclWinReg.c: package version 1.1.4 (should have
- been done for the Tcl 8.4.8 release!)
+ * tools/tclZIC.tcl: Always emit Unix-style line terminators.
+ * library/tzdata: Olson's tzdata2009e.
- * library/dde/pkgIndex.tcl: Long overlooked bump to dde package
- * win/tclWinDde.c: version 1.2.4 (should have been done
- for the Tcl 8.4.8 release!)
+2009-04-09 Don Porter <dgp@users.sourceforge.net>
-2006-04-05 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * library/http/http.tcl: Backport http 2.7.3 from HEAD for
+ * library/http/pkgIndex.tcl: bundling with the Tcl 8.5.7 release.
+ * unix/Makefile.in:
+ * win/Makefile.in:
- * generic/tclIndexObj.c (Tcl_GetIndexFromObjStruct): Allow empty
- strings to be matched by the Tcl_GetIndexFromObj machinery, in the
- same manner as any other key. [Bug 1464039]
+2009-04-08 Andreas Kupries <andreask@activestate.com>
-2006-04-04 Don Porter <dgp@users.sourceforge.net>
+ * library/platform/platform.tcl: Extended the darwin sections to
+ * library/platform/pkgIndex.tcl: add a kernel version number to
+ * unix/Makefile.in: the identifier for anything from Leopard (10.5)
+ * win/Makefile.in: on up. Extended patterns for same. Extended cpu
+ * doc/platform.n: recognition for 64bit Tcl running on a 32bit
+ kernel on a 64bit processor (By Daniel Steffen). Bumped version to
+ 1.0.4. Updated Makefiles.
- * generic/tclPkg.c: Revised Bug 1162286 fix from 2005-11-08 to be
- * tests/pkg.test: even more forgiving of package version
- mismatch errors in [package ifneeded] commands, not even logging any
- warning messages. This further reduces the
- ***POTENTIAL INCOMPATIBILITY*** noted for that change.
+2009-04-08 Don Porter <dgp@users.sourceforge.net>
-2006-04-03 Andreas Kupries <andreask@activestate.com>
+ * library/tcltest/tcltest.tcl: Converted [eval]s (some unsafe!) to
+ * library/tcltest/pkgIndex.tcl: {*} in tcltest package. [Bug 2570363]
+ * unix/Makefile.in: => tcltest 2.3.1
+ * win/Makefile.in:
- * generic/tclIO.c (ReadChars): Added check, panic and commentary to a
- piece of code which relies on BUFFER_PADDING to create enough space at
- the beginning of each buffer for the insertion of partial multibyte
- data at the beginning of a buffer. Commentary explains why this code
- is OK, and the panic is as a precaution if someone twiddled the
- BUFFER_PADDING into uselessness.
+2009-04-07 Don Porter <dgp@users.sourceforge.net>
- * generic/tclIO.c (ReadChars): Temporarily suppress the use of
- TCL_ENCODING_END set when EOF was reached while the buffer we are
- converting is not truly the last buffer in the queue. Together with
- the Utf bug below it was possible to completely wreck the buffer data
- structures, eventually crashing Tcl. [Bug 1462248]
+ * generic/tclStringObj.c: Completed backports of fixes for
+ [Bug 2494093] and [Bug 2553906].
- * generic/tclEncoding.c (UtfToUtfProc): Stop accessing memory beyond
- the end of the input buffer when TCL_ENCODING_END is set and the last
- bytes of the buffer start a multi-byte sequence. This bug contributed
- to [Bug 1462248].
+2009-03-30 Don Porter <dgp@users.sourceforge.net>
-2006-03-28 Jeff Hobbs <jeffh@ActiveState.com>
+ * doc/Alloc.3: Size argument is "unsigned int". [Bug 2556263]
- * win/configure, win/tcl.m4: define MACHINE for gcc builds as well.
- Needed by Tk for manifest generation.
+ * 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]
- * win/tclWinConsole.c: revert 2005-11-03 [Patch 1256872] change to add
- win32 unicode console support as it broke the ability to modify the
- encoding to the console.
+2009-03-27 Don Porter <dgp@users.sourceforge.net>
-2006-03-28 Daniel Steffen <das@users.sourceforge.net>
+ * generic/tclPathObj.c (TclPathPart): TclPathPart() was computing
+ * tests/fileName.test: the wrong results for both [file dirname] and
+ [file tail] on "path" arguments with the PATHFLAGS != 0 intrep and
+ with an empty string for the "joined-on" part. [Bug 2710920]
- * unix/tclUnixFCmd.c (TclpObjNormalizePath): deal with *BSD/Darwin
- realpath() converting relative paths into absolute paths. [Bug 1064247]
+2009-03-20 Don Porter <dgp@users.sourceforge.net>
-2006-03-28 Vince Darley <vincentdarley@sourceforge.net>
+ * generic/tclStringObj.c: Test stringObj-6.9 checks that
+ * tests/stringObj.test: Tcl_AppendStringsToObj() no longer
+ crashes when operating on a pure unicode value. [Bug 2597185]
- * generic/tclIOUtil.c: fix to nativeFilesystemRecord comparisons
- (lesser part of [Bug 1064247])
+ * generic/tclExecute.c (INST_CONCAT1): Panic when appends overflow
+ the max length of a Tcl value. [Bug 2669109]
-2006-03-27 Pat Thoyts <patthoyts@users.sourceforge.net>
+2009-03-18 Don Porter <dgp@users.sourceforge.net>
- * win/tclWinTest.c: Fixes for [Bug 1456373] (mingw-gcc issue)
+ * win/tclWinFile.c (TclpObjNormalizePath): Corrected Tcl_Obj leak.
+ Thanks to Joe Mistachkin for detection and patch. [Bug 2688184].
-2006-03-23 Don Porter <dgp@users.sourceforge.net>
+2009-03-15 Donal K. Fellows <dkf@users.sf.net>
- * tests/expr.test: Nan self-inquality test silenced. [Bug 761471]
+ * generic/tclPosixStr.c (Tcl_SignalId,Tcl_SignalMsg): [Patch 1513655]:
+ Added support for SIGINFO, which is present on BSD platforms.
-2006-03-22 Don Porter <dgp@users.sourceforge.net>
+2009-02-20 Don Porter <dgp@users.sourceforge.net>
- * changes: updates for another RC.
+ * 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].
-2006-03-18 Vince Darley <vincentdarley@sourceforge.net>
+2009-02-17 Jeff Hobbs <jeffh@ActiveState.com>
- * generic/tclTest.c:
- * win/tclWinFile.c:
- * win/tclWinTest.c:
- * tests/fCmd.test:
- * tests/winFCmd.test:
- * tests/tcltest.test: Backport of [file writable] fixes for Windows
- from HEAD. [Bug 1193497]
+ * win/tcl.m4, win/configure: Check if cl groks _WIN64 already to
+ avoid CC manipulation that can screw up later configure checks.
+ Use 'd'ebug runtime in 64-bit builds.
-2006-03-16 Andreas Kupries <andreask@activestate.com>
+2009-02-05 Don Porter <dgp@users.sourceforge.net>
- * doc/open.n: Documented the changed behaviour of 'a'ppend mode.
-
- * tests/io.test (io-43.1 io-44.[1234]): Rewritten to be
- self-contained with regard to setup and cleanup. [Bug 681793]
+ * 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/tclIOUtil.c (TclGetOpenMode): Added the flag O_APPEND to the
- list of POSIX modes used when opening a file for 'a'ppend. This
- enables the proper automatic seek-to-end-on-write by the OS. See [Bug
- 680143] for longer discussion.
+2009-02-04 Don Porter <dgp@users.sourceforge.net>
- * tests/ioCmd.test (iocmd-13.7.*): Extended the testsuite to check the
- new handling of 'a'.
+ * 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.
-2006-03-15 Andreas Kupries <andreask@activestate.com>
+ * generic/tclCmdMZ.c: Prevent crashes due to int overflow of the
+ length of the result of [string repeat]. [Bug 2561746]
- * tests/socket.test: Extended the timeout in socket-11.11 from 10 to
- 40 seconds to allow for really slow machines. Also extended
- actual/expected results with value of variable 'done' to make it
- clearer when a test fails due to a timeout. [Bug 792159]
+2009-01-29 Donal K. Fellows <dkf@users.sf.net>
-2006-03-14 Andreas Kupries <andreask@activestate.com>
+ * generic/tclNamesp.c (Tcl_FindCommand): [Bug 2519474]: Ensure that
+ the path is not searched when the TCL_NAMESPACE_ONLY flag is given.
- * generic/tclPipe.c (TclCreatePipeline): Modified the processing of
- pipebars to fail if the last bar is followed only by redirections.
- [Bug 768659]
+2009-01-22 Kevin B. Kenny <kennykb@acm.org>
-2006-03-14 Andreas Kupries <andreask@activestate.com>
+ * unix/tcl.m4: Corrected a typo ($(SHLIB_VERSION) should be
+ ${SHLIB_VERSION}).
+ * unix/configure: Autoconf 2.59
- * doc/fconfigure.n: Clarified that -translation is binary is reported
- as lf when queried, because it is identical to lf, except for the
- special additional behaviour when setting it. [Bug 666770]
+2009-01-21 Andreas Kupries <andreask@activestate.com>
-2006-03-14 Andreas Kupries <andreask@activestate.com>
+ * generic/tclIORChan.c (ReflectClose): Fix for [Bug 2458202].
+ 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.
- * win/tclWinPipe.c (Tcl_WaitPid): Backport of fix made to the head by
- David Gravereaux in 2004. See ChangeLog entry 2004-01-19. [Bug 1381436]
+2009-01-19 Kevin B. Kenny <kennykb@acm.org>
- Fixed a thread-safety problem with the process list. The delayed cut
- operation after the wait was going stale by being outside the list
- lock. It now cuts within the lock and does a locked splice for when it
- needs to instead. [Bug 859820]
+ * 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/configure: Autoconf 2.59
-2006-03-13 Don Porter <dgp@users.sourceforge.net>
+2009-01-09 Don Porter <dgp@users.sourceforge.net>
- * generic/tclEncoding.c: Report error when an escape encoding
- is missing one of its sub-encodings [Bug 506653]
+ * 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].
- * unix/configure.in: Revert change from 2005-07-26 that sometimes
- * unix/configure: added $prefix/share to the tcl_pkgPath.
- See [Patch 1231015]. autoconf-2.13.
+2009-01-08 Don Porter <dgp@users.sourceforge.net>
-2006-03-10 Zoran Vasiljevic <vasiljevic@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].
- -- Summary of changes fixing [Bug 1437595] --
+2009-01-06 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclEvent.c: Cosmetic touches and identation
- * generic/tclInt.h: Added TclpFinalizeSockets() call.
+ * generic/tclDictObj.c (DictIncrCmd): Corrected twiddling in internals
+ of dictionaries so that literals can't get destroyed.
- * generic/tclIO.c: Calls TclpFinalizeSockets() as part of the
- TclFinalizeIOSubsystem().
+ * tests/expr.test, tests/string.test: Eliminate non-ASCII characters.
+ [Bugs 2006884, 2006879]
- * unix/tclUnixSock: Added no-op TclpFinalizeSockets().
-
- * mac/tclMacSock.c:
- * win/tclWinPipe.c
- * win/tclWinSock.c: Finalization of the sockets/pipes is now solely
- done in TclpFinalizeSockets() and TclpFinalizePipes() and not over the
- thread-exit handler, because the order of actions the Tcl generic core
- will impose may result in cores/hangs if the thread exit handler tears
- down corresponding subsystem(s) too early.
+2009-01-03 Kevin B. Kenny <kennykb@acm.org>:
-2006-03-10 Vince Darley <vincentdarley@sourceforge.net>
+ * library/clock.tcl (tcl::clock::add): Fixed error message formatting
+ in the case where [clock add] is presented with a bad switch.
+ * tests/clock.test (clock-65.1) Added a test case for the above
+ problem [Bug 2481670].
- * win/tclWin32Dll.c:
- * win/tclWinInt.h:
- * win/tclWinFile.c: backported some fixes from HEAD relating to 'file
- readable' and 'file writable', but main 'file writable' bug still
- outstanding.
+2008-12-21 Don Porter <dgp@users.sourceforge.net>
-2006-03-07 Don Porter <dgp@users.sourceforge.net>
+ *** 8.5.6 TAGGED FOR RELEASE ***
- * README: Bump version number to 8.4.13 and update
- * changes: changes to start prep for an 8.4.13 release.
- * generic/tcl.h:
+ * generic/tcl.h: Bump to 8.5.6 for release.
+ * library/init.tcl:
* tools/tcl.wse.in:
- * unix/configure{.in}:
+ * unix/configure.in:
* unix/tcl.spec:
- * win/README.binary:
- * win/configure{.in}:
-
- * tests/parse.test: Missing constraint
-
-2006-03-06 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclBasic.c: Revised handling of TCL_EVAL_* flags to
- * tests/parse.test: simplify TclEvalObjvInternal and to correct
- the auto-loading of alias targets (parse-8.12). [Bug 1444291]
-
-2006-03-02 Jeff Hobbs <jeffh@ActiveState.com>
-
- * win/Makefile.in: convert _NATIVE paths to use / to avoid ".\"
- path-as-escape issue.
-
- * unix/tcl.m4, win/tcl.m4: []-quote ac_defun functions.
-
-2006-03-02 Pat Thoyts <patthoyts@users.sourceforge.net>
-
- * unix/tcl.m4: Fix for [Tk Bug 1334613] to sort out shared library
- * unix/configure: issues on NetBSD. Regenerated configure script.
-
-2006-02-28 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclBasic.c: Corrections to be sure that TCL_EVAL_GLOBAL
- * tests/parse.test: evaluations act the same as [uplevel #0]
- * tests/trace.test: evaluations, even when execution traces or
- invocations of [::unknown] are present. [Bug 1439836]
-
-2006-02-16 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclIndexObj.c: Disallow the "ambiguous" error message
- * tests/indexObj.test: when TCL_EXACT matching is requested.
-
-2006-02-15 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclIO.c: Made several routines tolerant of
- * generic/tclIOUtil.c: interp == NULL arguments. [Bug 1380662]
-
-2006-02-09 Don Porter <dgp@users.sourceforge.net>
-
- * tests/main.test (Tcl_Main-6.7): Improved robustness of command
- auto-completion test. [Bug 1422736]
-
-2006-01-25 Donal K. Fellows <donal.k.fellows@man.ac.uk>
-
- * unix/tclUnixInit.c (TclpInitPlatform): Improved conditions on when
- to update the FP rounding mode on FreeBSD, taken from FreeBSD port.
+ * win/configure.in:
+ * README:
-2006-01-23 Miguel Sofer <msofer@users.sf.net>
+ * unix/configure: autoconf-2.59
+ * win/configure:
- * generic/tclStringObj.c (Tcl_GetRange):
- * tests/stringTest (string-12.21):fixed incorrect handling of internal
- rep in Tcl_GetRange. Thanks to twylite and Peter Spjuth. [Bug 1410553]
+ * changes: Update for 8.5.6 release.
-2006-01-16 Reinhard Max <max@suse.de>
+ * library/tclIndex: Removed reference to no-longer-extant procedure
+ 'tclLdAout'.
+ * doc/library.n: Corrected mention of 'auto_exec' to 'auto_execok'.
+ [Patch 2114900] thanks to Stu Cassoff <stwo@users.sf.net>
+ Backport of 2008-11-26 commit from Kevin Kenny.
- * generic/tclPipe.c (FileForRedirect): Prevent nameString from being
- freed without having been initialized.
- * tests/exec.test: Added a test for the above.
-
-2006-01-12 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+ * win/tclWinThrd.c (TclpThreadCreate): We need to initialize the
+ thread id variable to 0 as on 64 bit windows this is a pointer sized
+ field while windows only fills it with a 32 bit value. The result is
+ an inability to join the threads as the ids cannot be matched.
+ Backport of 2008-10-13 commit from Pat Thoyts.
- * generic/tclIOUtil.c (Tcl_FSGetInternalRep): fixed potential
- overwriting of already freed memory which caused all kinds of (rare
- but reproducible) coredumps all over the place.
+2008-12-15 Donal K. Fellows <donal.k.fellows@man.ac.uk>
-2006-01-11 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclExecute.c (TEBC:INST_DICT_GET): Make sure that the result
+ is empty when generating an error message. [Bug 2431847]
- * tests/error.test (error-7.0): Test the timing of write traces on
- ::errorInfo. [Bug 1397843]
+2008-12-12 Jan Nijtmans <nijtmans@users.sf.net>
-2006-01-10 Daniel Steffen <das@users.sourceforge.net>
+ * library/clock.tcl (ProcessPosixTimeZone): Fix time change in Eastern
+ Europe (not 3:00 but 4:00 local time) [Bug 2207436]
- * unix/configure: add caching, use AC_CACHE_CHECK instead of
- * unix/configure.in: AC_CACHE_VAL where possible, consistent message
- * unix/tcl.m4: quoting, sync relevant tclconfig/tcl.m4 and HEAD
- changes and gratuitous formatting differences, fix SC_CONFIG_MANPAGES
- with default argument, Darwin improvements to SC_LOAD_*CONFIG.
-
-2006-01-09 Don Porter <dgp@users.sourceforge.net>
+2008-12-11 Andreas Kupries <andreask@activestate.com>
- * generic/tclNamesp.c (NamespaceInscopeCmd): [namespace inscope]
- * tests/namespace.test: commands were not reported by [info level].
- [Bug 1400572]
+ * generic/tclIO.c (SetChannelFromAny and related): Modified the
+ * tests/io.test: internal representation of the tclChannelType to
+ contain not only the ChannelState pointer, but also a reference to the
+ interpreter it was made in. Invalidate and recompute the internal
+ representation when it is used in a different interpreter (like
+ cmdName intrep's). Added testcase. [Bug 2407783]
-2005-12-20 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+2008-12-11 Jan Nijtmans <nijtmans@users.sf.net>
- * generic/tclThreadAlloc.c (Tcl_GetMemoryInfo): Format values as longs
- and not ints, so they are less likely to wrap on 64-bit machines.
+ * library/clock.tcl (ProcessPosixTimeZone): Fallback to European time
+ zone DST rules, when the timezone is between 0 and -12. [Bug 2207436]
+ * tests/clock.test (clock-52.[23]): Test cases.
-2005-12-19 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+2008-12-10 Kevin B. Kenny <kennykb@acm.org>
- * doc/Tcl.n: Clarify what is going on in variable substitution
- following thread on comp.lang.tcl.
+ * library/tzdata/*: Update from Olson's tzdata2008i.
-2005-12-14 Daniel Steffen <das@users.sourceforge.net>
+2008-12-04 Don Porter <dgp@users.sourceforge.net>
- * generic/tclIOUtil.c: workaround gcc warning "comparison is always
- * generic/tclTest.c: false due to limited range of data type".
+ * generic/tclPathObj.c (Tcl_FSGetNormalizedPath): Added another
+ flag value TCLPATH_NEEDNORM to mark those intreps which need more
+ complete normalization attention for correct results. [Bug 2385549]
- * unix/configure.in: run check for fts API on all platforms, since
- Linux glibc2 and *BSDs also have this and using fts is more efficient
- than recursive opendir/readdir (sync with HEAD).
- * unix/configure: regen.
+2008-12-03 Don Porter <dgp@users.sourceforge.net>
-2005-12-12 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclFileName.c (DoGlob): One of the Tcl_FSMatchInDirectory
+ calls did not have its return code checked. This caused error messages
+ returned by some Tcl_Filesystem drivers to be swallowed.
- * unix/tcl.m4, unix/configure: Fix sh quoting error reported in
- bash-3.1+ [Bug 1377619] (schafer)
+2008-12-02 Andreas Kupries <andreask@activestate.com>
-2005-12-12 Reinhard Max <max@suse.de>
+ * generic/tclIO.c (TclFinalizeIOSubsystem): Replaced Alexandre
+ Ferrieux's first patch for [Bug 2270477] with a gentler version, also
+ supplied by him.
- * generic/tclExecute.c (ExprAbsFunc): fixed the abs(MIN_INT) case so
- that it doesn't break on compilers that don't assume integers to wrap
- around (e.g. gcc-4.1.0).
+2008-12-01 Don Porter <dgp@users.sourceforge.net>
-2005-12-09 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+ * generic/tclParse.c: Backport fix for [Bug 2251175].
- * tests/lsearch.test (lsearch-10.8..10): If the -start is off the end,
- * generic/tclCmdIL.c (Tcl_LsearchObjCmd): searching should find
- nothing at all. [Bug 1374778]
+2008-11-30 Kevin B. Kenny <kennykb@acm.org>
-2005-12-05 Daniel Steffen <das@users.sourceforge.net>
+ * library/clock.tcl (format, ParseClockScanFormat): Added a [string
+ map] to get rid of namespace delimiters before caching a scan or
+ format procedure. [Bug 2362156]
+ * tests/clock.test (clock-64.[12]): Added test cases for the bug that
+ was tickled by a namespace delimiter inside a format string.
- *** 8.4.12 TAGGED FOR RELEASE ***
+2008-11-25 Andreas Kupries <andreask@activestate.com>
- * unix/tclUnixPort.h (Darwin): fix incorrect __DARWIN_UNIX03 configure
- overrides that were originally copied from Darwin CVS (rdar://3693001).
+ * generic/tclIO.c (TclFinalizeIOSubsystem): Applied Alexandre
+ Ferrieux's patch for [Bug 2270477] to prevent infinite looping during
+ finalization of channels not bound to interpreters.
-2005-12-05 Don Porter <dgp@users.sourceforge.net>
+2008-08-23 Andreas Kupries <andreask@activestate.com>
- * unix/configure.in: Revised fix for [Bug 1034337] from Daniel
- * unix/tclUnixFCmd.c: Steffen. Uses fts_*() routines.
- * unix/configure: autoconf-2.13
- * changes: Update changes for 8.4.12 release
+ * generic/tclIO.c: Backport of fix for [Bug 2333466].
-2005-12-04 Daniel Steffen <das@users.sourceforge.net>
+2008-11-18 Jan Nijtmans <nijtmans@users.sf.net>
- * README: refer to macosx/README instead of mac/README.
- * mac/README: add note that mac classic port is no longer supported.
+ * generic/tcl.decls: Fix signature and implementation of
+ * generic/tclDecls.h: Tcl_HashStats, such that it conforms
+ * generic/tclHash.c: to the documentation. [Bug 2308236]
+ * doc/Hash.3:
-2005-12-03 Jeff Hobbs <jeffh@ActiveState.com>
+2008-11-13 Jan Nijtmans <nijtmans@users.sf.net>
- * README: correct 2 urls
+ * generic/tclInt.h: Rename static function FSUnloadTempFile to
+ * generic/tclIOUtil.c: TclFSUnloadTempFile, needed in tclLoad.c
-2005-12-01 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclLoad.c: Fixed [Bug 2269431]: load of shared
+ objects leaves temporary files on windows
- * changes: Update changes for 8.4.12 release
+2008-11-10 Andreas Kupries <andreask@activestate.com>
-2005-12-01 Daniel Steffen <das@users.sourceforge.net>
+ * doc/platform_shell.n: Fixed [Bug 2255235], reported by Ulrich
+ * library/platform/pkgIndex.tcl: Ring <uring@users.sourceforge.net>.
+ * library/platform/shell.tcl: Updated the LOCATE command in the
+ * library/tm.tcl: package 'platform::shell' to handle the new form
+ * unix/Makefile.in: of 'provide' commands generated by tm.tcl. Bumped
+ * win/Makefile.in: package to version 1.1.4. Added cross-references
+ to the relevant parts of the code to avoid future desynchronization.
- * unix/tcl.m4 (Darwin): fixed error when MACOSX_DEPLOYMENT_TARGET unset
- * unix/configure: regen.
+2008-11-04 Jeff Hobbs <jeffh@ActiveState.com>
-2005-11-29 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclPort.h: remove the ../win/ header dir as the build system
+ already has it, and it confuses builds when used with private headers
+ installed.
- * win/tcl.m4: Add build support for Windows-x64 builds.
- * win/configure: --enable-64bit now accepts =amd64|ia64 for
- * win/Makefile.in: Windows 64-bit build variants (default: amd64)
- * win/makefile.vc: [Bug 1369597]
+2008-10-24 Pat Thoyts <patthoyts@users.sourceforge.net>
-2005-11-29 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * library/http/http.tcl: Backported a fix for reading HTTP-like
+ protocols that used to work and were broken with http 2.7. Now http
+ 2.7.2
- * generic/tclObj.c (Tcl_GetWideIntFromObj): Add more efficient
- conversion to wides from normal ints. [Bug 1310081]
+2008-10-23 Don Porter <dgp@users.sourceforge.net>
- * generic/tclCmdIL.c (Tcl_LsearchObjCmd): Allow [lsearch -regexp] to
- process REs that contain backreferences. This expensive mode of
- operation is only used if the RE would otherwise cause a compilation
- failure. [Bug 1366683]
+ * generic/tcl.h: Bump version number to 8.5.6b1 to distinguish
+ * library/init.tcl: CVS development snapshots from the 8.5.5 and
+ * unix/configure.in: 8.5.6 releases.
+ * unix/tcl.spec:
+ * win/configure.in:
+ * tools/tcl.wse.in:
+ * README
-2005-11-28 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * unix/configure: autoconf (2.59)
+ * win/configure:
- * win/tclWinSock.c (CreateSocket): Applied [Patch 1353853] to prevent
- reads of uninitialized variables during cleanup.
+2008-10-19 Don Porter <dgp@users.sourceforge.net>
-2005-11-27 Daniel Steffen <das@users.sourceforge.net>
+ * generic/tclProc.c: Reset -level and -code values to defaults
+ after they are used. [Bug 2152286]
- * unix/tcl.m4 (Darwin): add 64bit support, check for Tiger copyfile(),
- add CFLAGS to SHLIB_LD to support passing -isysroot in env(CFLAGS) to
- configure (flag can't be present twice, so can't be in both CFLAGS and
- LDFLAGS during configure), don't use -prebind when deploying on 10.4,
- define TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING (rdar://3171542).
- (SC_ENABLE_LANGINFO, SC_TIME_HANDLER): add/fix caching, fix obsolete
- autoconf macros. Sync with tk/unix/tcl.m4, sync whitespace with HEAD.
+2008-10-16 Don Porter <dgp@users.sourceforge.net>
- * unix/configure.in: fix obsolete autoconf macros, sync gratuitous
- formatting/ordering differences with tk/unix/configure.in.
+ * library/init.tcl: Revised [unknown] so that it carefully
+ preserves the state of the ::errorInfo and ::errorCode variables at
+ the start of auto-loading and restores that state before the
+ autoloaded command is evaluated. [Bug 2140628]
- * unix/Makefile.in: add CFLAGS to tclsh/tcltest link to make
- executable linking the same as during configure (needed to avoid
- loosing any linker relevant flags in CFLAGS, in particular flags that
- can't be in LDFLAGS). Avoid concurrent linking of tclsh and compiling
- of tclTestInit.o or xtTestInit.o during parallel make.
- (checkstubs, checkdoc, checkexports): dependency and Darwin fixes
+2008-10-10 Don Porter <dgp@users.sourceforge.net>
- * unix/tclLoadDyld.c (TclpDlopen): [Bug 1204237] use
- NSADDIMAGE_OPTION_WITH_SEARCHING on second NSAddImage only.
- (TclGuessPackageName): should not be MODULE_SCOPE.
- (TclpLoadMemory): ppc64 and endian (i386) fixes, add support for
- loading universal (fat) bundles from memory.
+ *** 8.5.5 TAGGED FOR RELEASE ***
- * unix/tclUnixPort.h:
- * unix/tclUnixFCmd.c: add support for new Tiger copyfile() API to
- enable copying of xattrs & ACLs by [file copy].
+ * generic/tcl.h: Bump to 8.5.5 for release.
+ * library/init.tcl:
+ * tools/tcl.wse.in:
+ * unix/configure.in:
+ * unix/tcl.spec:
+ * win/configure.in:
- * generic/tcl.h: add Darwin specifc configure overrides for TCL_WIDE
- defines to support fat compiles of ppc and ppc64 at the same time,
- (replaces Darwin CVS fix by emoy, rdar://3693001).
- add/correct location of version numbers in macosx files.
+ * unix/configure: autoconf-2.59
+ * win/configure:
- * generic/tclInt.h: clarify fat compile comment.
+ * changes: Update for 8.5.5 release.
- * unix/tclUnixPort.h: add Darwin specifc configure overrides to
- support fat compiles, where configure runs only once for multiple
- architectures (replaces Darwin CVS fix by emoy, rdar://3693001).
+2008-10-08 Don Porter <dgp@users.sourceforge.net>
- * macosx/tclMacOSXBundle.c:
- * macosx/tclMacOSXNotify.c:
- * unix/tclUnixNotfy.c: fix #include order to support compile time
- * unix/tclUnixPort.h: override of HAVE_COREFOUNDATION in
- tclUnixPort.h when building for ppc64
+ * generic/tclTrace.c: Corrected handling of errors returned by
+ variable traces so that the errorInfo value contains the original
+ error message. [Bug 2151707]
- * macosx/Tcl.pbproj/default.pbxuser (new file):
- * macosx/Tcl.pbproj/jingham.pbxuser:
- * macosx/Tcl.pbproj/project.pbxproj: sync with HEAD.
+ * generic/tclVar.c: Revised implementation of TclObjVarErrMsg so
+ that error message construction does not disturb an existing
+ iPtr->errorInfo that may be in progress.
- * macosx/README: clarification/cleanup, sync with HEAD, document
- universal (fat) builds via CFLAGS (i.e. all of ppc ppc64 i386 at once).
+2008-10-06 Jan Nijtmans <nijtmans@users.sf.net>
- * macosx/Makefile: add support for reusing configure cache, build
- target fixes, remove GENERIC_FLAGS override now handled by tcl.m4.
+ * tclWinTest.c: Fix compiler warning when compiling this file with
+ mingw gcc:
+ tclWinTest.c:706: warning: dereferencing type-punned pointer will
+ break strict-aliasing rules
+ * generic/tclLoad.c: Make sure that any library which doesn't have an
+ unloadproc is only really unloaded when no library code is executed
+ yet. [Bug 2059262]
- * generic/tclIOUtil.c:
- * generic/tclRegexp.c:
- * generic/tclVar.c: declare globals used only in own file as static
- (sync with HEAD).
+2008-10-06 Joe Mistachkin <joe@mistachkin.com>
- * generic/rege_dfa.c (getvacant):
- * generic/regexec.c (cfind):
- * generic/tclCompExpr.c (CompileSubExpr):
- * unix/tclUnixChan.c (TclUnixWaitForFile): initialise variables to
- silence gcc 4 warnings.
+ * tools/man2tcl.c: Added missing line from patch by Harald Oehlmann.
+ [Bug 1934200]
- * generic/regguts.h: only #define NDEBUG if not already #defined.
+2008-10-05 Kevin B. Kenny <kennykb@acm.org>
- * macosx/tclMacOSXNotify.c: sync whitespace & comments with HEAD
+ * libtommath/bn_mp_sqrt.c (bn_mp_sqrt): Handle the case where a
+ * tests/expr.test (expr-47.13): number's square root is
+ between n<<DIGIT_BIT and n<<DIGIT_BIT+1. [Bug 2143288]
+ Thanks to Malcolm Boffey (malcolm.boffey@virgin.net) for the patch.
- * unix/configure: regen.
+2008-10-02 Joe Mistachkin <joe@mistachkin.com>
-2005-11-20 Joe English <jenglish@users.sourceforge.net>
+ * tools/man2help2.tcl: Integrated patches from Harald Oehlmann.
+ * tools/man2tcl.c: [Bug 1934200, 1934272]
- * generic/tclStubLib.c: Don't set tclStubsPtr to 0 when
- Tcl_PkgRequireEx() fails [Fix for [Bug 1091431] "Tcl_InitStubs failure
- crashes wish"]
+2008-09-27 Donal K. Fellows <donal.k.fellows@man.ac.uk>
-2005-11-18 Miguel Sofer <msofer@users.sf.net>
+ * generic/tclCmdIL.c (Tcl_LrepeatObjCmd): Improve the handling of the
+ case where the combination of number of elements and repeat count
+ causes the resulting list to be too large. [Bug 2130992]
- * tests/trace.test (trace-34.5): [Bug 1047286], added a second test
- illustrating the role of "ns in callStack" in the ns's visibility
- during deletion traces.
+2008-09-25 Don Porter <dgp@users.sourceforge.net>
- * generic/tclBasic.c (Tcl_DeleteCommandFromToken):
- * generic/tclCmdMZ.c (TraceCommandProc):
- * generic/tclInt.h (NS_KILLED):
- * generic/tclNamesp.c (Tcl_DeleteNamespace
- * tests/namespace.test (namespace-7.3-6):
- * tests/trace.test (trace-20.13-16): fix [Bugs 1355942/1355342].
+ * doc/global.n: Correct false claim about [info locals].
-2005-11-18 Jeff Hobbs <jeffh@ActiveState.com>
+2008-09-17 Don Porter <dgp@users.sourceforge.net>
- * generic/tclIO.c (TclFinalizeIOSubsystem): preserve statePtr until we
- netrieve next statePtr from it.
+ * generic/tclInt.h: Correct the TclGetLongFromObj,
+ TclGetIntFromObj, and TclGetIntForIndexM macros so that they
+ retrieve the internalRep.longValue field instead of casting the
+ internalRep.otherValuePtr field to type long.
-2005-11-18 Don Porter <dgp@users.sourceforge.net>
+2008-09-17 Miguel Sofer <msofer@users.sf.net>
- * generic/tclPkg.c: Revised Bug 1162286 fix from 2005-11-08 to be
- * tests/pkg.test: more forgiving of package version mismatch
- errors in [package ifneeded] commands. This reduces the
- ***POTENTIAL INCOMPATIBILITY*** noted for that change.
+ * library/init.tcl: export min and max commands from the mathfunc
+ namespace [Bug 2116053]
-2005-11-18 Andreas Kupries <andreask@activestate.com>
+2008-09-10 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * generic/tclIO.c (TclFinalizeIOSubsystem): Applied Pat Thoyts' patch
- for [Bug 1359094]. This moves the retrieval of the next channel state
- to the end of the loop, as the called closeproc may close other
- channels, i.e., modify the list we are iterating, invalidating any
- pointer retrieved earlier.
+ * generic/tclListObj.c (Tcl_ListObjGetElements): Make this list->dict
+ transformation - encountered when using [foreach] with dicts - not as
+ expensive as it was before. Spotted by Kieran Elby and reported on
+ tcl-core.
-2005-11-18 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+2008-09-07 Miguel Sofer <msofer@users.sf.net>
- * library/http/http.tcl (http::geturl): Improved syntactic validation
- of URLs, and better error messages in some cases. [Bug 1358369]
+ * doc/namespace.n: fix [Bug 2098441]
-2005-11-16 Don Porter <dgp@users.sourceforge.net>
+2008-08-28 Don Porter <dgp@users.sourceforge.net>
- * README: Bump version number to 8.4.12
- * generic/tcl.h:
- * tools/tcl.wse.in:
- * unix/configure.in:
+ * generic/tcl.h: Bump version number to 8.5.5b1 to distinguish
+ * library/init.tcl: CVS development snapshots from the 8.5.4 and
+ * unix/configure.in: 8.5.5 releases.
* unix/tcl.spec:
- * win/README.binary:
* win/configure.in:
+ * tools/tcl.wse.in:
+ * README
- * unix/configure: autoconf-2.13
+ * unix/configure: autoconf (2.59)
* win/configure:
-2005-11-15 Don Porter <dgp@users.sourceforge.net>
-
- * changes: Update changes for 8.4.12 release
-
-2005-11-15 Kevin B. Kenny <kennykb@acm.org>
-
- * tests/cmdAH.test: Backported the fix for [Bug 926016] because of
- * win/tclWinFile.c: a repeated bug report in 8.4 [Bug 1353840].
- Windows [file mtime] will now return seconds from the Posix epoch
- correctly (except for FAT32 file systems after a DST change without a
- reboot - for which there is no help). A side effect is that file times
- will appear different in Tcl from the way they do in Windows Explorer
- or a 'dir' listing, because the Microsoft tools get the DST state
- wrong in the listings.
+2008-08-22 Don Porter <dgp@users.sourceforge.net>
-2005-11-09 Kevin B. Kenny <kennykb@acm.org>
+ * generic/tclUtil.c (TclReToGlob): Added missing set of the
+ *exactPtr value to really fix [Bug 2065115]. Also avoid possible
+ DString overflow.
+ * tests/regexpComp.test: Correct duplicate test names.
- * generic/tclTimer.c: Changed [after] so that it behaves correctly
- * tests/timer.test: with negative arguments. [Bug 1350293]
+2008-08-21 Jeff Hobbs <jeffh@ActiveState.com>
-2005-11-08 Jeff Hobbs <jeffh@ActiveState.com>
+ * tests/regexp.test, tests/regexpComp.test: correct re2glob ***=
+ * generic/tclUtil.c (TclReToGlob): translation from exact
+ to anywhere-in-string match. [Bug 2065115]
- * unix/tclUnixFCmd.c (MAX_READDIR_UNLINK_THRESHOLD): reduce to 130
- based on errors seen on OS X 10.3 with lots of links in a dir. [Bug
- 1034337 followup]
+2008-08-20 Daniel Steffen <das@users.sourceforge.net>
-2005-11-08 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclTest.c (TestconcatobjCmd): fix use of internal-only
+ TclInvalidateStringRep macro.
+ [Bug 2057479]
- * tests/expr.test: Portable tests expr-46.13-18 [Bug 1341368]
+2008-08-17 Miguel Sofer <msofer@users.sf.net>
- * generic/tclPkg.c: Corrected inconsistencies in the value returned
- * tests/pkg.test: by Tcl_PkgRequire(Ex) so that the returned
- values will always agree with what is stored in the package database.
- This way repeated calls to Tcl_PkgRequire(Ex) have the same results.
- Thanks to Hemang Lavana. [Bug 1162286]
- ***POTENTIAL INCOMPATIBILITY***: Incompatible with those existing
- packages that are accustomed to the [package] command forgiving
- their bugs.
+ * generic/tclTest.c (TestconcatobjCmd):
+ * generic/tclUtil.c (Tcl_ConcatObj):
+ * tests/util.test (util-4.7):
+ fix [Bug 1447328]; the original "fix" turned Tcl_ConcatObj() into
+ a hairy monster. This was exposed by [Bug 2055782]. Additionally,
+ Tcl_ConcatObj could corrupt its input under certain conditions!
- * tests/namespace.test (25.7,8): Backport test of knownBug.
+ *** NASTY BUG FIXED ***
-2005-11-08 Donal K. Fellows <donal.k.fellows@man.ac.uk>
-
- * generic/tclCmdMZ.c (TclTraceVariableObjCmd, TraceVarProc): Applied
- Miguel's fix for [Bug 1348775]. It is not quite as elegant as the one
- applied to the HEAD, but it is easier to use it rather than fully
- backporting.
-
-2005-11-07 Miguel Sofer <msofer@users.sf.net>
-
- * tests/trace.test (trace-13.2-4): added tests to detect leak, see
- [Bug 1348775].
-
-2005-11-04 Don Porter <dgp@users.sourceforge.net>
-
- * unix/tcl.m4: Added code to enable [load] on LynxOS. Thanks to
- heidibr@users.sf.net for the patch. [Bug 1163896]
+2008-08-14 Don Porter <dgp@users.sourceforge.net>
- * unix/configure: autoconf-2.13.
+ *** 8.5.4 TAGGED FOR RELEASE ***
-2005-11-04 Pat Thoyts <patthoyts@users.sourceforge.net>
+ * tests/fileName.test: Revise new tests for portability to case
+ insensitive filesystems.
- * win/tclWinPipe.c: Applied [Patch 1267871] by Matt Newman which
- * win/tclWinPort.h: provides extended error code support.
- * tests/exec.test: Wrote some tests for this feature.
+2008-08-14 Daniel Steffen <das@users.sourceforge.net>
-2005-11-04 Kevin Kenny <kennykb@acm.org>
+ * generic/tclCompile.h: Add support for debug logging of DTrace
+ * generic/tclBasic.c: 'proc', 'cmd' and 'inst' probes (does
+ _not_ require a platform with DTrace).
- * generic/tclGetDate.y: Added abbreviations for the Korean timezone.
- * generic/tclDate.c: Regenerated.
+ * generic/tclCmdIL.c (TclInfoFrame): Check fPtr->line before
+ dereferencing as line info may
+ not exists when TclInfoFrame()
+ is called from a DTrace probe.
- * compat/strftime.c: Fixed a problem where the name of the time zone
- was double-converted from system encoding to UTF-8. Thanks to the
- anonymous submitter of [Bug 1317477] for the report and the patch.
+ * tests/msgcat.test: Fix for ::tcl::mac::locale with
+ @modifier (HEAD backport 2008-06-01).
-2005-11-04 Miguel Sofer <msofer@users.sf.net>
+ * tests/fCmd.test (fCmd-6.23): Made result matching robust when test
+ workdir and /tmp are not on same FS.
- * generic/tclInt.h:
- * generic/tclNamesp.c:
- * generic/tclVar.c: fix for [Bugs 1338280/1337229]. Thanks Don.
+ * unix/Makefile.in: Ensure Makefile shell is /bin/bash for
+ * unix/configure.in (SunOS): DTrace-enabled build on Solaris.
+ (followup to 2008-06-12) [Bug 2016584]
- * tests/trace.test: fix duplicate test numbers
+ * unix/tcl.m4 (SC_PATH_X): Check for libX11.dylib in addition to
+ libX11.so et al.
-2005-11-03 Don Porter <dgp@users.sourceforge.net>
+ * unix/configure: autoconf-2.59
- * generic/tclUnixInit.c (TclpSetInitialEncodings): Modified so
- that multiple calls can continue to atttempt to properly set the
- system encoding. Needed for Tclkit to properly support non-default
- encodings. Thanks to Yaroslav Schekin. [Bug 1201171]
+2008-08-13 Don Porter <dgp@users.sourceforge.net>
-2005-11-03 Pat Thoyts <patthoyts@users.sourceforge.net>
+ * generic/tclFileName.c: Fix for errors handling -types {}
+ * tests/fileName.test: option to [glob]. [Bug 1750300]
+ Thanks to Matthias Kraft and George Peter Staplin.
- * win/tclWin32Dll.c: Backported Anton Kovalenko's [Patch 1256872]
- * win/tclWinConsole.c: to give unicode console support on
- * win/tclWinInt.h: suitable systems (eg: NT/XP)
+2008-08-12 Don Porter <dgp@users.sourceforge.net>
-2005-11-01 Don Porter <dgp@users.sourceforge.net>
+ * changes: Update for 8.5.4 release.
- * generic/tclCmdMZ.c (TclCheckExecutionTraces): Corrected mistaken
- assumption that all command traces are set at the script level.
- Report/fix from Jacques H. de Villiers. [Bug 1337941]
+2008-08-11 Pat Thoyts <patthoyts@users.sourceforge.net>
- * tests/expr-old.test (expr-32.52): Use int(.) to restrict result
- of left shift to the C long range.
+ * library/http/http.tcl: Remove 8.5 requirement.
+ * library/http/pkgIndex.tcl:
+ * unix/Makefile.in:
+ * win/Makefile.in:
+ * win/makefile.vc:
-2005-10-29 Mo DeJong <mdejong@users.sourceforge.net>
+2008-08-11 Andreas Kupries <andreask@activestate.com>
- * tests/expr.test: Fix problems in new round() tests that lead to
- correct result only on 32 bit long systems. [Bug 1341368]
+ * library/tm.tcl: Added a 'package provide' command to the generated
+ ifneeded scripts of Tcl Modules, for early detection of conflicts
+ between the version specified through the file name and a 'provide'
+ command in the module implementation, if any. Note that this change
+ also now allows Tcl Modules to not provide a 'provide' command at all,
+ and declaring their version only through their filename.
-2005-10-29 Miguel Sofer <msofer@users.sf.net>
+ * generic/tclProc.c (Tcl_ProcObjCmd): Fixed memory leak triggered
+ * tests/proc.test: by procbody::test::proc. See [Bug 2043636]. Added a
+ test case demonstrating the leak before the fix. Fixed a few spelling
+ errors in test descriptions as well.
- * generic/tclCmdMZ.c (TraceVarProc): [Bug 1337229], partial fix.
- Ensure that a second call with TCL_TRACE_DESTROYED does not lead to a
- second call to Tcl_EventuallyFree(). It is still true that that second
- call should not happen, so the bug is not completely fixed.
- * tests/trace.test (test-18.3-4): added tests for [Bugs 1337229 and
- 1338280].
+2008-08-11 Don Porter <dgp@users.sourceforge.net>
-2005-10-27 Mo DeJong <mdejong@users.sourceforge.net>
+ * library/http/http.tcl: Bump http version to 2.7.1 to account
+ * library/http/pkgIndex.tcl: for [Bug 2046486] bug fix. This
+ * unix/Makefile.in: release of http now requires a
+ * win/Makefile.in: dependency on Tcl 8.5 to be able to
+ * win/makefile.bc: use the unsigned formats in the
+ * win/makefile.vc: [binary scan] command.
- * generic/tclExecute.c (ExprRoundFunc): Fix typo where number before
- rounding is compared with smallest integer instead of number after
- rounding. This fix does not change the results of any tests.
- * tests/expr.test: Add round() tests for cases near the min and max
- int values.
- * tests/util.test: Remove pointless warning code about testobj command
+2008-08-11 Pat Thoyts <patthoyts@users.sourceforge.net>
-2005-10-23 Miguel Sofer <msofer@users.sf.net>
+ * library/http/http.tcl: crc field from zlib data should be treated as
+ unsigned for 64bit support [Bug 2046846]
- * generic/tclBasic.c:
- * generic/tclBinary.c:
- * generic/tclCmdAH.c:
- * generic/tclCmdIL.c:
- * generic/tclCmdMZ.c:
- * generic/tclExecute.c:
- * generic/tclLink.c:
- * generic/tclMain.c:
- * generic/tclProc.c:
- * generic/tclScan.c:
- * generic/tclTest.c:
- * generic/tclVar.c:
- * mac/tclMacInit.c:
- * unix/tclUnixInit.c:
- * win/tclWinInit.c: Ensure that the core never calls TclPtrSetVar,
- Tcl_SetVar2Ex, Tcl_ObjSetVar2 or Tcl_SetObjErrorCode with a 0-ref new
- value. It is not possible to handle error returns correctly in that
- case [Bug 1334947], one has the choice of leaking the object in some
- cases, or else risk crashing in some others.
+2008-08-08 Don Porter <dgp@users.sourceforge.net>
-2005-10-22 Miguel Sofer <msofer@users.sf.net>
+ * generic/tcl.h: Bump to 8.5.4 for release.
+ * library/init.tcl:
+ * tools/tcl.wse.in:
+ * unix/configure.in:
+ * unix/tcl.spec:
+ * win/configure.in:
- * generic/tclExecute.c (INST_CONCAT): disable the optimisation for
- wide integers. [Bug 1251791]
+ * unix/configure: autoconf-2.59
+ * win/configure:
-2005-10-14 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+ * changes: Update for 8.5.4 release.
- * generic/tclIO.c (Tcl_ClearChannelHandlers): removed change dated
- 2005-10-04 below. Look into [Bug 1323992] for detailed discussion.
+2008-08-08 Kevin Kenny <kennykb@acm.org>
-2005-10-13 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * library/tzdata/CET:
+ * library/tzdata/MET:
+ * library/tzdata/Africa/Casablanca:
+ * library/tzdata/America/Eirunepe:
+ * library/tzdata/America/Santarem:
+ * library/tzdata/America/Rio_Branco:
+ * library/tzdata/America/Argentina/San_Luis:
+ * library/tzdata/Asia/Karachi:
+ * library/tzdata/Europe/Belgrade:
+ * library/tzdata/Europe/Berlin:
+ * library/tzdata/Europe/Budapest:
+ * library/tzdata/Europe/Sofia:
+ * library/tzdata/Indian/Mauritius: Olson's tzdata2008e.
- * generic/tclCmdAH.c (Tcl_FormatObjCmd): Stop [format] from seeing
- the difference between ints and wides. [Bug 1284178]
+2008-08-06 Don Porter <dgp@users.sourceforge.net>
-2005-10-13 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+ * generic/tclVar.c (TclLookupSimpleVar): Retrieve the number of
+ locals in the localCache from the CallFrame and not from the Proc
+ which may have been mangled by a (broken?) recompile. Backport from
+ the HEAD.
- * generic/tclIO.c (Tcl_ClearChannelHandlers): temporary
- ifdef TCL_THREADS changes done to de-activate pending
- event processing when channel is being closed/cutted.
+2008-08-04 Don Porter <dgp@users.sourceforge.net>
-2005-10-10 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclExecute.c: Stopped faulty double-logging of errors to
+ * tests/execute.test: stack trace when a compile epoch bump triggers
+ fallback to direct evaluation of commands in a compiled script.
+ [Bug 2037338]
- * generic/tclInt.h: ensure MODULE_SCOPE decl
+2008-07-30 Don Porter <dgp@users.sourceforge.net>
-2005-10-07 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclBasic.c: Corrected the timing of when the flag
+ TCL_ALLOW_EXCEPTIONS is tested.
- * unix/tclUnixFCmd.c (TraverseUnixTree): Adjust 2004-11-11 change to
- * tests/fCmd.test (fCmd-20.2): account for NFS special
- files with a readdir rewind threshold. [Bug 1034337]
+2008-07-29 Miguel Sofer <msofer@users.sf.net>
-2005-10-05 Andreas Kupries <andreask@activestate.com>
+ * generic/tclExecute.c: fix [Bug 2030670] that cause
+ TclStackRealloc to panic on rare corner cases. Thx ajpasadyn for
+ diagnose and patch.
- * generic/tclPipe.c (TclCreatePipeline): Fixed [Bug 1109294]. Applied
- the patch provided by David Gravereaux.
+2008-07-28 Andreas Kupries <andreask@activestate.com>
- * doc/CrtChannel.3: Fixed [Bug 1104682], by application of David
- Welton's patch for it, and added a note about wideSeekProc.
+ * generic/tclBasic.c: Added missing ref count when creating an empty
+ string as path (TclEvalEx). In 8.4 the missing code caused panics in
+ the testsuite. It doesn't in 8.5. I am guessing that the code path
+ with the missing the incr-refcount is not invoked any longer. Because
+ the bug in itself is certainly the same.
-2005-10-05 Jeff Hobbs <jeffh@ActiveState.com>
+2008-07-25 Daniel Steffen <das@users.sourceforge.net>
- * tests/env.test (env-6.1):
- * win/tclWinPort.h: define USE_PUTENV_FOR_UNSET 1
- * generic/tclEnv.c (TclSetEnv, TclUnsetEnv): add
- USE_PUTENV_FOR_UNSET to existing USE_PUTENV define to account for
- various systems that have putenv(), but can't unset env vars with it.
- Note difference between Windows and Linux for actually unsetting the
- env var (use of '=').
- Correct the resizing of the environ array. We assume that we are in
- full ownership, but that's not correct. [Bug 979640]
+ * tests/info.test (info-37.0): Add !singleTestInterp constraint;
+ (info-22.8, info-23.0): switch to glob matching to avoid sensitivity
+ to tcltest.tcl line number changes, remove knownBug constraint, fix
+ expected result. [Bug 1605269]
-2005-10-04 Jeff Hobbs <jeffh@ActiveState.com>
+2008-07-25 Andreas Kupries <andreask@activestate.com>
- * win/tclWinSerial.c (SerialSetOptionProc): free argv [Bug 1067708]
+ * tests/info.test: Tests 38.* added, exactly testing the tracking of
+ location for uplevel scripts.
- * tests/http.test: Do not URI encode -._~ according to
- * library/http/http.tcl (init): RFC3986. [Bug 1182373] (aho)
+ * generic/tclCompile.c (TclInitCompileEnv): Reorganized the
+ initialization of the #280 location information to match the flow in
+ TclEvalObjEx to get more absolute contexts.
- * generic/tclIOUtil.c (TclFSNormalizeAbsolutePath): make static
- * generic/tclEncoding.c (TclFindEncodings): make static
+ * generic/tclBasic.c (TclEvalObjEx): Moved the pure-list optimization
+ out of the eval-direct code path to be done always, i.e. even when a
+ compile is requested. This way we do not loose the association between
+ #280 location information and the list elements, if any.
- * unix/tclLoadShl.c (TclpDlopen): use DYNAMIC_PATH on second
- shl_load only. [Bug 1204237]
+2008-07-23 Andreas Kupries <andreask@activestate.com>
-2005-10-04 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+ * tests/info.test: Reordered the tests to have monotonously
+ increasing numbers.
- * generic/tclIO.c (Tcl_ClearChannelHandlers): now deletes any
- outstanding timer for the channel. Also, prevents events still
- in the event queue from triggering on the current channel.
+ * generic/tclBasic.c: Modified TclArgumentGet to reject pure lists
+ * generic/tclCmdIL.c: immediately, without search. Reworked setup
+ * generic/tclCompile.c: of eoFramePtr, doesn't need the line
+ * tests/info.test: information, more sensible to have everything on
+ line 1 when eval'ing a pure list. Updated the users of the line
+ information to special case this based on the frame type (i.e.
+ TCL_LOCATION_EVAL_LIST). Added a testcase demonstrating the new
+ behaviour.
- * generic/tclTimer.c (Tcl_DeleteTimerHandler): bail out early
- if passed NULL argument.
+2008-07-22 Andreas Kupries <andreask@activestate.com>
-2005-09-30 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclBasic.c: Added missing function comments.
- * generic/tclMain.c: Separate encoding conversion of command line
- arguments from list formatting. [Bug 1306162]
+ * generic/tclCompile.c: Made the new TclEnterCmdWordIndex
+ * generic/tclCompile.h: static, and ansified.
-2005-09-27 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * generic/tclBasic.c: Reworked the handling of bytecode literals
+ * generic/tclCompile.c: for #280 to fix the abysmal performance
+ * generic/tclCompile.h: for deep recursion, replaced the linear
+ * generic/tclExecute.c: search through the whole stack with another
+ * generic/tclInt.h: hashtable and simplified the data structure used
+ by the compiler (array instead of hashtable). Incidentially this also
+ fixes the memory leak reported via [Bug 2024937].
- * generic/tclBinary.c (FormatNumber): Factorize out copying of double
- values to a helper to work around ugly broken compiler problems. [Bug
- 1116542]
+2008-07-21 Don Porter <dgp@users.sourceforge.net>
-2005-09-15 Miguel Sofer <msofer@users.sf.net>
+ * tests/encoding.test: Make failing tests pass again. [Bug 1972867]
- * doc/ParseCmd.3: copy/paste fix [Bug 1292427]
+2008-07-21 Andreas Kupries <andreask@activestate.com>
-2005-09-15 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * generic/tclBasic.c: Extended the existing TIP #280 system (info
+ * generic/tclCmdAH.c: frame), added the ability to track the
+ * generic/tclCompCmds.c: absolute location of literal procedure
+ * generic/tclCompile.c: arguments, and making this information
+ * generic/tclCompile.h: available to uplevel, eval, and
+ * generic/tclInterp.c: siblings. This allows proper tracking of
+ * generic/tclInt.h: absolute location through custom (Tcl-coded)
+ * generic/tclNamesp.c: control structures based on uplevel, etc.
+ * generic/tclProc.c:
- * unix/tcl.m4 (SC_TCL_EARLY_FLAGS): Added extra hack to allow Tcl to
- transparently open large files on RHEL 3. [Bug 1287638]
+2008-07-21 Pat Thoyts <patthoyts@users.sourceforge.net>
- * unix/configure: autoconf-2.13
+ * generic/tclFCmd.c: Inodes on windows are unreliable [Bug 2015723]
-2005-09-07 Don Porter <dgp@users.sourceforge.net>
+2008-07-20 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * generic/tclUtf.c (Tcl_UniCharToUtf): Corrected handling of negative
- * tests/utf.test (utf-1.5): Tcl_UniChar input value. Incorrect
- handling was producing byte sequences outside of Tcl's legal internal
- encoding. [Bug 1283976]
+ * generic/tclDictObj.c (SetDictFromAny): Make the list->dict
+ transformation a bit more efficient; modern dicts are ordered and so
+ we can round-trip through lists without needing the string rep at all.
+ * generic/tclListObj.c (SetListFromAny): Make the dict->list
+ transformation not lossy of internal representations and hence more
+ efficient. [Bug 2008248] (ajpasadyn) but using a more efficient patch.
-2005-08-29 Kevin Kenny <kennykb@acm.org>
+2008-07-15 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * generic/tclBasic.c (ExprMathFunc): Restored "round away from zero"
- * tests/expr.test (expr-46.*): behaviour to the "round"
- function. Added test cases for the behavior, including the awkward
- case of a number whose fractional part is 1/2-1/2ulp. [Bug 1275043]
+ * doc/DictObj.3: Fix error in example. [Bug 2016740]
-2005-08-25 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+2008-07-08 Don Porter <dgp@users.sourceforge.net>
- * generic/tclListObj.c (UpdateStringOfList): Stop uncontrolled and
- unsafe crashes from happening when working with very large string
- representations. [Bug 1267380]
+ * generic/tclGet.c: Corrected out of date comments.
-2005-08-17 Jeff Hobbs <jeffh@ActiveState.com>
+2008-07-07 Andreas Kupries <andreask@activestate.com>
- * generic/tclFCmd.c (TclFileMakeDirsCmd): fix to race condition in
- file mkdir (backport from head 2005-06-13) [Bug 1217375]
+ * generic/tclCmdIL.c (InfoFrameCmd): Fixed unsafe idiom of setting the
+ interp result found by Don Porter.
-2005-08-16 Kevin Kenny <kennykb@acm.org>
+2008-07-07 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * generic/tclEvent.c (Tcl_Finalize): Pushed Tcl_FinalizeLoad and
- Tcl_ResetFilesystem down after Tcl_FinalizeThreadAlloc because
- unloading DLLs can't happen while they still own TSD keys.
- (This is a backport of changes made in the HEAD on 2005-08-10.)
+ * doc/regexp.n, doc/regsub.n: Correct examples. [Bug 1982642]
-2005-08-05 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+2008-07-04 Joe English <jenglish@users.sourceforge.net>
- * unix/tclUnixInit.c (localeTable): Solaris uses a non-standard name
- for the cp1251 charset. Thanks to Victor Wagner for reporting this.
- [Bug 1252475]
+ * generic/tclEncoding.c(UtfToUtfProc): Avoid unwanted sign extension
+ when converting incomplete UTF-8 sequences. See [Bug 1908443] for
+ details.
-2005-08-05 Kevin Kenny <kennykb@users.sourceforge.net>
+2008-07-03 Andreas Kupries <andreask@activestate.com>
- * generic/tclExecute.c (TclExecuteByteCode): Fixed a corner case
- * tests/expr.test (expr-38.1): where applying abs to
- MIN_INT failed to promote the result to a wide integer. [Bug 1241572]
+ * generic/tclIORChan.c (InvokeTclMethod): Fixed the memory leak
+ reported in [Bug 1987821]. Thanks to Miguel for the rpeort and Don
+ Porter for tracking the cause down.
-2005-08-04 Don Porter <dgp@users.sourceforge.net>
+2008-07-03 Don Porter <dgp@users.sourceforge.net>
- * generic/tclObj.c: Simplified routines that manage the typeTable.
+ * library/package.tcl: Removed [file readable] testing from
+ [tclPkgUnknown] and friends. We find out soon enough whether a file is
+ readable when we try to [source] it, and not testing before allows us
+ to workaround the bugs on some common filesystems where [file
+ readable] lies to us. [Patch 1969717]
-2005-08-03 Don Porter <dgp@users.sourceforge.net>
+2008-06-29 Don Porter <dgp@users.sourceforge.net>
- * generic/tclCompExpr.c: Untangled some dependencies in the
- * generic/tclEvent.c: order of finalization routines.
- * generic/tclInt.h: [Bug 1251399]
- * generic/tclObj.c:
+ *** 8.5.3 TAGGED FOR RELEASE ***
-2005-07-30 Daniel Steffen <das@users.sourceforge.net>
+ * generic/tcl.h: Bump to 8.5.3 for release.
+ * library/init.tcl:
+ * tools/tcl.wse.in:
+ * unix/configure.in:
+ * unix/tcl.spec:
+ * win/configure.in:
- * unix/configure, unix/tcl.m4: revert 2005-07-28 change.
+ * unix/configure: autoconf-2.59
+ * win/configure:
- * unix/tclLoadDyld.c (TclpDlopen, TclpLoadMemory): workarounds for
- bugs/changes in behaviour in Mac OS X 10.4 Tiger, sync formatting
- changes from HEAD.
+ * doc/ObjectType.3: Updated documentation of the Tcl_ObjType
+ struct to match expectations of Tcl 8.5 [Bug 1917650].
-2005-07-29 Donal K. Fellows <dkf@users.sf.net>
+ * generic/tclPathObj.c: Plug memory leak in [Bug 1999176] fix. Thanks
+ Rolf Ade for detecting.
- * generic/tclCmdIL.c (InfoGlobalsCmd): Even in high-speed mode, still
- have to take care with non-existant variables. [Bug 1247135]
+2008-06-28 Don Porter <dgp@users.sourceforge.net>
-2005-07-28 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tclPathObj.c: Plug memory leak in [Bug 1972879] fix. Thanks
+ Rolf Ade for detecting and Dan Steffen for the fix [Bug 2004654].
- * win/README: Update link to msys_mingw8.zip. Remove old Cygwin +
- Mingw info, people should just build with the msys + mingw
- configuration.
+2008-06-26 Andreas Kupries <andreask@activestate.com>
-2005-07-28 Jeff Hobbs <jeffh@ActiveState.com>
+ * unix/Makefile.in: Followup to my change of 2008-06-25, make code
+ generated by the Makefile and put into the installd tm.tcl conditional
+ on interpreter safeness as well. Thanks to Daniel Steffen for
+ reminding me of that code.
- * unix/configure, unix/tcl.m4: defined TCL_LOAD_FROM_MEMORY on Darwin
- only for SHARED_BUILD
+2008-06-25 Don Porter <dgp@users.sourceforge.net>
-2005-07-28 Donal K. Fellows <dkf@users.sf.net>
+ * changes: Update for 8.5.3 release.
- * generic/tclPipe.c (TclCreatePipeline): Arrange for POSIX systems to
- * unix/tclUnixPipe.c (TclpOpenFile): use the O_APPEND flag for
- * tests/exec.test (exec-19.1): files opened in a pipeline
- like ">>this". Note that Windows cannot support such access; there is
- no equivalent flag on the handle that can be set at the kernel-call
- level. The test is unix-specific in every way. [Bug 1245953]
+2008-06-25 Andreas Kupries <andreask@activestate.com>
-2005-07-26 Mo DeJong <mdejong@users.sourceforge.net>
+ * library/tm.tcl: Modified the handling of Tcl Modules and of the
+ * library/safe.tcl: Safe Base to interact nicely with each other,
+ * library/init.tcl: enabling requiring Tcl Modules in safe
+ * tests/safe.test: interpreters. Fixes [Bug 1999119].
- * unix/configure: Regen.
- * unix/configure.in: Check for a $prefix/share directory and add it
- the the package if found. This will check for Tcl packages in
- /usr/local/share when Tcl is configured with the default dist install.
- [Patch 1231015]
+2008-06-25 Pat Thoyts <patthoyts@users.sourceforge.net>
-2005-07-26 Don Porter <dgp@users.sourceforge.net>
+ * win/rules.vc: Backported fix for dde/registry versions and
+ * win/makefile.vc: the staticpkg build option
- * doc/tclvars.n: Improved $errorCode documentation. [RFE 776921]
+2008-06-24 Don Porter <dgp@users.sourceforge.net>
- * generic/tclBasic.c (Tcl_CallWhenDeleted): Converted to use
- per-thread counter, rather than a process global one that required
- mutex protection. [RFE 1077194]
+ * generic/tclPathObj.c: Fixed some internals management in the "path"
+ Tcl_ObjType for the empty string value. Problem led to a crash in the
+ command [glob -dir {} a]. [Bug 1999176].
- * generic/tclNamesp.c (TclTeardownNamespace): Re-ordering so that
- * tests/trace.test (trace-34.4): command delete traces fire
- while the command still exists. [Bug 1047286]
+2008-06-23 Don Porter <dgp@users.sourceforge.net>
-2005-07-24 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tclPathObj.c: Fixed bug in Tcl_GetTranslatedPath() when
+ operating on the "Special path" variant of the "path" Tcl_ObjType
+ intrep. A full normalization was getting done, in particular, coercing
+ relative paths to absolute, contrary to what the function of
+ producing the "translated path" is supposed to do. [Bug 1972879]
- * unix/tcl.m4 (SC_PROG_TCLSH, SC_BUILD_TCLSH):
- * win/tcl.m4 (SC_PROG_TCLSH, SC_BUILD_TCLSH):
- Split confused search for tclsh on PATH and build and install
- locations into two macros. SC_PROG_TCLSH searches just the PATH.
- SC_BUILD_TCLSH determines the name of the tclsh executable in the Tcl
- build directory. [Bug 1160114], [Patch 1244153]
+2008-06-19 Don Porter <dgp@users.sourceforge.net>
-2005-07-22 Don Porter <dgp@users.sourceforge.net>
+ * changes: Update for 8.5.3 release.
- * library/auto.tcl: Updates to the Tcl script library to make
- * library/history.tcl: use of Tcl 8.4 feautures. Thanks to
- * library/init.tcl: Patrick Fradin for prompting on this.
- * library/package.tcl: [Patch 1237755]
- * library/safe.tcl:
- * library/word.tcl:
+ * generic/tclInterp.c: Fixed completely boneheaded mistake that
+ * tests/interp.test: [interp bgerror $slave] and [$slave bgerror]
+ would always act like [interp bgerror {}]. [Bug 1999035]
-2005-07-07 Jeff Hobbs <jeffh@ActiveState.com>
+ * tests/chanio.test: Corrected flawed tests revealed by a -debug 1
+ * tests/event.test: -singleproc 1 test suite run.
+ * tests/io.test:
- * unix/tcl.m4, unix/configure: Backported [Bug 1095909], removing
- * unix/tclUnixPort.h: any use of readdir_r as it is not
- * unix/tclUnixThrd.c: necessary and just confuses things.
+2008-06-19 Don Porter <dgp@users.sourceforge.net>
-2005-07-05 Don Porter <dgp@users.sourceforge.net>
+ * changes: Updates for 8.5.3 release.
- * generic/tclCmdAH.c: New "encoding" Tcl_ObjType (not registered)
- * generic/tclEncoding.c: that permits longer lifetimes of the
- * generic/tclInt.h: Tcl_Encoding values kept as intreps of
- Tcl_Obj's. Reduces the need for repeated reading of encoding
- definition files from the filesystem. [Bug 1077262]
+2008-06-17 Andreas Kupries <andreask@activestate.com>
- * generic/tclNamesp.c: Allow for [namespace import] of a command
- * tests/namespace.test: over a previous [namespace import] of itself
- without throwing an error. [RFE 1230597]
+ * generic/tclClock.c (ClockConvertlocaltoutcObjCmd): Removed left
+ over debug output.
-2005-07-01 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+2008-06-17 Andreas Kupries <andreask@activestate.com>
- * unix/tclUnixNotfy.c: protect against spurious wake-ups while waiting
- on the condition variable when tearing down the notifier thread. [Bug
- 1222872]
+ * doc/tm.n: Followup to changelog entry 2008-03-18 regarding
+ ::tcl::tm::Defaults. Updated the documentation to not only mention
+ the new (underscored) form of environment variable names, but make
+ it the encouraged form as well. See [Bug 1914604].
-2005-06-27 Don Porter <dgp@users.sourceforge.net>
+2008-06-17 Kevin Kenny <kennykb@acm.org>
- *** 8.4.11 TAGGED FOR RELEASE ***
+ * generic/tclClock.c (ConvertLocalToUTC):
+ * tests/clock.test (clock-63.1): Fixed a bug where the
+ internal ConvertLocalToUTC command segfaulted if passed a
+ dictionary without the 'localSeconds' key. To the best of
+ my knowledge, the bug was not observable in the [clock]
+ command itself.
- * library/auto.tcl: Reverted to Revision 1.12.2.3 (Tcl 8.4.9).
- Restores the (buggy) behavior of [auto_reset] that fails to clear
- away auto-loaded commands from non-global namespaces. Fixing this
- bug exposed an unknown number of buggy files out there (including at
- least portions of the Tk script library) that cannot tolerate double
- [source]-ing. The burden of fixing these exposed bugs will not be
- forced on package/extension/application authors until Tcl 8.5.
+2008-06-16 Andreas Kupries <andreask@activestate.com>
-2005-06-24 Kevin Kenny <kennykb@acm.org>
+ * generic/tclCmdIL.c (TclInfoFrame): Backport of fix made on the
+ * tests/info.test: head branch :: Moved the code looking up the
+ information for key 'proc' out of the TCL_LOCATION_BC branch to
+ after the switch, this is common to all frame types. Updated the
+ testsuite to match. This was exposed by the 2008-06-08 commit
+ (Miguel), switching uplevel from direct eval to compilation. Fixes
+ [Bug 1987851].
- * generic/tclEvent.c (Tcl_Finalize):
- * generic/tclInt.h:
- * generic/tclPreserve.c (TclFinalizePreserve): Changed the
- finalization logic so that Tcl_Preserve finalizes after exit
- handlers run; a lot of code called from Tk's exit handlers
- presumes tha Tcl_Preserve will still work even from an exit
- handler. Also, made the assertion check that no exit handlers
- are created in Tcl_Finalize conditional on TCL_MEM_DEBUG to
- avoid spurious panics in the "stable" release.
+2008-06-12 Daniel Steffen <das@users.sourceforge.net>
-2005-06-24 Don Porter <dgp@users.sourceforge.net>
+ * unix/Makefile.in: add complete deps on tclDTrace.h.
- * library/auto.tcl: Make file safe to re-[source] without
- destroying registered auto_mkindex_parser hooks.
+ * unix/Makefile.in: clean generated tclDTrace.h file.
+ * unix/configure.in (SunOS): fix static DTrace-enabled build.
-2005-06-23 Daniel Steffen <das@users.sourceforge.net>
+ * unix/tcl.m4 (SunOS-5.11): fix 64bit amd64 support with gcc & Sun cc.
+ * unix/configure: autoconf-2.59
- * tools/tcltk-man2html.tcl: fixed useversion glob pattern to accept
- multi-digit patchlevels.
+ * macosx/Tcl.xcodeproj/project.pbxproj: add debug configs with gcov,
+ and with corefoundation disabled; updates and cleanup for Xcode 3.1 and
+ for Leopard.
+ * macosx/Tcl.xcode/project.pbxproj: sync Tcl.xcodeproj changes.
+ * macosx/README: document new build configs.
-2005-06-23 Kevin Kenny <kennykb@acm.org>
+2008-05-26 Jeff Hobbs <jeffh@ActiveState.com>
- * win/tclWinChan.c: More rewriting of __asm__ blocks that
- * win/tclWinFCmd.c: implement SEH in GCC, because mingw's
- gcc 3.4.2 is not as forgiving of violations committed by
- the old code and caused panics. [Bug 1225957]
+ * tests/io.test (io-53.9): need to close chan before removing file.
-2005-06-23 Daniel Steffen <das@users.sourceforge.net>
+2008-05-23 Andreas Kupries <andreask@activestate.com>
- * unix/Makefile.in (install-private-headers): rewrite tclPort.h when
- installing private headers to remove ../unix relative #include path to
- tclUnixPort.h (which is incorrect at the installed location).
+ * win/tclWinChan.c (FileWideSeekProc): Accepted a patch by
+ Alexandre Ferrieux <ferrieux@users.sourceforge.net> to fix the
+ [Bug 1965787]. 'tell' now works for locations > 2 GB as well
+ instead of going negative.
-2005-06-22 Kevin Kenny <kennykb@acm.org>
+ * generic/tclIO.c (Tcl_SetChannelBufferSize): Accepted a patch by
+ * tests/io.test: Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+ * tests/chanio.test: to fix the [Bug 1969953]. Buffersize outside
+ of the supported range are now clipped to nearest boundary instead
+ of ignored.
- * generic/tclInt.h: Changed the finalization
- * generic/tclEvent.c (Tcl_Finalize): logic to defer the
- * generic/tclIO.c (TclFinalizeIOSubsystem): shutdown of the pipe
- * unix/tclUnixPipe.c (TclFinalizePipes): management until after
- * win/tclWinPipe.c (TclFinalizePipes): all channels have been
- closed, in order to avoid a situation where the Windows
- PipeCloseProc2 would re-establish the exit handler after exit
- handlers had already run, corrupting the heap. [Bug 1225727]
- Corrected a read of uninitialized memory in PipeCloseProc2, which (at
- least on certain configurations) caused a great number of tests to
- either fail or hang. [Bug 1225044]
+2008-05-22 Don Porter <dgp@users.sourceforge.net>
-2005-06-22 Andreas Kupries <andreask@activestate.com>
+ * generic/tclNamesp.c (Tcl_LogCommandInfo): Restored ability to
+ handle the argument value length = -1. Thanks to Chris Darroch for
+ discovering the bug and providing the fix. [Bug 1968245].
- * generic/tclInt.h: Followup to change made on 2005-06-18 by Daniel
- Steffen. There are compilers (*) who error out on the redefinition of
- WORDS_BIGENDIAN. We have to undef the previous definition (on the
- command line) first to make this acceptable. (*): AIX native.
+2008-05-21 Don Porter <dgp@users.sourceforge.net>
-2005-06-22 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclParse.c (ParseComment): The new TclParseAllWhiteSpace
+ * tests/parse.test (parse-15.60): routine has no mechanism to
+ return the "incomplete" status of "\\\n" so calling this routine
+ anywhere that can be reached within a Tcl_ParseCommand call is a
+ mistake. In particular, ParseComment must not use it. [Bug 1968882]
- * win/tclWinFile.c: Potential buffer overflow. [Bug 1225571]
- Thanks to Pat Thoyts for discovery and fix.
+2008-05-21 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * tests/safe.test: Backport performance improvement from
- reduced $::auto_path.
+ * generic/tclNamesp.c (Tcl_SetNamespaceUnknownHandler): Corrected odd
+ logic for handling installation of namespace unknown handlers which
+ could lead too very strange things happening in the error case.
-2005-06-21 Pat Thoyts <patthoyts@users.sourceforge.net>
+2008-05-16 Miguel Sofer <msofer@users.sf.net>
- * tests/winDde.test: Added some waits to the dde server script to
- let event processing run after we create the dde server and before
- we exit the server process. This avoids 'server did not respond'
- errors.
+ * generic/tclCompile.c: Fix crash with tcl_traceExec. Found and
+ fixed by Alexander Pasadyn [Bug 1964803].
-2005-06-21 Kevin Kenny <kennykb@acm.org>
+2008-05-07 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * generic/tclFileName.c: Corrected a problem where a directory name
- containing a colon can crash the process on Windows [Bug 1194458]
- * tests/fileName.test: Added test for [file split] and [file join]
- with a name containing a colon.
- * win/tclWinPipe.c: Reverted davygrvy's changes of 2005-04-19;
- they cause multiple failures in io.test. [Bug 1225044, still open]
+ * generic/tclCompCmds.c (TclCompileDictAppendCmd): Fix silly
+ off-by-one error that caused a crash every time a compiled 'dict
+ append' with more than one value argument was used. Found by Colin
+ McCormack.
-2005-06-21 Don Porter <dgp@users.sourceforge.net>
+2008-04-26 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
- * generic/tclBasic.c: Made the walk of the active trace list aware
- * generic/tclCmdMZ.c: of the direction of trace scanning, so the
- * generic/tclInt.h: proper correction can be made. [Bug 1224585]
- * tests/trace.test (trace-34.2,3):
+ * generic/tclAsync.c: Tcl_AsyncDelete(): panic if attempt to locate
+ handler token fails. Happens when some other thread attempts to delete
+ somebody else's token.
- * generic/tclBasic.c (Tcl_DeleteTrace): Added missing walk of the
- * tests/trace.test (trace-34.1): list of active traces to
- cleanup references to traces being deleted. [Bug 1201035]
+ Also, panic early if we find out the wrong thread attempting to delete
+ the async handler (common trap). As, only the one that created the
+ handler is allowed to delete it.
-2005-06-20 Don Porter <dgp@users.sourceforge.net>
+2008-04-24 Andreas Kupries <andreask@activestate.com>
- * doc/FileSystem.3: added missing Tcl_GlobTypeData documentation [Bug
- 935853]
+ * tests/ioCmd.test: Extended testsuite for reflected channel
+ implementation. Added test cases about how it handles if the rug is
+ pulled out from under a channel (= killing threads, interpreters
+ containing the tcl command for a channel, and channel sitting in a
+ different interpreter/thread.)
-2005-06-18 Daniel Steffen <das@users.sourceforge.net>
+ * generic/tclIORChan.c: Fixed the bugs exposed by the new testcases,
+ redone most of the cleanup and exit handling.
- * generic/tclInt.h: ensure WORDS_BIGENDIAN is defined correctly with
- fat compiles on Darwin (i.e. ppc and i386 at the same time), the
- configure AC_C_BIGENDIAN check is not sufficient in this case because
- a single run of the compiler builds for two architectures with
- different endianness.
+2008-04-15 Andreas Kupries <andreask@activestate.com>
- * unix/tcl.m4 (Darwin): add -headerpad_max_install_names to LDFLAGS to
- ensure we can always relocate binaries with install_name_tool.
+ * generic/tclIO.c (CopyData): Applied another patch by Alexandre
+ * io.test (io-53.8a): Ferrieux <ferrieux@users.sourceforge.net>,
+ * chanio.test (chan-io-53.8a): to shift EOF handling to the async
+ part of the command if a callback is specified, should the channel
+ be at EOF already when fcopy is called. Testcase by myself.
- * unix/configure: autoconf-2.13
+2008-04-14 Kevin B. Kenny <kennykb@acm.org>
-2005-06-18 Don Porter <dgp@users.sourceforge.net>
+ * unix/tclUnixTime.c (NativeGetTime): Removed obsolete use of
+ 'struct timezone' in the call to 'gettimeofday'. [Bug 1942197].
+ * tests/clock.test (clock-33.5, clock-33.5a, clock-33.8, clock-33.8a):
+ Added comments to the test that it can fail on a heavily loaded
+ system.
- * changes: Update changes for 8.4.11 release
+2008-04-11 Don Porter <dgp@users.sourceforge.net>
- * README: Bump version number to 8.4.11
- * generic/tcl.h:
- * tools/tcl.wse.in:
- * unix/configure.in:
+ * generic/tcl.h: Bump version number to 8.5.3b1 to distinguish
+ * library/init.tcl: CVS development snapshots from the 8.5.2 and
+ * unix/configure.in: 8.5.3 releases.
* unix/tcl.spec:
- * win/README.binary:
* win/configure.in:
+ * README
- * unix/configure: autoconf
+ * unix/configure: autoconf (2.59)
* win/configure:
-2005-06-18 Donal K. Fellows <donal.k.fellows@man.ac.uk>
-
- * generic/tclCmdAH.c (Tcl_FormatObjCmd): Fix for [Bug 1154163]; only
- * tests/format.test: insert 'l' modifier when it is needed.
-
-2005-06-07 Donal K. Fellows <donal.k.fellows@man.ac.uk>
-
- * unix/tclUnixNotfy.c (Tcl_FinalizeNotifier): Add dummy variable
- so threaded build compiles.
-
-2005-06-06 Kevin B. Kenny <kennykb@acm.org>
-
- * win/tclWin32Dll.c: Corrected another buglet in the assembly code for
- stack probing on Win32/gcc. [Bug 1213678]
-
-2005-06-03 Daniel Steffen <das@users.sourceforge.net>
-
- *** 8.4.10 TAGGED FOR RELEASE ***
-
- * unix/tclLoadDyld.c: fixed header conflict when building this file
- with USE_TCL_STUBS.
-
- * macosx/Makefile: fixed 'embedded' target.
+2008-04-10 Andreas Kupries <andreask@activestate.com>
-2005-06-02 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclIOCmd.c (Tcl_FcopyObjCmd): Keeping check for negative
+ values, changed to not be an error, but behave like the special
+ value -1 (copy all, default).
- * unix/Makefile.in (html): add BUILD_HTML_FLAGS optional var
- * tools/tcltk-man2html.tcl: add a --useversion to prevent
- confusion when multiple Tcl source dirs exist.
+ * tests/iocmd.test (iocmd-15.{12,13}): Removed.
- * changes: updated for 8.4.10 release (porter)
+ * tests/io.test (io-52.5{,a,b}): Reverted last change, added
+ * tests/chanio.test (chan-io-52.5{,a,b}): comment regarding the
+ meaning of -1, added two more testcases for other negative values,
+ and input wrapped to negative.
-2005-05-31 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+2008-04-09 Andreas Kupries <andreask@activestate.com>
- * unix/tclUnixNotfy.c: the notifier thread is now created as
- joinable thread and it is properly joined in Tcl_FinalizeNotifier.
- This is an attempt to fix [Bug 1082283]
+ * tests/chanio.test (chan-io-52.5): Removed '-size -1' from test,
+ * tests/io.test (io-52.5): does not seem to have any bearing, and
+ was an illegal value.
-2005-05-29 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclIOCmd.c (Tcl_FcopyObjCmd): Added checking of -size
+ * tests/ioCmd.test (iocmd-15.{13,14}): value to reject negative
+ values, and values overflowing 32-bit signed. [Bug 1557855]. Basic
+ patch by Alexandre Ferrieux <ferrieux@users.sourceforge.net>, with
+ modifications from me to separate overflow from true negative
+ value. Extended testsuite.
- * win/tclWinThrd.c (TclpFinalizeThreadData): move tlsKey defn
- to top of file and clarify name (was 'key'). [Bug 1204064]
+2008-04-08 Andreas Kupries <andreask@activestate.com>
-2005-05-27 Jeff Hobbs <jeffh@ActiveState.com>
+ * tests/io.test (io-53.8): Fixed ordering of vwait and after
+ cancel. cancel has to be done after the vwait completes.
- * README: Bumped patchlevel to 8.4.10
- * generic/tcl.h:
- * tools/tcl.wse.in:
- * unix/tcl.spec, unix/configure, unix/configure.in:
- * win/configure, win/configure.in:
+2008-04-09 Daniel Steffen <das@users.sourceforge.net>
-2005-05-26 Daniel Steffen <das@users.sourceforge.net>
+ * tests/chanio.test (chan-io-53.8,53.9,53.10): fix typo & quoting for
+ * tests/io.test (io-53.8,53.9,53.10): spaces in builddir path
- * macosx/Makefile: moved & corrected EMBEDDED_BUILD check.
+2008-04-07 Andreas Kupries <andreask@activestate.com>
- * unix/configure.in: corrected framework finalization to softlink
- stub library to Versions/8.x subdir instead of Versions/Current.
- * unix/configure: autoconf-2.13
+ * tests/io.test (io-53.10): Testcase for bi-directionaly fcopy.
+ * tests/chanio.test:
+ * generic/tclIO.c: Additional changes to data structures for fcopy
+ * generic/tclIO.h: and channels to perform proper cleanup in case
+ of a channel having two background copy operations running as is
+ now possible.
-2005-05-25 Jeff Hobbs <jeffh@ActiveState.com>
+ * tests/io.test (io-53.10): Testcase for bi-directionaly fcopy.
+ * generic/tclIO.c: Additional changes to data structures for fcopy
+ and channels to perform proper cleanup in case of a channel having
+ two background copy operations running as is now possible.
- * generic/tclCmdMZ.c (Tcl_TimeObjCmd): add necessary cast
+2008-04-07 Andreas Kupries <andreask@activestate.com>
- * unix/configure, unix/configure.in: ensure false Tcl.framework is
- only created with --enable-framework
+ * generic/tclIO.c (BUSY_STATE, CheckChannelErrors,
+ TclCopyChannel): New macro, and the places using it. This change
+ allows for bi-directional fcopy on channels. [Bug 1350564]. Thanks
+ to Alexandre Ferrieux <ferrieux@users.sourceforge.net> for the
+ patch.
-2005-05-24 Daniel Steffen <das@users.sourceforge.net>
+2008-04-07 Reinhard Max <max@suse.de>
- * tests/env.test: added DYLD_FRAMEWORK_PATH to the list of env vars
- that need to be handled specially.
+ * generic/tclStringObj.c (Tcl_AppendFormatToObj): Fix [format {% d}]
+ so that it behaves the same way as in 8.4 and as C's printf().
+ * tests/format.test: Add a test for '% d' and '%+d'.
- * macosx/Makefile:
- * macosx/README:
- * macosx/Tcl-Info.plist.in (new file):
- * unix/Makefile.in:
- * unix/configure.in:
- * unix/tcl.m4:
- * unix/tclUnixInit.c: moved all Darwin framework build support from
- macosx/Makefile into the standard unix configure/make buildsystem, the
- macosx/Makefile is no longer required to build Tcl.framework (but its
- functionality is still available for backwards compatibility).
- * unix/configure: autoconf-2.13
+2008-04-05 Kevin B. Kenny <kennykb@acm.org>
- * generic/tclIOUtil.c (TclLoadFile):
- * generic/tclInt.h:
- * unix/tcl.m4:
- * unix/tclLoadDyld.c: added support for [load]ing .bundle binaries in
- addition to .dylib's: .bundle's can be [unload]ed (unlike .dylib's),
- and can be [load]ed from memory, e.g. directly from VFS without
- needing to be written out to a temporary location first. [Bug 1202209]
- * unix/configure: autoconf-2.13
+ * tests/chanio.test (chan-io-53.9):
+ * tests/io.test (io-53.9): Made test cleanup robust against the
+ possibility of slow process shutdown on Windows.
+
+ * win/tcl.m4: Added -D_CRT_SECURE_NO_DEPRECATE and
+ -DCRT_NONSTDC_NO_DEPRECATE to the MSVC compilation flags so that
+ the compilation doesn't barf on perfectly reasonable Posix system
+ calls.
+ * win/configure: Manually patched (don't have the right autoconf
+ to hand).
+
+ * win/tclWinFile.c: (WinSymLinkDirectory): Fixed a problem that
+ Tcl was creating an NTFS junction point (IO_REPARSE_TAG_MOUNT_POINT)
+ but filling in the union member for a Vista symbolic link. We had
+ gotten away with this error because the union member
+ (SymbolicLinkReparseBuffer) was misdefined in this file and in the
+ 'winnt.h' in early versions of MinGW. MinGW 3.4.2 has the correct
+ definition of SymbolicLinkReparseBuffer, exposing the mismatch,
+ and making tests cmdAH-19.4.1, fCmd-28.*, and filename-11.* fail.
- * generic/tclCmdMZ.c (Tcl_TimeObjCmd): change [time] called with a
- count > 1 to return a string with a float value instead of a rounded
- off integer. [Bug 1202178]
+2008-04-04 Andreas Kupries <andreask@activestate.com>
-2005-05-20 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+ * tests/io.test (io-53.9): Added testcase for [Bug 780533], based
+ * tests/chanio.test: on Alexandre's test script. Also fixed
+ problem with timer in preceding test, was not canceled properly in
+ the ok case.
- * generic/tclParseExpr.c: removed unreferenced stack variable "errMsg"
- probably included by fixing [Bug 1201589] (see below).
+2008-04-04 Andreas Kupries <andreask@activestate.com>
-2005-05-20 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclIORChan.c (ReflectOutput): Allow zero return from
+ write when input was zero-length anyway. Otherwise keept it an
+ error, and separate the message from 'written too much'.
- * generic/tclParseExpr.c: Corrected parser to recognize all
- boolean literals accepted by Tcl_GetBoolean, including prefixes like
- "y" and "f", and to allow "eq" and "ne" as function names in the
- proper context. [Bug 1201589]
+ * tests/ioCmd.test (iocmd-24.6): Testcase updated for changed
+ message.
-2005-05-19 Daniel Steffen <das@users.sourceforge.net>
+ * generic/tclIORChan.c (ReflectClose): Added missing removal of
+ the now closed channel from the reflection map. Before we could
+ crash the system by invoking 'chan postevent' on a closed
+ reflected channel, dereferencing the dangling pointer in the map.
- * macosx/tclMacOSXNotify.c (Tcl_InitNotifier): fixed crashing
- CFRelease of runLoopSource in Tcl_InitNotifier (reported by Zoran):
- CFRunLoopAddSource doesn't CFRetain, so can only CFRelease the
- runLoopSource in Tcl_FinalizeNotifier.
+ * tests/ioCmd.test (iocmd-31.8): Testcase for the above.
-2005-05-14 Daniel Steffen <das@users.sourceforge.net>
+2008-04-03 Andreas Kupries <andreask@activestate.com>
- * macosx/tclMacOSXBundle.c:
- * unix/tclUnixInit.c:
- * unix/tcl.m4 (Darwin): made use of CoreFoundation API configurable
- and added test of CoreFoundation availablility to allow building on
- ppc64, replaced HAVE_CFBUNDLE by HAVE_COREFOUNDATION; test for
- availability of Tiger or later OSSpinLockLock API.
+ * generic/tclIO.c (CopyData): Applied patch [Bug 1932639] to
+ * tests/io.test: prevent fcopy from calling -command synchronously
+ * tests/chanio.test: the first time. Thanks to Alexandre Ferrieux
+ <ferrieux@users.sourceforge.net> for report and patch.
- * unix/tclUnixNotfy.c:
- * unix/Makefile.in:
- * macosx/tclMacOSXNotify.c (new file): when CoreFoundation is
- available, use new CFRunLoop based notifier: allows easy integration
- with other event loops on Mac OS X, in particular the TkAqua Carbon
- event loop is now integrated via a standard tcl event source (instead
- of TkAqua upon loading having to finalize the exsting notifier and
- replace it with its custom version). [Patch 1202052]
+2008-04-02 Andreas Kupries <andreask@activestate.com>
- * tests/unixNotfy.test: don't run unthreaded tests on Darwin since
- notifier may be using threads even in unthreaded core.
+ * generic/tclIO.c (CopyData): Applied patch for the fcopy problem
+ [Bug 780533], with many thanks to Alexandre Ferrieux
+ <ferrieux@users.sourceforge.net> for tracking it down and
+ providing a solution. Still have to convert his test script into a
+ proper test case.
- * unix/tclUnixPort.h:
- * unix/tcl.m4 (Darwin): test for thread-unsafe realpath durning
- configure, as Darwin 7 and later realpath is threadsafe.
+2008-04-01 Andreas Kupries <andreask@activestate.com>
- * macosx/tclMacOSXBundle.c:
- * unix/tclLoadDyld.c:
- * unix/tclUnixInit.c: fixed gcc 4.0 warnings.
+ * generic/tclStrToD.c: Applied patch for [Bug 1839067] (fp
+ * unix/tcl.m4: rounding setup on solaris x86, native cc), provided
+ * unix/configure: by Michael Schlenker. configure regen'd.
- * unix/configure: autoconf-2.13
+2008-04-01 Don Porter <dgp@users.sourceforge.net>
-2005-05-10 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclStubLib.c (Tcl_InitStubs): Added missing error message.
+ * generic/tclPkg.c (Tcl_PkgInitStubsCheck):
- * tests/string.test: string-10.[21-30]
- * generic/tclCmdMZ.c (Tcl_StringObjCmd): add extra checks to
- prevent possible UMR in unichar cmp function for string map.
+2008-03-30 Kevin Kenny <kennykb@acm.org>
-2005-05-06 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclInt.h (TclIsNaN):
+ * unix/configure.in: Added code to the configurator to check for
+ a standard isnan() macro and use it if one
+ is found. This change avoids bugs where
+ the test of ((d) != (d)) is optimized away
+ by an overaggressive compiler. [Bug 1783544]
+ * generic/tclObj.c: Added missing #include <math.h> needed to
+ locate isnan() after the above change.
- * unix/tcl.m4, unix/configure: correct Solaris 10 (5.10) check and
- add support for x86_64 Solaris cc builds.
+ * unix/configure: autoconf-2.61
-2005-04-29 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * tests/mathop.test (mathop-25.9, mathop-25.14): Modified tests
+ to deal with (slightly buggy) math libraries in which pow()
+ returns an incorrectly rounded result. [Bug 1808174]
- * doc/FileSystem.3: Backport of doc fix. [Bug 1172401]
+2008-03-26 Don Porter <dgp@users.sourceforge.net>
-2005-04-27 Don Porter <dgp@users.sourceforge.net>
+ *** 8.5.2 TAGGED FOR RELEASE ***
- * library/init.tcl: Corrected flaw in interactive command
- * tests/main.test: auto-completion. [Bug 1191409]
+ * generic/tcl.h: Bump to 8.5.2 for release.
+ * library/init.tcl:
+ * tools/tcl.wse.in:
+ * unix/configure.in:
+ * unix/tcl.spec:
+ * win/configure.in:
- * tests/unixInit.test (7.1): Alternative fix for the
- 2005-04-22 commit.
+ * unix/configure: autoconf-2.59
+ * win/configure:
-2005-04-25 Daniel Steffen <das@users.sourceforge.net>
+ * changes: Updated for 8.5.2 release.
+
+2008-03-28 Donal K. Fellows <dkf@users.sf.net>
+
+ * tests/fCmd.test: Substantial rewrite to use many more tcltest
+ features. Great reduction in quantity of [catch] gymnastics. Several
+ buggy tests fixed, including one where the result of the previous test
+ was being checked!
+
+2008-03-27 Kevin B. Kenny <kennykb@acm.org>
+
+ * library/tzdata/America/Marigot:
+ * library/tztata/America/St_Barthelemy:
+ * library/tzdata/America/Argentina/San_Luis:
+ * library/tzdata/Asia/Ho_Chi_Minh:
+ * library/tzdata/Asia/Kolkata: (new files)
+ * library/tzdata/America/Caracas:
+ * library/tzdata/America/Havana:
+ * library/tzdata/America/Santiago:
+ * library/tzdata/America/Argentina/Buenos_Aires:
+ * library/tzdata/America/Argentina/Catamarca:
+ * library/tzdata/America/Argentina/Cordoba:
+ * library/tzdata/America/Argentina/Jujuy:
+ * library/tzdata/America/Argentina/La_Rioja:
+ * library/tzdata/America/Argentina/Mendoza:
+ * library/tzdata/America/Argentina/Rio_Gallegos:
+ * library/tzdata/America/Argentina/San_Juan:
+ * library/tzdata/America/Argentina/Tucuman:
+ * library/tzdata/America/Argentina/Ushuaia:
+ * library/tzdata/Asia/Baghdad:
+ * library/tzdata/Asia/Calcutta:
+ * library/tzdata/Asia/Damascus:
+ * library/tzdata/Asia/Saigon:
+ * library/tzdata/Pacific/Easter:
+ Changes up to and including Olson's tzdata2008b.
- * compat/string.h: fixed memchr() protoype for __APPLE__ so that we
- build on Mac OS X 10.1 again.
+2008-03-27 Daniel Steffen <das@users.sourceforge.net>
- * generic/tclNotify.c (TclFinalizeNotifier): fixed notifier not being
- finalized in unthreaded core (was testing for notifier initialization
- in current thread by checking thread id != 0 but thread id is always 0
- in untreaded core).
+ * unix/tcl.m4 (SunOS-5.1x): fix 64bit support for Sun cc. [Bug 1921166]
- * unix/tclUnixNotfy.c (Tcl_WaitForEvent): sync with HEAD: only declare
- and use timeout var in unthreaded core.
+ * unix/configure: autoconf-2.59
- * unix/Makefile.in: added @PLAT_SRCS@ to SRCS and split out
- NOTIFY_SRCS from UNIX_SRCS for parity with UNIX_OBJS & NOTIFY_OBJS.
+2008-03-26 Don Porter <dgp@users.sourceforge.net>
- * unix/configure.in: only run check for broken strstr implementation
- if AC_REPLACE_FUNCS(strstr) hasn't already determined that strstr is
- unavailable, otherwise compat/strstr.o will be used twice (resulting
- in duplicate symbol link errors on Mac OS X 10.1)
+ * changes: Updated for 8.5.2 release.
- * unix/tcl.m4 (Darwin): added configure checks for recently added
- linker flags -single_module and -search_paths_first to allow building
- with older tools (and on Mac OS X 10.1), use -single_module in
- SHLIB_LD and not just T{CL,K}_SHLIB_LD_EXTRAS, added unexporting from
- Tk of symbols from libtclstub to avoid duplicate symbol warnings,
- added PLAT_SRCS definition for Mac OS X.
- (SC_MISSING_POSIX_HEADERS): added caching of dirent.h check.
- (SC_TCL_64BIT_FLAGS): fixed 'checking for off64_t' message output.
+2008-03-24 Pat Thoyts <patthoyts@users.sourceforge.net>
- * unix/configure: autoconf-2.13
+ * generic/tclBinary.c: [Bug 1923966] - crash in binary format
+ * tests/binary.test: Added tests for the above crash condition.
-2005-04-22 Don Porter <dgp@users.sourceforge.net>
+2008-03-21 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclCmdMZ.c: Corrected intrep-dependence of
- * tests/string.test: [string is boolean] [Bug 1187123]
+ * doc/switch.n: Clarified documentation in respect of two-argument
+ invokation. [Bug 1899962]
-2005-04-22 Daniel Steffen <das@users.sourceforge.net>
+ * tests/switch.test: Added more tests of regexp-mode compilation of
+ the [switch] command. [Bug 1854435]
- * tests/unixInit.test (7.1): fixed failure when running tests with
- -tmpdir arg not set to working dir.
+2008-03-20 Donal K. Fellows <dkf@users.sf.net>
-2005-04-20 Don Porter <dgp@users.sourceforge.net>
+ * generic/tcl.h, generic/tclThreadAlloc.c: Tidied up the declarations
+ of Tcl_GetMemoryInfo so that it is always defined. Will panic when
+ called against a Tcl that was previously built without it at all,
+ which is OK because that also indicates a serious mismatch between
+ memory configuration options.
- * generic/tclGet.c (Tcl_GetInt): Corrected error that did not
- * generic/tclObj.c (Tcl_GetIntFromObj): permit 0x80000000 to be
- recognized as an integer on TCL_WIDE_INT_IS_LONG systems [Bug 1090869]
+2008-03-19 Donal K. Fellows <dkf@users.sf.net>
-2005-04-19 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tcl.h, generic/tclThreadAlloc.c (Tcl_GetMemoryInfo): Make
+ sure this function is available when direct linking. [Bug 1868171]
- * tests/winPipe.test (winpipe-6.2): remove -blocking 1 as this one
- can truly block.
+ * tests/reg.test (reg-33.14): Marked nonPortable because some
+ environments have small default stack sizes. [Bug 1905562]
-2005-04-19 David Gravereaux <davygrvy@pobox.com>
+2008-03-18 Andreas Kupries <andreask@activestate.com>
- * win/tclWinPipe.c: The pipe channel driver now respects the -blocking
- option when closing. The windows pipe driver now has the same behavior
- as the UNIX side. This change is to avoid a hung shell when exiting
- due to open pipes that refuse to close in a graceful manner.
- * doc/open.n: Added a note about -blocking 0 and lack of exit status
- as it had never been documented. [Bug 947693]
+ * library/tm.tcl (::tcl::tm::UnknownHandler): Changed 'source' to
+ 'source -encoding utf-8'. This fixes a portability problem of Tcl
+ Modules pointed out by Don Porter. By using plain 'source' we were at
+ the mercy of 'encoding system', making modules less portable than they
+ could be. The exact scenario: A writes a TM in some weird encoding
+ which is A's system encoding, distributes it, and somewhere else it
+ cannot be read/used because the system encoding is different. Forcing
+ the use of utf-8 makes the module portable.
- ***POTENTIAL INCOMPATIBILITY***
+ ***INCOMPATIBILITY*** for all Tcl Modules already written in non-utf-8
+ compatible encodings.
- Scripts that use async pipes on windows, must (like the UNIX side) set
- -blocking to 1 before calling [close] to receive the exit status.
+2008-03-18 Don Porter <dgp@users.sourceforge.net>
- * tests/winPipe.test (winpipe-6.1/2): added 'fconfigure $f -blocking
- 1' so the exit status can be acquired.
+ * generic/tclExecute.c: Patch from Miguel Sofer to correct the
+ alignment of memory allocated by GrowEvaluationStack(). [Bug 1914503]
-2005-04-13 David Gravereaux <davygrvy@pobox.com>
+2008-03-18 Andreas Kupries <andreask@activestate.com>
- * generic/tclIO.c (Tcl_SetChannelBufferSize): Lowest size limit
- * tests/io.test: changed from ten bytes to one byte. Need for
- * tests/iogt.test: this change was proven by Ross Cartlidge
- <rossc@cisco.com> where [read stdin 1] was grabbing 10 bytes followed
- by starting a child process that was intended to continue reading from
- stdin. Even with -buffersize set to one, nine chars were getting lost
- by the buffersize over reading for the native read() caused by [read].
+ * library/tm.tcl (::tcl::tm::Defaults): Modified handling of
+ environment variables. See [Bug 1914604]. Solution slightly different
+ than proposed in the report. Using the underscored form TCLX_y_TM_PATH
+ even if TCLX.y_TM_PATH exists. Also using a loop to cut prevent code
+ replication.
-2005-04-12 Kevin B. Kenny <kennykb@acm.org>
+2008-03-16 Donal K. Fellows <dkf@users.sf.net>
- * compat/strstr.c: Added default definition of NULL to accommodate
- building on systems with badly broken headers. [Bug 1175161]
+ * generic/tclCompCmds.c (TclCompileDictForCmd): Correct the handling
+ of stack space calculation (the jump pattern used was confusing the
+ simple-minded code doing the calculations). [Bug 1903325]
-2005-04-09 Daniel Steffen <das@users.sourceforge.net>
+ * doc/lreplace.n: Clarified documentation of what happens with
+ negative indices. [Bug 1905809] Added example, tidied up formatting.
- * macosx/README: updated requirements for OS & developer tool versions
- + other small fixes/cleanup.
+2008-03-14 Don Porter <dgp@users.sourceforge.net>
- * unix/tcl.m4 (Darwin): added -single_module linker flag to
- TCL_SHLIB_LD_EXTRAS and TK_SHLIB_LD_EXTRAS.
- * unix/configure: autoconf-2.13
+ * generic/tclBasic.c (OldMathFuncProc): Same workaround protection
+ from bad TclStackAlloc() alignment. Thanks George Peter Staplin.
-2005-04-05 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+ * generic/tclCmdIL.c (Tcl_LsortObjCmd): Use ckalloc() to allocate
+ SortElement arrays instead of TclStackAlloc() which isn't getting
+ alignment right. Workaround for [Bug 1914503].
- Set of changes correcting huge memory waste (not a leak) when a thread
- exits. This has been introduced in 8.4.7 within an attempt to
- correctly cleanup after ourselves when Tcl library is being unloaded
- with the Tcl_Finalize() call.
+2008-03-14 Reinhard Max <max@suse.de>
- This fixes the [Bug 1178445].
+ * generic/tclTest.c: Ignore the return value of write() when we are
+ * unix/tclUnixPipe.c: about to exit anyways.
- * generic/tclInt.h: added prototypes for TclpFreeAllocCache() and
- TclFreeAllocCache()
+2008-03-13 Daniel Steffen <das@users.sourceforge.net>
- * generic/tclThreadAlloc.c: modified TclFinalizeThreadAlloc() to
- explicitly call TclpFreeAllocCache with the NULL-ptr as argument
- signalling cleanup of private tsd key used only by the threading
- allocator.
+ * unix/configure.in: Use backslash-quoting instead of double-quoting
+ * unix/tcl.m4: for lib paths in tclConfig.sh. [Bug 1913622]
+ * unix/configure: autoconf-2.59
- * unix/tclUnixThrd.c: fixed TclpFreeAllocCache() to recognize when
- being called with NULL argument. This is a signal for it to clean up
- the tsd key associated with the threading allocator.
+2008-03-13 Don Porter <dgp@users.sourceforge.net>
- * win/tclWinThrd.c: renamed TclWinFreeAllocCache to TclpFreeAllocCache
- and fixed to recognize when being called with NULL argument. This is a
- signal for it to clean up the tsd key associated with the threading
- allocator.
+ * changes: Updated for 8.5.2 release.
-2005-04-05 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclStrToD.c: Resolve identifier conflict over "pow10" with
+ libm in Cygwin and DJGPP. Thanks to Gordon Schumacher and Philip
+ Moore. [Patch 1800636]
- * generic/tclExecute.c (ExprSrandFunc): Replaced incursions into the
- * generic/tclUtil.c (TclGetIntForIndex): intreps of numeric types with
- simpler calls of Tcl_GetIntFromObj and Tcl_GetLongFromObj, now that
- those routines are better behaved wrt shimmering. [Patch 1177129]
+2008-03-12 Daniel Steffen <das@users.sourceforge.net>
-2005-03-29 Jeff Hobbs <jeffh@ActiveState.com>
+ * macosx/Tcl.xcodeproj/project.pbxproj: Add support for Xcode 3.1
+ * macosx/Tcl.xcodeproj/default.pbxuser: CODE_SIGN_IDENTITY and
+ * macosx/Tcl-Common.xcconfig: 'xcodebuild install'.
- * win/tcl.m4, win/configure: do not require cygpath in macros to
- allow msys alone as an alternative.
+2008-03-12 Andreas Kupries <andreask@activestate.com>
- * win/tclWinTime.c (TclpGetDate): use time_t for 'time' [Bug 1163422]
+ * doc/info.n: Replaced {expand} with {*}.
-2005-03-18 Don Porter <dgp@users.sourceforge.net>
+2008-03-12 Jeff Hobbs <jeffh@ActiveState.com>
- * generic/tclCompCmds.c (TclCompileIncrCmd): Corrected checks for
- immediate operand usage to permit leading space and sign characters.
- Restores more efficient bytecode for [incr x -1] that got lost in the
- CONST string reforms of Tcl 8.4. [Bug 1165671]
+ * unix/Makefile.in (install-libraries): Bump http to 2.7
+ * win/Makefile.in (install-libraries): Added -myaddr option to allow
+ * library/http/http.tcl (http::geturl): control of selected socket
+ * library/http/pkgIndex.tcl: interface. [Bug 559898]
+ * doc/http.n, tests/http.test: Added -keepalive and
+ -protocol 1.1 with chunked transfer encoding support. [Bug 1063703,
+ 1470377, 219225] (default keepalive is 0)
+ Added ability to override Host in -headers. [Bug 928154]
+ Added -strict option to control URL validation on per-call basis.
+ [Bug 1560506]
- * generic/tclBasic.c (Tcl_EvalEx,TclEvalTokensStandard):
- * generic/tclCmdMZ.c (Tcl_SubstObj):
- * tests/basic.test (basic-46.4): Restored recursion limit
- * tests/parse.test (parse-19.*): testing in nested command
- substitutions within direct script evaluation (Tcl_EvalEx) that got
- lost in the parser reforms of Tcl 8.1. Added tests for correct
- behavior. [Bug 1115904]
+2008-03-11 Jeff Hobbs <jeffh@ActiveState.com>
-2005-03-15 Vince Darley <vincentdarley@users.sourceforge.net>
+ * library/http/http.tcl (http::geturl): Add -method option to support
+ * tests/http.test (http-3.1): http PUT and DELETE requests.
+ * doc/http.n: [Bug 1599901, 862554]
- * generic/tclFileName.c:
- * win/tclWinFile.c:
- * tests/winFCMd.test: fix to 'file pathtype' and 'file norm' failures
- on reserved filenames like 'COM1:', etc.
+ * library/http/http.tcl: Whitespace changes, code cleanup. Allow http
+ to be re-sourced without overwriting http state.
-2005-03-15 Kevin B. Kenny <kennykb@acm.org>
+2008-03-11 Daniel Steffen <das@users.sourceforge.net>
- * generic/tclClock.c:
- * generic/tclDate.c:
- * generic/tclGetDate.y:
- * generic/tclInt.decls:
- * unix/tclUnixTime.c:
- * win/tclWinTime.c: Replaced 'unsigned long' variable holding
- times with 'Tcl_WideInt', to cope with systems on which a time_t is
- wider than a long (Win64) [Bug 1163422]
- * generic/tclIntDecls.h: Regen
+ * generic/tclEncoding.c (LoadEscapeEncoding): Avoid leaking escape
+ sub-encodings, fixes encoding-11.1 failing after iso2022-jp loaded.
+ [Bug 1893053]
-2005-03-15 Pat Thoyts <patthoyts@users.sourceforge.net>
+ * macosx/tclMacOSXNotify.c: Avoid using CoreFoundation after fork() on
+ Darwin 9 even when TclpCreateProcess() uses vfork().
- * unix/tcl.m4: Make it work on OpenBSD again. Imported patch
- from the OpenBSD ports tree.
+ * macosx/Tcl.xcodeproj/project.pbxproj: Add support for Xcode 3.1 and
+ * macosx/Tcl.xcodeproj/default.pbxuser: configs for building with
+ * macosx/Tcl-Common.xcconfig: gcc-4.2 and llvm-gcc-4.2.
-2005-03-10 Don Porter <dgp@users.sourceforge.net>
+ * unix/tclUnixPort.h: Workaround vfork() problems
+ in llvm-gcc-4.2.1 -O4 build.
- * generic/tclCmdMZ.c (TclCheckInterpTraces): Corrected mistaken
- cast of ClientData to (TraceCommandInfo *) when not warranted. Thanks
- to Yuri Victorovich for the report. [Bug 1153871]
+ * unix/tclUnixPort.h: Move MODULE_SCOPE compat define
+ to top [Bug 1911102].
-2005-03-08 Jeff Hobbs <jeffh@ActiveState.com>
+ * macosx/GNUmakefile: Fix quoting to allow paths to
+ * macosx/Tcl-Common.xcconfig: ${builddir} and ${INSTALL_ROOT}
+ * unix/Makefile.in: to contain spaces.
+ * unix/configure.in:
+ * unix/install-sh:
+ * unix/tcl.m4:
+ * tests/ioCmd.test:
- * win/makefile.vc: clarify necessary defined vars that can come
- from MSVC or the Platform SDK.
+ * unix/configure: autoconf-2.59
-2005-02-24 Don Porter <dgp@users.sourceforge.net>
+ * unix/Makefile.in (install-strip): Strip non-global symbols from
+ dynamic library.
- * library/tcltest/tcltest.tcl: Better use of [glob -types] to avoid
- * tests/tcltest.test: failed attempts to [source] a directory, and
- similar matters. Thanks to "mpettigr". [Bug 1119798]
+ * unix/tclUnixNotfy.c: Fix warning.
- * library/tcltest/pkgIndex.tcl: Bump to tcltest 2.2.8
+ * tests/exec.test (exec-9.7): Reduce timing sensitivity
+ * tests/socket.test (socket-2.11): (esp. on multi-proc machines).
-2005-02-23 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * tests/fCmd.test (fCmd-9.4): Skip on Darwin 9 (xfail).
- * doc/CrtChannel.3 (THREADACTIONPROC): Formatting fix. [Bug 1149605]
+2008-03-11 Miguel Sofer <msofer@users.sf.net>
-2005-02-17 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclVar.c (TclDeleteNamespaceVars):
+ * tests/var.test (var-8.2): Unset traces on vars should be called with
+ a FQ named during namespace deletion. This was causing infinite loops
+ when unset traces recreated the var, as reported by Julian Noble. [Bug
+ 1911919]
- * win/tclWinFCmd.c (TraverseWinTree): use wcslen on wchar, not
- Tcl_UniCharLen.
+2008-03-10 Don Porter <dgp@users.sourceforge.net>
-2005-02-16 Miguel Sofer <msofer@users.sf.net>
+ * changes: Updated for 8.5.2 release.
- * doc/variable.n: fix for [Bug 1124160], variables are detected by
- [info vars] but not by [info locals].
+ * doc/http.n: Revised to indicate that [package require http 2.5.5]
+ is needed to get all the documented commands ([http::meta]).
-2005-02-10 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclEvent.c (TclDefaultBgErrorHandlerObjCmd): Added error
+ * tests/event.test (event-5.*): checking to protect against callers
+ passing invalid return options dictionaries. [Bug 1901113]
- * unix/Makefile.in: remove SHLIB_LD_FLAGS (only for AIX, inlined
- * unix/tcl.m4: into SHLIB_LD). Combine AIX-* and AIX-5
- * unix/configure: branches in SC_CONFIG_CFLAGS.
- Correct gcc builds for AIX-4+ and HP-UX-11.
+ * generic/tclBasic.c (ExprAbsFunc): Revised so that the abs()
+ * tests/expr.test: function and the [::tcl::mathfunc::abs]
+ command do not return the value of -0, or equivalent values with more
+ alarming string reps like -1e-350. [Bug 1893815]
-2005-02-10 Miguel Sofer <msofer@users.sf.net>
+2008-03-07 Andreas Kupries <andreask@activestate.com>
- * generic/tclBasic.c (Tcl_EvalObjEx):
- * tests/basic.test (basic-26.2): preserve the arguments passed to TEOV
- in the pure-list branch, in case the list shimmers away. Fix for [Bug
- 1119369], reported by Peter MacDonald.
+ * generic/tclResult.c (ReleaseKeys): Workaround for [Bug 1904907].
+ Reset the return option keys to NULL to allow full re-initialization
+ by GetKeys(). This introduces a memory leak for the key objects, but
+ gets us around a crash in the finalization of reflected channels when
+ handling returns, either at compile- or runtime. In both cases we
+ access the keys after they have been released by their thread exit
+ handler. A proper fix is entangled with the untangling of the
+ finalization ordering and attendant issues. For now we choose the
+ lesser evil.
-2005-02-10 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+2008-03-07 Don Porter <dgp@users.sourceforge.net>
- * doc/binary.n: Made the documentation of sign bit masking and
- [binary scan] consistent. [Bug 1117017]
+ * generic/tclExecute.c (Tcl_ExprObj): Revised expression bytecode
+ compiling so that bytecodes invalid due to changing context or due to
+ the difference between expressions and scripts are not reused. [Bug
+ 1899164]
-2005-02-01 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclCmdAH.c: Revised direct evaluation implementation of
+ [expr] so that [expr $e] caches compiled bytecodes for the expression
+ as the intrep of $e.
- * generic/tclExecute.c (TclCompEvalObj): Removed stray statement
- left behind in prior code reorganization.
+ * tests/execute.test (execute-6.*): More tests checking that
+ script bytecode is invalidated in the right situations.
-2005-01-28 Jeff Hobbs <jeffh@ActiveState.com>
+2008-03-07 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * unix/configure, unix/tcl.m4: add solaris 64-bit gcc build
- support. [Bug 1021871]
+ * win/configure.in: Add AC_HEADER_STDC to support msys/win64.
-2005-01-27 Jeff Hobbs <jeffh@ActiveState.com>
+2008-03-06 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclBasic.c (Tcl_ExprBoolean, Tcl_ExprDouble)
- (Tcl_ExprLong): Fix to recognize Tcl_WideInt type. [Bug 1109484]
+ * doc/namespace.n: Minor tidying up. [Bug 1909019]
-2005-01-27 Andreas Kupries <andreask@activestate.com>
+2008-03-04 Don Porter <dgp@users.sourceforge.net>
- TIP#218 IMPLEMENTATION
+ * tests/execute.test (6.3,4): Added tests for [Bug 1899164].
- * generic/tclDecls.h: Regenerated from tcl.decls.
- * generic/tclStubInit.c:
+2008-03-03 Reinhard Max <max@suse.de>
- * doc/CrtChannel.3: Documentation of extended API,
- * generic/tcl.decls: extended testsuite, and
- * generic/tcl.h: implementation. Removal of old
- * generic/tclIO.c: driver-specific TclpCut/Splice
- * generic/tclInt.h: functions. Replaced with generic
- * tests/io.test: thread-action calls through the
- * unix/tclUnixChan.c: new hooks. Update of all builtin
- * unix/tclUnixPipe.c: channel drivers to version 4.
- * unix/tclUnixSock.c: Windows drivers extended to
- * win/tclWinChan.c: manage thread state in a thread
- * win/tclWinConsole.c: action handler.
- * win/tclWinPipe.c:
- * win/tclWinSerial.c:
- * win/tclWinSock.c:
- * mac/tclMacChan.c:
+ * unix/tclUnixChan.c: Fix mark and space parity on Linux, which uses
+ CMSPAR instead of PAREXT.
-2005-01-25 Don Porter <dgp@users.sourceforge.net>
+2008-03-02 Miguel Sofer <msofer@users.sf.net>
- * library/auto.tcl: Updated [auto_reset] to clear auto-loaded
- procs in namespaces other than :: [Bug 1101670].
+ * generic/tclNamesp.c (GetNamespaceFromObj):
+ * tests/interp.test (interp-28.2): Spoil the intrep of an nsNameType
+ obj when the reference crosses interpreter boundaries.
-2005-01-25 Daniel Steffen <das@users.sourceforge.net>
+2008-02-29 Don Porter <dgp@users.sourceforge.net>
- * unix/tcl.m4 (Darwin): fixed bug with static build linking to dynamic
- library in /usr/lib etc instead of linking to static library earlier
- in search path. [Bug 956908]
- Removed obsolete references to Rhapsody.
- * unix/configure: autoconf-2.13
+ * generic/tclResult.c (Tcl_SetReturnOptions): Revised the refcount
+ management of Tcl_SetReturnOptions to become that of a conventional
+ Consumer routine. Thanks to Peter Spjuth for pointing out the
+ difficulties calling Tcl_SetReturnOptions with non-0-count value for
+ options.
+ * generic/tclExecute.c (INST_RETURN_STK): Revised the one caller
+ within Tcl itself which passes a non-0-count value to
+ Tcl_SetReturnOptions().
-2005-01-19 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tclBasic.c (Tcl_AppendObjToErrorInfo): Revised the
+ refcount management of Tcl_AppendObjToErrorInfo to become that of a
+ conventional Consumer routine. This preserves the ease of use for the
+ overwhelming common callers who pass in a 0-count value, but makes the
+ proper call with a non-0-count value less surprising.
+ * generic/tclEvent.c (TclDefaultBgErrorHandlerObjCmd): Revised the
+ one caller within Tcl itself which passes a non-0-count value to
+ Tcl_AppendObjToErrorInfo().
- * win/tclWinChan.c (FileCloseProc): Invoke TclpCutFileChannel() to
- remove a FileInfo from the thread local list before deallocating it.
- This should have been done via an earlier call to Tcl_CutChannel, but
- I was running into a crash in the next call to Tcl_CutChannel during
- the IO finalization stage.
+2008-02-28 Joe English <jenglish@users.sourceforge.net>
-2005-01-17 Vince Darley <vincentdarley@users.sourceforge.net>
+ * unix/tclPort.h, unix/tclCompat.h, unix/tclUnixChan.h: Reduce scope
+ of <sys/filio.h> and <sys/ioctl.h> #includes. [Patch 1903339]
- * tests/winFCmd.test: made test independent of current drive. [Bug
- 1066528]
+2008-02-28 Joe English <jenglish@users.sourceforge.net>
-2005-01-10 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * unix/tclUnixChan.c, unix/tclUnixNotfy.c, unix/tclUnixPipe.c:
+ Consolidate all code conditionalized on -DUSE_FIONBIO into one place.
+ * unix/tclUnixPort.h, unix/tclUnixCompat.c: New routine
+ TclUnixSetBlockingMode() [Patch 1903339].
- * unix/tclUnixFCmd.c (CopyFile): Convert u_int to unsigned to make
- clashes with types in standard C headers less of a problem. [Bug
- 1098829]
+2008-02-28 Don Porter <dgp@users.sourceforge.net>
-2005-01-06 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * generic/tclBasic.c (TclEvalObjvInternal): Plug memory leak when
+ an enter trace deletes or changes the command, prompting a reparsing.
+ Don't let the second pass lose commandPtr value allocated during the
+ first pass.
- * library/http/http.tcl (http::mapReply): Significant performance
- enhancement by using [string map] instead of [regsub]/[subst], and
- update version requirement to Tcl8.4. [Bug 1020491]
+ * generic/tclCompExpr.c (ParseExpr): Plug memory leak in error
+ message generation.
-2005-01-05 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * generic/tclStringObj.c (Tcl_AppendFormatToObj): [format %llx $big]
+ leaked an mp_int.
- * unix/tclUnixInit.c (localeTable): Add encoding mappings for some
- Chinese locales. [Bug 1084595]
+ * generic/tclCompCmds.c (TclCompileReturnCmd): The 2007-10-18 commit
+ to optimize compiled [return -level 0 $x] [RFE 1794073] introduced a
+ memory leak of the return options dictionary. Fixing that.
- * doc/lsearch.n: Convert to other form of emacs mode control
- comment to prevent problems with old versions of man. [Bug 1085127]
+2008-02-27 Pat Thoyts <patthoyts@users.sourceforge.net>
-2004-12-29 Jeff Hobbs <jeffh@ActiveState.com>
+ * library/http/http.tcl: [Bug 705956] - fix inverted logic when
+ cleaning up socket error in geturl.
- * win/tcl.m4, win/configure: update MSVC CFLAGS_OPT to -O2, remove
- -Gs (included in -O2) and -GD (outdated). Use "link -lib" instead
- of "lib" binary and remove -YX for MSVC7 portability. Add
- -fomit-frame-pointer for gcc OPT compiles. [Bug 1092952, 1091967]
+2008-02-27 Kevin B. Kenny <kennykb@acm.org>
-2004-12-13 Kevin B. Kenny <kennykb@acm.org>
+ * doc/clock.n: Corrected minor indentation gaffe in the penultimate
+ paragraph. [Bug 1898025]
+ * generic/tclClock.c (ParseClockFormatArgs): Changed to check that the
+ clock value is in the range of a 64-bit integer. [Bug 1862555]
+ * library/clock.tcl (::tcl::clock::format, ::tcl::clock::scan,
+ (::tcl::clock::add, ::tcl::clock::LocalizeFormat): Fixed bugs in
+ caching of localized strings that caused weird results when localized
+ date/time formats were used. [Bug 1902423]
+ * tests/clock.test (clock-61.*, clock-62.1): Regression tests for [Bug
+ 1862555] and [Bug 1902423].
- * doc/clock.n: Clarify that the [clock scan] command does not accept
- the full range of ISO8601 point-in-time formats. [Bug 1075433]
+2008-02-26 Joe English <jenglish@users.sourceforge.net>
-2004-12-09 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * generic/tclIOUtil.c, unix/tclUnixPort.h, unix/tclUnixChan.c:
+ Remove dead/unused portability-related #defines and unused conditional
+ code. See [Patch 1901828] for discussion.
- * doc/Async.3: Reword for better grammar, better nroff and get the
- flag name right. (Reported by David Welton.)
+2008-02-26 Joe English <jenglish@users.sourceforge.net>
-2004-12-06 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclIORChan.c (enum MethodName),
+ * generic/tclCompExpr.c (enum Marks): More stray trailing ","s
- *** 8.4.9 TAGGED FOR RELEASE ***
+2008-02-26 Joe English <jenglish@users.sourceforge.net>
- * unix/tclUnixNotfy.c (NotifierThreadProc): init numFdBits [Bug
- 1079286]
+ * unix/configure.in(socklen_t test): Define socklen_t as "int" if
+ missing, not "unsigned". Use AC_TRY_COMPILE instead of
+ AC_EGREP_HEADER.
+ * unix/configure: regenerated.
-2004-12-02 Jeff Hobbs <jeffh@ActiveState.com>
+2008-02-26 Joe English <jenglish@users.sourceforge.net>
- * changes: updated for 8.4.9 release
+ * generic/tclCompile.h: Remove stray trailing "," from enum
+ InstOperandType definition (C99ism).
-2004-12-02 Vince Darley <vincentdarley@users.sourceforge.net>
+2008-02-26 Jeff Hobbs <jeffh@ActiveState.com>
- * generic/tclIOUtil.c: fix and new tests for [Bug 1074671] to
- * tests/fileSystem.test: ensure tilde paths are not returned specially
- by 'glob'.
+ * generic/tclUtil.c (TclReToGlob): Fix the handling of the last star
+ * tests/regexpComp.test: possibly being escaped in
+ determining right anchor. [Bug 1902436]
-2004-12-01 Don Porter <dgp@users.sourceforge.net>
+2008-02-26 Pat Thoyts <patthoyts@users.sourceforge.net>
- * library/auto.tcl (tcl_findLibrary): Disabled use of [file normalize]
- that caused trouble with freewrap. [Bug 1072136]
+ * library/http/pkgIndex.tcl: Set version 2.5.5
+ * library/http/http.tcl: It is better to do the [eof] check after
+ trying to read from the socket. No clashes found in testing. Added
+ http::meta command to access the http headers. [Bug 1868845]
-2004-11-26 Don Porter <dgp@users.sourceforge.net>
+2008-02-22 Pat Thoyts <patthoyts@users.sourceforge.net>
- * tests/reg.test (reg-32.*): Added missing testregexp constraints.
+ * library/http/pkgIndex.tcl: Set version 2.5.4
+ * library/http/http.tcl: Always check that the state array exists
+ in the http::status command. [Bug 1818565]
- * library/auto.tcl (tcl_findLibrary): Made sure the uniquifying
- operations on the search path does not also normalize. [Bug 1072136]
+2008-02-13 Don Porter <dgp@users.sourceforge.net>
-2004-11-26 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * generic/tcl.h: Bump version number to 8.5.2b1 to distinguish
+ * library/init.tcl: CVS development snapshots from the 8.5.1 and
+ * unix/configure.in: 8.5.2 releases.
+ * unix/tcl.spec:
+ * win/configure.in:
+ * README
- * doc/dde.n: Resynchonized the documentation with itself and fixed
- some formatting errors.
+ * unix/configure: autoconf (2.59)
+ * win/configure:
-2004-11-25 Zoran Vasiljevic <vasiljevic@users.sf.net>
+2008-02-12 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * doc/Notify.3:
- * doc/Thread.3: Added doc fixes and hints from [Bug 1068077].
+ * generic/tclCompCmds.c (TclCompileSwitchCmd): Corrected logic for
+ * tests/switch.test (switch-10.15): handling -nocase compilation; the
+ -exact -nocase option cannot be compiled currently. [Bug 1891827]
-2004-11-25 Reinhard Max <max@suse.de>
+ * unix/README: Documented missing configure flags. [Bug 1799011]
- * tests/tcltest.test: The order in which [glob] returns the file names
- * tests/fCmd.test: is undefined, so tests should not depend on it.
+2008-02-06 Kevin B. Kenny <kennykb@acm.org>
-2004-11-24 Don Porter <dgp@users.sourceforge.net>
+ * doc/clock.n (%N): Corrected an error in the explanation of the %N
+ format group.
+ * generic/tclClock.c (ClockParseformatargsObjCmd):
+ * library/clock.tcl (::tcl::clock::format):
+ * tests/clock.test (clock-1.0, clock-1.4):
+ Performance enhancements in [clock format] (moving the analysis of
+ $args into C code, holding on to Tcl_Objs with resolved command names,
+ [lassign] in place of [foreach], avoiding [namespace which] for
+ command resolution).
- * unix/tcl.m4 (SC_ENABLE_THREADS): Corrected failure to determine
- the number of arguments for readdir_r on SunOS systems. [Bug 1071701]
+2008-02-04 Don Porter <dgp@users.sourceforge.net>
- * unix/configure: autoconf-2.13
+ *** 8.5.1 TAGGED FOR RELEASE ***
-2004-11-24 Jeff Hobbs <jeffh@ActiveState.com>
+ * changes: Updated for 8.5.1 release.
- * README: Bumped patchlevel to 8.4.9
- * generic/tcl.h:
+ * generic/tcl.h: Bump to 8.5.1 for release.
+ * library/init.tcl:
* tools/tcl.wse.in:
- * unix/tcl.spec, unix/configure, unix/configure.in:
- * win/configure, win/configure.in:
-
-2004-11-24 Kevin B. Kenny <kennykb@acm.org>
-
- * unix/tcl.m4 (SC_ENABLE_THREADS): Corrected bad check for 3-argument
- readdir_r(). [Bug 1001325]
- * unix/configure: Regenerated.
- * unix/tclUnixNotfy.c: Corrected all uses of 'select' to manage their
- masks using the FD_CLR, FD_ISSET, FD_SET, and FD_ZERO macros rather
- than bit-whacking that failed under Solaris-Sparc-64. [Bug 1071807]
-
-2004-11-23 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclCmdIL.c (InfoVarsCmd): Corrected segfault in new
- * tests/info.test (info-19.6): trivial matching branch [Bug 1072654]
-
-2004-11-23 Vince Darley <vincentdarley@users.sourceforge.net>
-
- * generic/tclPathObj.c: fix and new test for [Bug 1043129] in
- * tests/fileSystem.test: the treatment of backslashes in file join on
- Windows.
-
-2004-11-22 Mo DeJong <mdejong@users.sourceforge.net>
-
- * unix/configure: Regen.
- * unix/tcl.m4 (SC_TCL_64BIT_FLAGS): Define HAVE_TYPE_OFF64_T only when
- off64_t, open64(), and lseek64() are defined. IRIX 5.3 is known to not
- include an open64 function. [Bug 1030465]
-
-2004-11-22 Mo DeJong <mdejong@users.sourceforge.net>
-
- * unix/configure: Regen.
- * unix/tcl.m4 (SC_ENABLE_THREADS): Check for a 2 argument version of
- readdir_r that is known to exists under IRIX 5.3.
- * unix/tclUnixThrd.c (TclpReaddir): Use either 2 arg or 3 arg version
- of readdir_r. [Bug 1001325]
-
-2004-11-19 Reinhard Max <max@suse.de>
-
- *** 8.4.8 TAGGED FOR RELEASE ***
-
- * unix/installManPage: Classic sed doesn't support | in REs.
-
-2004-11-19 Daniel Steffen <das@users.sourceforge.net>
-
- * macosx/Makefile:
* unix/configure.in:
- * unix/tclUnixInit.c (MacOSXGetLibraryPath): changed detection of tcl
- framework build when determining tclLibPath from overloaded
- TCL_LIBRARY to configuration define TCL_FRAMEWORK. [Bug 1068088]
-
- * unix/configure: autoconf-2.13
+ * unix/tcl.spec:
+ * win/configure.in:
- * tests/unixInit.test (7.1): fixed failure when running tests
- with -tmpdir arg not set to working dir.
+ * unix/configure: autoconf-2.59
+ * win/configure:
-2004-11-18 Don Porter <dgp@users.sourceforge.net>
+2008-02-04 Miguel Sofer <msofer@users.sf.net>
- * changes: Final updates for Tcl 8.4.8 release.
+ * generic/tclExecute.c (INST_CONCAT1): Fix optimisation for in-place
+ concatenation (was going over String type)
-2004-11-18 Reinhard Max <max@suse.de>
+2008-02-02 Daniel Steffen <das@users.sourceforge.net>
- * unix/tcl.m4 (SC_CONFIG_MANPAGES): Applied an improved version of
- * unix/configure.in: [Patch 996085], that introduces
- * unix/Makefile.in: --enable-man-suffix.
+ * unix/configure.in (Darwin): Correct Info.plist year substitution in
+ non-framework builds.
- * unix/installManPage: added
- * unix/mkLinks.tcl: removed
- * unix/mkLinks: removed
+ * unix/configure: autoconf-2.59
-2004-11-16 Jeff Hobbs <jeffh@ActiveState.com>
+2008-01-30 Miguel Sofer <msofer@users.sf.net>
- * unix/tclUnixChan.c (TtySetOptionProc): fixed crash configuring
- -ttycontrol on a channel. [Bug 1067708]
+ * generic/tclInterp.c (Tcl_GetAlias): Fix for [Bug 1882373], thanks go
+ to an00na.
-2004-11-16 Andreas Kupries <andreask@activestate.com>
+2008-01-30 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * win/makefile.vc: Fixed bug in installation of http 2.5.
- * win/makefile.bc: Was installed into directory http2.4.
- * win/Makefile.in: This has been corrected.
- * unix/Makefile.in:
- * tools/tcl.wse.in:
- * tools/tclmin.wse:
+ * tools/tcltk-man2html.tcl: Reworked manual page scraper to do a
+ proper job of handling references to Ttk options. [Tk Bug 1876493]
-2004-11-16 Don Porter <dgp@users.sourceforge.net>
+2008-01-29 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * library/auto.tcl: Updated [tcl_findLibrary] search path to
- include the $::auto_path. [RFE 695441]
+ * doc/man.macros (SO, SE): Adjusted macros so that it is possible for
+ Ttk to have its "standard options" on a manual page that is not called
+ "options". [Tk Bug 1876493]
-2004-11-16 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+2008-01-25 Don Porter <dgp@users.sourceforge.net>
- * doc/tclvars.n: Mention global variables set by tclsh and wish so
- they are easier to find. [Patch 1065732]
+ * changes: Updated for 8.5.1 release.
-2004-11-15 Don Porter <dgp@users.sourceforge.net>
+2008-01-23 Don Porter <dgp@users.sourceforge.net>
- * generic/tclCmdMZ.c (Tcl_TraceObjCmd): Fixed Bug 1065378 which failed
- * tests/trace.test (trace-33.1): to permit a variable trace
- created with [trace variable] to be destroyed with [trace remove].
- Thanks to Keith Vetter for the report.
+ * generic/tclInt.h: New macro TclGrowParseTokenArray() to
+ * generic/tclCompCmds.c: simplify code that might need to grow
+ * generic/tclCompExpr.c: an array of Tcl_Tokens in the parsePtr
+ * generic/tclParse.c: field of a Tcl_Parse. Replaces the
+ TclExpandTokenArray() routine via replacing:
+ int needed = parsePtr->numTokens + growth;
+ while (needed > parsePtr->tokensAvailable) {
+ TclExpandTokenArray(parsePtr);
+ }
+ with:
+ TclGrowParseTokenArray(parsePtr, growth);
+ This revision merged over from dgp-refactor branch.
-2004-11-12 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclCompile.h: Demote TclCompEvalObj() from internal stubs to
+ * generic/tclInt.decls: a MODULE_SCOPE routine declared in
+ tclCompile.h.
- * library/init.tcl: Made [unknown] robust in the case that either
- of the variables ::errorInfo or ::errorCode gets unset. [Bug 1063707]
+ * generic/tclIntDecls.h: make genstubs
+ * generic/tclStubInit.c:
-2004-11-12 Jeff Hobbs <jeffh@ActiveState.com>
+2008-01-22 Don Porter <dgp@users.sourceforge.net>
- * generic/tclEncoding.c (TableFromUtfProc): correct crash
- condition when TCL_UTF_MAX == 6. [Bug 1004065]
+ * generic/tclTimer.c (AfterProc): Replace Tcl_EvalEx() with
+ Tcl_EvalObjEx() to evaluate [after] callbacks. Part of trend to favor
+ compiled execution over direct evaluation.
-2004-11-12 Daniel Steffen <das@users.sourceforge.net>
+2008-01-22 Miguel Sofer <msofer@users.sf.net>
- * doc/clock.n:
- * doc/registry.n:
- * doc/upvar.n: fixed *roff errors uncovered by running 'make html'.
+ * generic/tclCmdIl.c (Tcl_LreverseObjCmd):
+ * tests/cmdIL.test (cmdIL-7.7): Fix crash on reversing an empty list.
+ [Bug 1876793]
- * tools/tcltk-man2html.tcl: added faked support for bullet point
- lists, i.e. *nroff ".IP \(bu" syntax.
- Synced other changes from HEAD.
+2008-01-20 Jeff Hobbs <jeffh@ActiveState.com>
-2004-11-11 Daniel Steffen <das@users.sourceforge.net>
+ * unix/README: Minor typo fixes [Bug 1853072]
- * tests/fCmd.test:
- * unix/tclUnixFCmd.c (TraverseUnixTree): added option to rewind() the
- readdir() loop whenever the source hierarchy has been modified by
- traverseProc (e.g. by deleting files); this is required to ensure
- complete traversal of the source hierarchy on certain filesystems like
- HFS+. Added test for failing recursive delete on Mac OS X that was due
- to this. [Bug 1034337]
+ * generic/tclIO.c (TclGetsObjBinary): Operate on topmost channel.
+ [Bug 1869405] (Ficicchia)
- * generic/tclListObj.c (Tcl_ListObjReplace): use memmove() instead of
- manual copy loop to shift list elements. Decreases time spent in
- Tcl_ListObjReplace() from 5.2% to 1.7% of overall runtime of tclbench
- on a ppc 7455 (i.e. 200% speed increase). [Patch 1064243]
+2008-01-17 Don Porter <dgp@users.sourceforge.net>
- * generic/tclHash.c: hoisted some constant pointer dereferences out of
- loops to eliminate redundant loads that the gcc optimizer didn't deal
- with. Decreases time spend in Tcl_FindHashEntry() by 10% over a full
- run of the tcl testuite on a ppc 7455. [Patch 1064243]
+ * generic/tclCompExpr.c: Revision to preserve parsed intreps of
+ numeric and boolean literals when compiling expressions with (optimize
+ == 1).
- * tests/fileName.test:
- * tests/fileSystem.test:
- * tests/io.test:
- * tests/tcltest.test: fixed bugs causing failures when running tests
- with -tmpdir arg not set to working dir.
+2008-01-15 Miguel Sofer <msofer@users.sf.net>
- * macosx/Makefile: corrected path to html help inside framework.
- Prevent parallel make from building several targets at the same time.
+ * generic/tclCompExpr.c: Add an 'optimize' argument to
+ * generic/tclCompile.c: TclCompileExpr() to profit from better
+ * generic/tclCompile.h: literal management according to usage.
+ * generic/tclExecute.c:
-2004-11-09 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * generic/tclCompExpr.c: Fix literal leak in exprs [Bug 1869989] (dgp)
+ * generic/tclExecute.c:
+ * tests/compExpr.test:
- * doc/catch.n: Clarify documentation on return codes. [Bug 1062647]
+ * doc/proc.n: Changed wording for access to non-local variables; added
+ mention to [namespace upvar]. Lame attempt at dealing with
+ documentation. [Bug 1872708]
-2004-11-02 Don Porter <dgp@users.sourceforge.net>
+2008-01-15 Miguel Sofer <msofer@users.sf.net>
- * changes: Updates for Tcl 8.4.8 release.
+ * generic/tclBasic.c: Replacing 'operator' by 'op' in the def of
+ * generic/tclCompExpr.c: struct TclOpCmdClientData to accommodate C++
+ * generic/tclCompile.h: compilers. [Bug 1855644]
-2004-11-02 Don Porter <dgp@users.sourceforge.net>
+2008-01-13 Jeff Hobbs <jeffh@ActiveState.com>
- * library/tcltest/tcltest.tcl: Corrected some misleading
- * tests/tcltest.test (tcltest-26.1,2): displays of ::errorInfo and
- ::errorCode information when the -setup, -body, and/or -cleanup scripts
- return an unexpected return code. Thanks to Robert Seeger for the
- fix. [RFE 1017151]
+ * win/tclWinSerial.c (SerialCloseProc, TclWinOpenSerialChannel): Use
+ critical section for read & write side. [Bug 1353846] (newman)
-2004-11-02 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+2008-01-11 Miguel Sofer <msofer@users.sf.net>
- * generic/tclExecute.c (TclExecuteByteCode): NaN-equality fix from
- Miguel Sofer. [Bug 761471]
+ * unix/tclUnixThrd.c (TclpThreadGetStackSize): Restore stack checking
+ functionality in freebsd. [Bug 1850424]
- * doc/CrtChannel.3 (Tcl_GetChannelMode): Add synopsis. [Bug 1058446]
+ * unix/tclUnixThrd.c (TclpThreadGetStackSize): Fix for crash in
+ freebsd. [Bug 1860425]
-2004-10-31 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+2008-01-10 Don Porter <dgp@users.sourceforge.net>
- * generic/tclCmdIL.c (InfoGlobalsCmd):
- * tests/info.test (info-8.4): Strip leading global-namespace
- specifiers from the pattern argument. [Bug 1057461]
+ * generic/tclStringObj.c (Tcl_AppendFormatToObj): Correct failure to
+ * tests/format.test: account for big.used == 0 corner case in the
+ %ll(idox) format directives. [Bug 1867855]
-2004-10-30 Miguel Sofer <msofer@users.sf.net>
+2008-01-09 George Peter Staplin <georgeps@xmission.com>
- * generic/tclCmdAH.c (Tcl_CatchObjCmd): removed erroneous comment [Bug
- 1029518]
+ * doc/vwait.n: Add a missing be to fix a typo.
-2004-10-29 Don Porter <dgp@users.sourceforge.net>
+2008-01-04 Jeff Hobbs <jeffh@ActiveState.com>
- * library/tcltest/tcltest.tcl: Correct reaction to errors in the
- obsolete processCmdLineArgsHook. [Bug 1055673]
- * library/tcltest/pkgIndex.tcl: Bump to tcltest 2.2.7
+ * tools/tcltk-man2html.tcl (make-man-pages): Make man page title use
+ more specific info on lhs to improve tabbed browser view titles.
-2004-10-28 Andreas Kupries <andreask@activestate.com>
+2008-01-02 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclAlloc.c: Fixed [Bug 1030548], a threaded debug
- * generic/tclThreadAlloc.c: build on Windows now works again. Had to
- * win/tclWinThrd.c: touch Unix as well. Basic patch by Kevin,
- * unix/tclUnixThrd.c: with modifications by myself.
+ * doc/binary.n: Fixed documentation bug reported on tcl-core, and
+ reordered documentation to discourage people from using the hex
+ formatter that is hardly ever useful.
-2004-10-28 Don Porter <dgp@users.sourceforge.net>
+2008-01-02 Don Porter <dgp@users.sourceforge.net>
- * README: Bumped patch level to 8.4.8 to prepare for
- * generic/tcl.h: next patch release.
- * tools/tcl.wse.in:
- * unix/configure.in:
+ * generic/tcl.h: Bump version number to 8.5.1b1 to distinguish
+ * library/init.tcl: CVS development snapshots from the 8.5.0 and
+ * unix/configure.in: 8.5.1 releases.
* unix/tcl.spec:
- * win/README.binary:
* win/configure.in:
+ * README
- * unix/configure: autoconf (2.13)
+ * unix/configure: autoconf (2.59)
* win/configure:
-2004-10-28 Kevin B. Kenny <kennykb@acm.org>
-
- * generic/tclInt.decls:
- * unix/tclUnixTime.c (TclpGmtime, TclpLocaltime):
- * win/tclWinTime.c (TclpGmtime, TclpLocaltime): Changed type
- signatures of TclpGmtime and TclpLocaltime to accept CONST TclpTime_t
- throughout, to avoid any possible confusion in pedantic compilers.
- [Bug 1001319]
- * generic/tclIntDecls.h:
- * generic/tclIntPlatDecls.h: Regenerated.
-
-2004-10-27 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclCmdAH.c (Tcl_FormatObjCmd): Restored missing line
- from yesterday's 868489 backport that caused failed alloc's on LP64
- systems.
-
- * tests/appendComp.test: Backport test suite fixes of errors
- * tests/autoMkindex.test: revealed by -singleproc 1 -debug 1
- * tests/exec.test: options to make test.
- * tests/execute.test:
- * tests/interp.test:
- * tests/io.test:
- * tests/namespace.test:
- * tests/regexpComp.test:
- * tests/stringComp.test:
- * tests/unixInit.test:
- * tests/winPipe.test:
-
-2004-10-26 Kevin B. Kenny <kennykb@acm.org>
-
- * generic/tclCmdAH.c (Tcl_FormatObjCmd): Backport a missing bit of the
- [Bug 868489] fix.
- * generic/tclObj.c (SetBooleanFromAny): Backport fix for [Bug 1026125]
- * tests/format.test (format-19.1): Additional regression test for
- [Bug 868489].
-
-2004-10-26 Donal K. Fellows <donal.k.fellows@man.ac.uk>
-
- * doc/*.n: Backporting of documentation updates.
-
-2004-10-26 Don Porter <dgp@users.sourceforge.net>
-
- * tests/subst.test (subst-12.3-5): More tests for [Bug 1036649]
-
- * tests/compile.test (compile-12.4): Backport test for [Bug 1001997]
- * tests/timer.test (timer-10.1): Backport test for [Bug 1016167]
- * tests/tcltest.test (tcltest-12.3,4): Backport setup corrections.
- * tests/error.test (error-6.3,4,7,9): Backport of some tests.
- * tests/basic.test (basic-49.*):
- * tests/namespace.test (namespace-8.7):
- * tests/init.test (init-2.8): Updated to not rely on http package.
-
- * generic/tclThreadTest.c (ThreadEventProc): Corrected subtle bug
- where the returned (char *) from Tcl_GetStringResult(interp) continued
- to be used without copying or refcounting, while activity on the
- interp continued.
-
-2004-10-14 Donal K. Fellows <donal.k.fellows@man.ac.uk>
-
- * generic/tclUtil.c (TclMatchIsTrivial): Detect degenerate cases of
- glob matching that let us avoid scanning through hash tables.
- * generic/tclCmdIL.c (InfoCommandsCmd, InfoGlobalsCmd, InfoProcsCmd):
- (InfoVarsCmd): Use this to speed up some [info] subcommands.
-
-2004-10-08 Jeff Hobbs <jeffh@ActiveState.com>
-
- * win/tclWinFile.c (NativeIsExec): correct result of 'file executable'
- to not be case sensitive. [Bug 954263]
-
-2004-10-05 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclNamesp.c (Tcl_PopCallFrame): Removed Bug 1038021
- workaround. That bug is now fixed.
-
-2004-09-30 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclNamespace.c (TclTeardownNamespace): Tcl_Obj-ified the
- * tests/namespace.test (namespace-8.5,6): save/restore of
- ::errorInfo and ::errorCode during global namespace teardown. Revised
- the comment to clarify why this is done, and added tests that will
- fail if this is not done.
-
- * generic/tclResult.c (TclTransferResult): Added safety checks so
- that unexpected undefined ::errorInfo or ::errorCode will not lead to
- a segfault.
-
- * generic/tclVar.c (CallVarTraces): Save/restore the flag values
- * tests/var.test (var-16.1): that define part of the interpreter
- state during variable traces. [Bug 1038021]
+2007-12-31 Donal K. Fellows <dkf@users.sf.net>
-2004-09-30 Miguel Sofer <msofer@users.sf.net>
+ * doc/dict.n: Clarified meaning of dictionary values following
+ discussion on comp.lang.tcl.
- * tests/subst.test (12.2): test correction.
+2007-12-26 Miguel Sofer <msofer@users.sf.net>
-2004-09-29 Miguel Sofer <msofer@users.sf.net>
+ * generic/tclCmdIL.c: More [lsort] data handling streamlines. The
+ function MergeSort is gone, essentially inlined into Tcl_LsortObjCmd.
+ It is not a straight inlining, two loops over all lists elements where
+ merged in the process: the linked list elements are now built and
+ merged into the temporary sublists in the same pass.
- * generic/tclBasic.c (Tcl_EvalEx):
- * tests/subst.test (12.1-2): fix for buffer overflow in [subst], [Bug
- 1036649]
+2007-12-25 Miguel Sofer <msofer@users.sf.net>
-2004-09-23 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tclCmdIL.c: More [lsort] data handling streamlines. Extra
+ mem reqs of latest patches removed, restored to previous mem profile.
+ Improved -unique handling, now eliminating repeated elems immediately
+ instead of marking them to avoid reinsertion at the end.
- * unix/dltest/Makefile.in (clean): Fixup make clean rule so that it
- does not delete all files when SHLIB_SUFFIX is set to the empty string
- in a static build. [Bug 1016726]
+2007-12-23 Jeff Hobbs <jeffh@ActiveState.com>
-2004-09-18 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * generic/tclCompCmds.c (TclCompileRegexpCmd): TCL_REG_NOSUB cannot
+ * tests/regexp.test (regexp-22.2): be used because it
+ * tests/regexpComp.test: [Bug 1857126] disallows backrefs.
- * generic/tclExecute.c (TEBC-INST_LSHIFT,INST_RSHIFT): Ensure that
- large shifts end up shifting correctly. [Bug 868467]
+2007-12-21 Miguel Sofer <msofer@users.sf.net>
-2004-09-15 Daniel Steffen <das@users.sourceforge.net>
+ * generic/tclCmdIL.c: Speed patch for lsort [Patch 1856994].
- * tests/load.test (load-2.3): adopted fix for failure on darwin from
- HEAD.
+2007-12-21 Miguel Sofer <msofer@users.sf.net>
-2004-09-14 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclCmdIL.c (Tcl_LsortObjCmd, Tcl_LsearchObjCmd): Avoid
+ calling SelectObjFromSublist when there are no sublists.
- * generic/tclObj.c (Tcl_GetIntFromObj): Corrected flaw in returning
- the int value of a wideInteger. [Bug 1027690]
+2007-12-21 Miguel Sofer <msofer@users.sf.net>
-2004-09-10 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * generic/tclCmdIL.c (Tcl_LsortObjCmd): Preallocate a listObj of
+ sufficient length for the sorted list instead of growing it. Second
+ commit replaces calls to Tcl_ListObjAppenElement with direct access to
+ the internal rep.
- * generic/tclObj.c (SetIntOrWideFromAny): Rewritten integral value
- parsing code so that values do not flip so easily between numeric
- representations. Thanks to KBK for this! [Bug 868489]
+2007-12-19 Don Porter <dgp@users.sourceforge.net>
- * generic/tclIO.c (Tcl_Seek): Make sure wide seeks do not fail to set
- ::errorCode on error. [Bug 1025359]
+ *** 8.5.0 TAGGED FOR RELEASE ***
-2004-09-10 Andreas Kupries <andreask@activestate.com>
+ * changes: Updated for 8.5.0 release.
- * generic/tcl.h: Micro formatting fixes.
- * generic/tclIOGT.c: Channel version fixed, must be 3, to have
- wideseekProc. Thanks to David Graveraux <davygrvy@pobox.com>.
+2007-12-19 Jeff Hobbs <jeffh@ActiveState.com>
-2004-09-11 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclCompCmds.c (TclCompileSwitchCmd): update switch -regexp
+ * tests/switch.test-14.*: compilation to pass
+ the cflags to INST_REGEXP (changed on 12-07). Added tests for
+ switch -regexp compilation (need more). [Bug 1854399]
- * generic/tclNamespace.c (TclGetNamespaceForQualName): Resolved
- longstanding inconsistency in the treatment of the TCL_NAMESPACE_ONLY
- flag revealed by testing the 2004-09-09 commits against Itcl.
- TCL_NAMESPACE_ONLY now acts as specified in the pre-function
- comment, forcing resolution in the passed in context namespace. It has
- been incorrectly forcing resolution in the interp's current namespace.
+2007-12-18 Don Porter <dgp@users.sourceforge.net>
-2004-09-10 Miguel Sofer <msofer@users.sf.net>
+ * changes: Updated for 8.5.0 release.
- * generic/tclExecute.c (INST_CONCAT1): added a peephole optimisation
- for concatting an empty string. This enables replacing the idiom 'K $x
- [set x {}]' by '$x[set x {}]' for fastest execution.
-
-2004-09-09 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclNamesp.c (Tcl_ForgetImport): Corrected faulty logic that
- * tests/namespace.test: relied exclusively on string matching and
- failed in the presence of [rename]s. [Bug 560297]
- Also corrected faulty prevention of [namespace import] cycles. [Bug
- 1017299]
-
-2004-09-08 Kevin B. Kenny <kennykb@acm.org>
+2007-12-18 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * compat/strftime.c (_conv): Corrected a problem where hour 0 would
- format as a blank format group with %k.
- * tests/clock.test (clock-41.1): Added regression test case for %k at
- the zero hour.
+ * generic/regguts.h, generic/regc_color.c, generic/regc_nfa.c:
+ Fixes for problems created when processing regular expressions that
+ generate very large automata. An enormous number of thanks to Will
+ Drewry <wad_at_google.com>, Tavis Ormandy <taviso_at_google.com>,
+ and Tom Lane <tgl_at_sss.pgh.pa.us> from the Postgresql crowd for
+ their help in tracking these problems down. [Bug 1810264]
-2004-09-07 Kevin B. Kenny <kennykb@acm.org>
+2007-12-17 Don Porter <dgp@users.sourceforge.net>
- * generic/tclTimer.c: Removed a premature optimisation that attempted
- to store the assoc data in the client data; the optimisation caused a
- bug that [after] would overwrite its imports. [Bug 1016167]
+ * changes: Updated for 8.5.0 release.
-2004-09-02 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+2007-12-17 Miguel Sofer <msofer@users.sf.net>
- * doc/lsearch.n: Clarified meaning of -dictionary. [Bug 759545]
+ * generic/tclAlloc.c:
+ * generic/tclExecute.c:
+ * generic/tclInt.h:
+ * generic/tclThreadAlloc.c: Fix alignment for memory returned by
+ TclStackAlloc; insure that all memory allocators align to 16-byte
+ boundaries on 64 bit platforms [Bug 1851832, 1851524]
-2004-09-01 Jeff Hobbs <jeffh@ActiveState.com>
+2007-12-14 Jeff Hobbs <jeffh@ActiveState.com>
- * win/tclWinReg.c (BroadcastValue): WIN64 cast corrections
+ * generic/tclIOUtil.c (FsAddMountsToGlobResult): fix the tail
+ conversion of vfs mounts. [Bug 1602539]
- * win/tclWinDde.c (DdeClientWindowProc):
- (DdeServicesOnAck, DdeEnumWindowsCallback): WIN64 corrections
+ * win/README: updated notes
- * win/tclWin32Dll.c (TclWinCPUID): need _asm for WIN64 (Itanium),
- until we have it, just return unknown. [Bug 1020445]
+2007-12-14 Pat Thoyts <patthoyts@users.sourceforge.net>
-2004-08-30 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * tests/winFile.test: Fixed tests for win2k with long machine name
- * generic/tclCmdMZ.c (Tcl_StringObjCmd): Stop [string map] from
- crashing when its map and input string are the same object.
+2007-12-14 Pat Thoyts <patthoyts@users.sourceforge.net>
-2004-08-27 Daniel Steffen <das@users.sourceforge.net>
+ * win/nmakehlp.c: Support compilation with MSVC9 for AMD64.
+ * win/makefile.vc:
- * tests/env.test: macosx fixes.
+2007-12-13 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
-2004-08-19 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * doc/trace.n: Clarified documentation of enterstep and leavestep
+ traces, including adding example. [Bug 614282, 1701540, 1755984]
- * generic/tclScan.c (Tcl_ScanObjCmd, ValidateFormat): Ensure that the
- %ld conversion works correctly on 64-bit platforms. [Bug 1011860]
+2007-12-12 Don Porter <dgp@users.sourceforge.net>
-2004-08-16 Miguel Sofer <msofer@users.sf.net>
+ * doc/IntObj.3: Update docs for the Tcl_GetBignumAndClearObj() ->
+ Tcl_TakeBignumFromObj() revision [TIP 298]. Added docs for the
+ Tcl_InitBignumFromDouble() routine. [Bug 1446971].
- * doc/SetVar.3:
- * generic/tclTest.c (TestseterrorcodeCmd):
- * generic/tclVar.c (TclPtrSetVar):
- * tests/result.test (result-4.*, result-5.*): [Bug 1008314]
- detected and fixed by dgp.
+ * changes: Updated for 8.5.0 release.
-2004-08-13 Don Porter <dgp@users.sourceforge.net>
+2007-12-10 Jeff Hobbs <jeffh@ActiveState.com>
- * library/msgcat/msgcat.tcl: Added checks to prevent [mclocale]
- * tests/msgcat.test: from registering filesystem paths to possibly
- malicious code to be evaluated by a later [mcload].
- * library/msgcat/pkgIndex.tcl: Bump to msgcat 1.3.3
+ * generic/tclUtil.c (TclReToGlob): reduce escapes in conversion
+ when not necessary
-2004-08-10 Zoran Vasiljevic <vasiljevic@users.sf.net>
+ * generic/tclInt.decls: move TclByteArrayMatch and TclReToGlob
+ * generic/tclIntDecls.h: to tclInt.h from stubs.
+ * generic/tclStubInit.c: Add flags var to TclByteArrayMatch for
+ * generic/tclInt.h: future extensibility
+ * generic/tcl.h: define TCL_MATCH_EXACT doc for Tcl_StringCaseMatch.
+ * doc/StrMatch.3: It is compatible with existing usage.
+ * generic/tclExecute.c (INST_STR_MATCH): flag for TclByteArrayMatch
+ * generic/tclUtil.c (TclByteArrayMatch, TclStringMatchObj):
+ * generic/tclRegexp.c (Tcl_RegExpExecObj):
+ * generic/tclCmdMZ.c (StringMatchCmd): Use TclStringMatchObj
+ * tests/string.test (11.9.* 11.10.*): more tests
- * unix/tclUnixThrd.c (TclpThreadCreate): changed handling of the
- returned thread ID since broken on 64-bit systems (Cray). Thanks to
- Rob Ratcliff for reporting the bug.
+2007-12-10 Joe English <jenglish@users.sourceforge.net>
-2004-07-30 Don Porter <dgp@users.sourceforge.net>
+ * doc/string.n, doc/UniCharIsAlpha.3: Fix markup errors.
+ * doc/CrtCommand.3, doc/CrtMathFnc.3, doc/FileSystem.3,
+ * doc/GetStdChan.3, doc/OpenFileChnl.3, doc/SetChanErr.3,
+ * doc/eval.n, doc/filename.n: Consistency: Move "KEYWORDS" section
+ after "SEE ALSO".
- * generic/tclEvent.c (Tcl_Finalize): Re-organized Tcl_Finalize so
- that Tcl_ExitProc's that call Tcl_Finalize recursively do not cause
- deadlock. [Patch 999084, fixes Tk Bug 714956]
+2007-12-10 Daniel Steffen <das@users.sourceforge.net>
-2004-07-30 Daniel Steffen <das@users.sourceforge.net>
+ * tools/genStubs.tcl: fix numerous issues handling 'macosx',
+ 'aqua' or 'x11' entries interleaved
+ with 'unix' entries [Bug 1834288]; add
+ genStubs::export command
+ [Tk FR 1716117]; cleanup formatting.
- * unix/configure:
- * unix/tcl.m4 (SC_CONFIG_CFLAGS): Darwin: instead of setting PLAT_OBJS
- to explict object files in tcl.m4, refer to MAC_OSX_OBJS makefile var.
- * unix/Makefile.in: added MAC_OSX_OBJS variable.
+ * generic/tcl.decls: use new genstubs 'export' command to
+ * generic/tclInt.decls: mark exported symbols not in stubs
+ * generic/tclTomMath.decls: table [Tk FR 1716117]; cleanup
+ formatting.
-2004-07-28 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclDecls.h: regen with new genStubs.tcl.
+ * generic/tclIntDecls.h: [Bug 1834288]
+ * generic/tclIntPlatDecls.h:
+ * generic/tclPlatDecls.h:
+ * generic/tclStubInit.c:
- * generic/tclMain.c (Tcl_Main, StdinProc): Append newline only to
- * tests/basic.test (basic-46.1): incomplete scripts as part
- of multi-line script construction. Do not add an extra trailing
- newline to the complete script. [Bug 833150]
+2007-12-09 Jeff Hobbs <jeffh@ActiveState.com>
-2004-07-26 Jeff Hobbs <jeffh@ActiveState.com>
+ * tests/io.test, tests/chanio.test (io-73.1): Make sure to invalidate
+ * generic/tclIO.c (SetChannelFromAny): internal rep only after
+ validating channel rep. [Bug 1847044]
- *** 8.4.7 TAGGED FOR RELEASE ***
+2007-12-08 Donal K. Fellows <dkf@users.sf.net>
- * tests/io.test (io-61.1): create file in binary mode for x-plat.
+ * doc/expr.n, doc/mathop.n: Improved the documentation of the
+ operators. [Bug 1823622]
-2004-07-25 Pat Thoyts <patthoyts@users.sourceforge.net>
+ * generic/tclBasic.c (builtInCmds): Corrected list of hidden and
+ * doc/interp.n (SAFE INTERPRETERS): exposed commands so that the
+ documentation and reality now match. [Bug 1662436]
- * generic/tclThreadAlloc.c: Moved the tclInt.h include to provide
- Tcl_Panic which is now required for non-threaded build.
+2007-12-07 Jeff Hobbs <jeffh@ActiveState.com>
-2004-07-22 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclExecute.c (TclExecuteByteCode INST_REGEXP):
+ * generic/tclCompCmds.c (TclCompileRegexpCmd): Pass correct RE
+ compile flags at compile time, and use TCL_REG_NOSUB.
- * tests/eofchar.data (removed): Test io-61.1 now generates its own
- * tests/io.test: file of test data as needed.
+ * generic/tclIOCmd.c (FinalizeIOCmdTSD, Tcl_PutsObjCmd): cache
+ stdout channel object for [puts $str] calls.
-2004-07-21 Don Porter <dgp@users.sourceforge.net>
- * win/tclWinDde.c: Bump to dde 1.2.3 to cover changes
- * library/dde/pkgIndex.tcl: committed on 2004-06-14.
+2007-12-06 Don Porter <dgp@users.sourceforge.net>
- * changes: Updated for Tcl 8.4.7 release.
+ * README: Remove mention of dead comp.lang.tcl.announce
+ newsgroup. [Bug 1846433].
-2004-07-20 Jeff Hobbs <jeffh@ActiveState.com>
+ * unix/README: Mention the stub library created by `make` and warn
+ about the effect of embedded paths in the installed binaries.
+ Thanks to Larry Virden. [Bug 1794084]
- * generic/tclEvent.c: Correct threaded obj allocator to
- * generic/tclInt.h: fully cleanup on exit and allow for
- * generic/tclThreadAlloc.c: reinitialization. [Bug 736426]
- * unix/tclUnixThrd.c: (mistachkin, kenny)
- * win/tclWinThrd.c:
+ * doc/AddErrInfo.3: Documentation for the new routines in TIP 270.
+ * doc/Interp.3:
+ * doc/StringObj.3:
-2004-07-20 Daniel Steffen <das@users.sourceforge.net>
+2007-12-06 Don Porter <dgp@users.sourceforge.net>
- * unix/tcl.m4: fixed Darwin autoconf breakage caused by recent CFLAGS
- reordering.
- * unix/configure: regen
+ * doc/namespace.n: Documentation for zero-argument form of
+ [namespace import] (TIP 261) [Bug 1596416]
- * unix/tclConfig.sh.in: replaced EXTRA_CFLAGS with CFLAGS.
- * unix/dltest/Makefile.in: replaced EXTRA_CFLAGS with DEFS.
+2007-12-06 Jeff Hobbs <jeffh@ActiveState.com>
- * macosx/tclMacOSXBundle.c: dynamically acquire address for
- CFBundleOpenBundleResourceMap symbol, since it is only present in
- full CoreFoundation on Mac OS X and not in CFLite on pure Darwin.
+ * generic/tclInt.h: add TclGetChannelFromObj decl
+ (TclMatchIsTrivial): simplify TclMatchIsTrivial to remove ] check.
-2004-07-19 Jeff Hobbs <jeffh@ActiveState.com>
+2007-12-06 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * unix/Makefile.in, unix/tcl.m4: move (C|LD)FLAGS after their
- * unix/configure.in, unix/configure: _DEFAULT to allow for env setting
- to override m4 switches.
- Consolidate header checks to limit redundancy in configure.
- (CFLAGS_WARNING): Remove -Wconversion, add -fno-strict-aliasing for
- gcc builds (need to suppress 3.x type puning warnings).
- (SC_ENABLE_THREADS): Set m4 to force threaded build when built against
- a threaded Tcl core.
- Reorder configure.in for better 64-bit build configuration, replacing
- EXTRA_CFLAGS with CFLAGS. [Bug 874058]
-2004-07-19 Zoran Vasiljevic <vasiljevic@users.sf.net>
+ * generic/tclBasic.c (Tcl_CreateInterp): Simplify the setting up of
+ * generic/tclIOCmd.c (TclInitChanCmd): the [chan] ensemble. This
+ * library/init.tcl: gets rid of quite a bit of
+ code and makes it possible to understand the whole with less effort.
- * win/tclwinThrd.c: redefined MASTER_LOCK to call TclpMasterLock.
- Fixes [Bug 987967]
+ * generic/tclCompCmds.c (TclCompileEnsemble): Ensure that the right
+ number of tokens are copied. [Bug 1845320]
-2004-07-16 Andreas Kupries <andreask@activestate.com>
+ * generic/tclNamesp.c (TclMakeEnsemble): Added missing release of a
+ DString. [Bug 1845397]
- * generic/tclIOCmd.c (Tcl_FcopyObjCmd): Corrected a typo in the
- generation of error messages and simplified by reusing data in a
- variable instead of retrieving the string again. Fixes [Bug 835289]
+2007-12-05 Jeff Hobbs <jeffh@ActiveState.com>
- * doc/OpenFileChnl.3: Added description of the behaviour of
- Tcl_ReadChars when its 'charsToRead' argument is set to -1. Fixes [Bug
- 934511]
+ * generic/tclIO.h: Create Tcl_Obj for Tcl channels to reduce
+ * generic/tclIO.c: overhead in lookup by Tcl_GetChannel. New
+ * generic/tclIOCmd.c: TclGetChannelFromObj for internal use.
+ * generic/tclIO.c (WriteBytes, WriteChars): add opt check to avoid
+ EOL translation when not linebuffered or using lf. [Bug 1845092]
- * doc/CrtCommand.3: Added note that the arguments given to the command
- proc of a Tcl_CreateCommand are in utf8 since Tcl 8.1. Closing [Patch
- 414778]
+2007-12-05 Miguel Sofer <msofer@users.sf.net>
- * doc/ChnlStack.3: Removed the declaration that the interp argument to
- Tcl_(un)StackChannel can be NULL. This fixes [Bug 881220], reported by
- Marco Maggi <marcomaggi@users.sourceforge.net>.
+ * tests/stack.test: made the tests for stack overflow not care
+ about which mechanism caused the error (interp's recursion limit
+ or C-stack depth detector).
- * tests/socket.test: Accepted two new testcases by Stuart Casoff
- <stwo@users.sourceforge.net> checking that -server and -async don't go
- together [Bug 796534]
+2007-12-05 Jeff Hobbs <jeffh@ActiveState.com>
- * unix/tclUnixNotfy.c (NotifierThreadProc): Accepted Joe Mistachkin's
- patch for [Bug 990500], properly closing the notifier thread when its
- exits.
+ * win/configure, win/tcl.m4 (LIBS_GUI): mingw needs -lole32
+ -loleaut32 but not msvc for Tk's [send]. [Bug 1844749]
-2004-07-15 Andreas Kupries <andreask@activestate.com>
+2007-12-05 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * unix/tclUnixThrd.c (TclpFinalizeMutex): Accepted Joe Mistachkin's
- patch for [Bug 990453], closing leakage of mutexes. They were not
- destroyed properly upon finalization.
+ * generic/tclCmdIL.c (Tcl_LsearchObjCmd): Prevent shimmering crash
+ when -exact and -integer/-real are mixed. [Bug 1844789]
-2004-07-15 Zoran Vasiljevic <vasiljevic@users.sf.net>
+2007-12-03 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclEvent.c (NewThreadProc): Backout of changes to fix [Bug
- 770053]. See SF bugreport for more info.
+ * unix/tclUnixChan.c (CreateSocketAddress): Add extra #ifdef-fery to
+ make code compile on BSD 5. [Bug 1618235, again]
- * generic/tclNotify.c (TclFinalizeNotifier): Added conditional
- notifier finalization based on the fact that an TclInitNotifier has
- been called for the current thread. This fixes [Bug 770053] again.
- Hopefully this time w/o unwanted side-effects.
+2007-12-03 Don Porter <dgp@users.sourceforge.net>
-2004-07-14 Andreas Kupries <andreask@activestate.com>
+ * library/tcltest/tcltest.tcl: Bump tcltest to version 2.3.0 so that
+ * library/tcltest/pkgIndex.tcl: we release a stable tcltest with a
+ * unix/Makefile.in: stable Tcl.
+ * win/Makefile.in:
- * generic/tclIO.h (CHANNEL_INCLOSE): New flag. Set in Tcl_Close
- * generic/tclIO.c (Tcl_UnregisterChannel): while the close callbacks
- * generic/tclIO.c (Tcl_Close): are run. Checked in
- Tcl_Close and Tcl_Unregister to prevent recursive call of [close] in
- the close-callbacks. This is a possible error made by implementors of
- virtual filesystems based on 'tclvfs', thinking that they have to
- close the channel in the close handler for the filesystem.
+2007-12-03 Jeff Hobbs <jeffh@ActiveState.com>
-2004-07-14 Andreas Kupries <andreask@activestate.com>
+ * win/configure, win/tcl.m4 (LIBS_GUI): remove ole32.lib oleaut32.lib
- * generic/tclIO.c:
- * generic/tclIO.h:
- Not reverting, but #ifdef'ing the changes from May 19, 2004 out of the
- core. This removes the ***POTENTIAL INCOMPATIBILITY*** for channel
- drivers it introduced. This has become possible due to Expect gaining
- a BlockModeProc and now handling blockingg and non-blocking modes
- correctly. Thus [Bug 943274] is still fixed if a recent enough version
- of Expect is used.
+2007-12-03 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * doc/CrtChannel.3: Added warning about usage of a channel without a
- BlockModeProc.
+ * generic/tclCompCmds.c (TclCompileSwitchCmd): Adjusted the [switch]
+ * generic/tclCmdMZ.c (Tcl_SwitchObjCmd): command so that when
+ passed two arguments, no check for options are performed. This is OK
+ since in the two-arg case, detecting an option would definitely lead
+ to a syntax error. [Patch 1836519]
-2004-07-15 Andreas Kupries <andreask@pliers.activestate.com>
+2007-11-29 Jeff Hobbs <jeffh@ActiveState.com>
- * generic/tclIOCmd.c (Tcl_PutsObjCmd): Added length check to the old
- depreceated newline syntax, to ensure that only "nonewline" is
- accepted. [Bug 985869] (mistachkin)
+ * win/makefile.vc: add ws2_32.lib to baselibs
+ * win/configure, win/tcl.m4: add ws2_32.lib / -lws2_32 to build.
+ * win/tclWinSock.c: remove dyn loading of winsock, assume that it is
+ always available now.
-2004-07-13 Jeff Hobbs <jeffh@ActiveState.com>
+2007-11-29 Don Porter <dgp@users.sourceforge.net>
- * README, generic/tcl.h, tools/tcl.wse.in: bumped to
- * unix/configure, unix/configure.in, unix/tcl.spec: patchlevel
- * win/README.binary, win/configure, win/configure.in: 8.4.7
+ * generic/tclWinSock.c (InitializeHostName): Correct error in
+ buffer length tracking. After gethostname() writes into a buffer,
+ convert only the written string to internal encoding, not the whole
+ buffer.
-2004-07-13 Zoran Vasiljevic <vasiljevic@users.sf.net>
+2007-11-28 Don Porter <dgp@users.sourceforge.net>
- * generic/tclEvent.c (NewThreadProc): Fixed broken build on Windows
- caused by missing TCL_THREAD_CREATE_RETURN. This is backported from
- HEAD. Thnx to Kevin Kenny for spotting this.
+ * generic/tclConfig.c: Corrected failure of the [::foo::pkgconfig]
+ command to clean up registered configuration data when the query
+ command is deleted from the interp. [Bug 983501]
-2004-07-03 Miguel Sofer <msofer@users.sf.net>
+ * generic/tclNamesp.c (Tcl_SetEnsembleMappingDict): Added checks
+ that the dict value passed in is in the format required to make the
+ internals of ensembles work. [Bug 1436096]
- * generic/tclExecute.c (ExprRoundFunc):
- * tests/expr-old.test (39.1): added support for wide integers to
- round(); [Bug 908375], reported by Hemang Lavana.
+ * generic/tclIO.c: Simplify test and improve accuracy of error
+ message in latest changes.
-2004-07-02 Jeff Hobbs <jeffh@ActiveState.com>
+2007-11-28 Pat Thoyts <patthoyts@users.sourceforge.net>
- * generic/regcomp.c (stid): correct minor pointer size error
+ * generic/tclIO.c: -eofchar must support no eofchar.
- * generic/tclPipe.c (TclCreatePipeline): Add 2>@1 as a special
- * tests/exec.test: case redir of stderr to the result output.
+2007-11-27 Miguel Sofer <msofer@users.sf.net>
-2004-07-02 Vince Darley <vincentdarley@users.sourceforge.net>
+ * generic/tclBasic.c: remove unneeded call in Tcl_CreateInterp, add
+ comments.
- * tests/fileSystem.test: new tests backported
- * win/tclWin32Dll.c: compilation fix for VC++5.2
+2007-11-27 Don Porter <dgp@users.sourceforge.net>
-2004-06-29 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * win/tclWinSock.c: Add mising encoding conversion of the [info
+ hostname] value from the system encoding to Tcl's internal encoding.
- * library/safe.tcl: Make sure that the temporary variable is
- local to the namespace and not inadvertently global. [Bug 981733]
+ * doc/chan.n: "Fix" the limitation on channel -eofchar
+ * doc/fconfigure.n: values to single byte characters by documenting
+ * generic/tclIO.c: it and making it fail loudly. Thanks to Stuart
+ * tests/chan.test: Cassoff for contributing the fix. [Bug 800753]
-2004-06-22 Zoran Vasiljevic <vasiljevic@users.sf.net>
+2007-11-26 Miguel Sofer <msofer@users.sf.net>
- * generic/tclEvent.c:
+ * generic/tclBasic.c:
* generic/tclInt.h:
- * unix/tclUnixNotfy.c:
- * unix/tclUnixThrd.c:
- * win/tclWinThrd.c: See bug report for more information about what it
- does. [Bug 770053]
-
- * tests/unixNotfy.test: rewritten to use tcltest::threadReap to
- gracefully wait for the test thread to exit. Otherwise we got a race
- condition with main thread exiting before the test thread. This
- exposed the long-standing Tcl lib issue with resource
- garbage-collection on application exit.
-
-2004-06-21 Mo DeJong <mdejong@users.sourceforge.net>
-
- * win/tclWin32Dll.c (DllMain, _except_dllmain_detach_handler)
- (TclpCheckStackSpace, _except_checkstackspace_handler, TclWinCPUID)
- (_except_TclWinCPUID_detach_handler):
- * win/tclWinChan.c (Tcl_MakeFileChannel)
- (_except_makefilechannel_handler):
- * win/tclWinFCmd.c (DoRenameFile, _except_dorenamefile_handler)
- (DoCopyFile, _except_docopyfile_handler):
- Rework pushing of exception handler function pointer so that compiling
- with gcc -O3 works. Remove empty function call to avoid compiler
- warning. Mark the DllMain function as noinline to avoid compiler error
- from duplicated asm labels in generated code.
-
-2004-06-14 Pat Thoyts <patthoyts@users.sourceforge.net>
-
- * tests/winDde.test: Fixed -async test
- * win/tclWinDde.c: Backported the fix from 8.5 to avoid hanging in the
- presence of applications that do not process Window messages.
-
-2004-06-10 Andreas Kupries <andreask@activestate.com>
-
- * generic/tclDecls.h: Regenerated on a unix box. The Win/DOS
- * generic/tclIntDecls.h: EOLs from the last regen screwed up
- * generic/tclIntPlatDecls.h: compilation with an older gcc.
- * generic/tclPlatDecls.h:
- * generic/tclStubInit.c:
-
-2004-06-10 Zoran Vasiljevic <vasiljevic@users.sf.net>
-
- * generic/tclIOUtil.c: partially corrected [Bug 932314]. Also,
- corrected return values of Tcl_FSChdir() to reflect those of the
- underlying platform-specific call. Originally, return codes were mixed
- with those of Tcl.
-
-2004-06-08 Miguel Sofer <msofer@users.sf.net>
-
- * generic/tclCompile.c: handle warning [Bug 969066]
-
-2004-06-05 Kevin B. Kenny <kennykb@acm.org>
-
- * generic/tcl.h: Corrected Tcl_WideInt declarations so that the mingw
- build works again.
- * generic/tclDecls.h: Changes to the tests for
- * generic/tclInt.decls: clock frequency in Tcl_WinTime
- * generic/tclIntDecls.h: so that any clock frequency is
- * generic/tclIntPlatDecls.h: accepted provided that all
- * generic/tclPlatDecls.h: CPU's in the system share a
- * generic/tclStubInit.c: common chip, and hence,
- * tests/platform.test (platform-1.3): presumably, a common clock.
- * win/tclWin32Dll.c (TclWinCPUID): This change necessitated a
- * win/tclWinTest.c (TestwincpuidCmd) small burst of assembly code
- * win/tclWinTime.c (Tcl_GetTime): to read CPU ID information,
- which was added as TclWinCPUID in the internal Stubs. To test this
- code in the common case of a single-processor machine, a
- 'testwincpuid' command was added to tclWinTest.c, and a test case in
- platform.test. Thanks to Jeff Godfrey and Richard Suchenwirth for
- reporting this bug. [Bug 976722]
-
-2004-05-27 Kevin B. Kenny <kennykb@acm.org>
-
- * tests/clock.test: Added a single test for the presence of %G in
- [clock format], and conditioned out the clock-10.x series if they're
- all going to fail because of a broken strftime() call. [Bug 961714]
-
-2004-05-27 Reinhard Max <max@suse.de>
-
- * generic/tclEncoding.c:
- * tests/encoding.test: added support and tests for translating
- embedded null characters between real nullbytes and the internal
- representation on input/output. [Bug 949905]
-
-2004-05-26 Don Porter <dgp@users.sourceforge.net>
-
- * library/tcltest/tcltest.tcl: Correction to debug prints and testing
- * library/tcltest/pkgIndex.tcl: if TCLTEST_OPTIONS value. Corrected
- * tests/tcltest.test: double increment of numTestFiles in
- -singleproc 1 configurations. Updated tcltest-19.1 to tcltest 2.1
- behavior. Corrected tcltest-25.3 to not falsely report a failure in
- tcltest.test. Bumped to tcltest 2.2.6. [Bugs 960560, 960926]
-
-2004-05-25 Jeff Hobbs <jeffh@ActiveState.com>
-
- * doc/http.n (http::config): add -urlencoding option (default utf-8)
- * library/http/http.tcl: that specifies encoding conversion of
- * library/http/pkgIndex.tcl: args for http::formatQuery. Previously
- * tests/http.test: undefined, RFC 2718 says it should be
- utf-8. 'http::config -urlencoding {}' returns previous behavior,
- which will throw errors processing non-latin-1 chars. Bumped http
- package to 2.5.0.
-
-2004-05-25 Kevin Kenny <kennykb@acm.org>
-
- * tests/winFCmd.test: Correct test for the presence of a CD-ROM so
- that it doesn't misdetect some other sort of filesystem with a
- write-protected root as being a CD-ROM drive. [Bug 918267]
+ * unix/tclUnixInit.c:
+ * unix/tclUnixThrd.c: Fix stack checking via workaround for bug in
+ glibc's pthread_attr_get_np, patch from [Bug 1815573]. Many thanks to
+ Sergei Golovan (aka Teo) for detecting the bug and helping diagnose
+ and develop the fix.
-2004-05-24 Jeff Hobbs <jeffh@ActiveState.com>
+2007-11-24 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclExecute.c (VerifyExprObjType): use GET_WIDE_OR_INT to
- properly have tclIntType used for smaller values. This corrects TclX
- bug 896727 and any other 3rd party extension that created math
- functions but was not yet WIDE_INT aware in them.
+ * generic/tclCompCmds.c (TclCompileDictAppendCmd): Fix bug in [dict
+ append] compiler which caused strange stack corruption. [Bug 1837392]
-2004-05-24 Miguel Sofer <msofer@users.sf.net>
+2007-11-23 Andreas Kupries <andreask@activestate.com>
- * doc/set.n: accurate description of name resolution process,
- referring to namespace.n for details [Bug 959180]
+ * generic/tclIORChan.c: Fixed a problem with reflected channels. 'chan
+ postevent' is defined to work only from within the interpreter
+ containing the handler command. Sensible, we want only handler
+ commands to use it. It identifies the channel by handle. The channel
+ moves to a different interpreter or thread. The interpreter containing
+ the handler command doesn't know the channel any longer. 'chan
+ postevent' fails, not finding the channel any longer. Uhm.
-2004-05-22 Miguel Sofer <msofer@users.sf.net>
+ Fixed by creating a second per-interpreter channel table, just for
+ reflected channels, where each interpreter remembers for which
+ reflected channels it has the handler command. This info does not move
+ with the channel itself. The table is updated by 'chan create', and
+ used by 'chan postevent'.
- * generic/tclVar.c (TclObjUnsetVar2): backported fix [Bug 735335] and
- new (in tcl8.4) exteriorisations of [Bug 736729] due to the use of
- tclNsVarNameType obj types. The consequences of [Bug 736729] should be
- the same as in tcl8.3 and previous versions. The use of
- tclNsVarNameType objs is still disabled, pending a decision by the
- release manager.
+ * tests/ioCmd.test: Updated the testsuite.
-2004-05-19 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+2007-11-23 Jeff Hobbs <jeffh@ActiveState.com>
- * win/tclWinFile.c (TclpMatchInDirectory): fix for an issue where
- there was a sneak path from Tcl_DStringFree to SetErrorCode(0). The
- result was that the error code could be reset between a call to
- FindFirstFile and the check of its status return, leading to a bizarre
- error return of {POSIX unknown {No error}}. (Found in unplanned test -
- no incident logged at SourceForge.)
+ * generic/tclVar.c (Tcl_ArrayObjCmd): handle the right data for
+ * tests/var.test (var-14.2): [array names $var -glob $ptn]
-2004-05-19 Andreas Kupries <andreask@activestate.com>
+2007-11-23 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * generic/tclIO.c: Fixed [SF Tcl Bug 943274]. This is the same problem
- * generic/tclIO.h: as [SF Tcl Bug 462317], see ChangeLog entry
- 2001-09-26. The fix done at that time is incomplete. It is possible to
- get around it if the actual read operation is defered and not executed
- in the event handler itself. Instead of tracking if we are in an read
- caused by a synthesized fileevent we now track if the OS has delivered
- a true event = actual data and bypass the driver if a read finds that
- there is no actual data waiting. The flag is cleared by a short or
- full read. [[this bug amended 2004-07-14]]
+ * generic/tclCmdMZ.c (String*Cmd, TclInitStringCmd): Rebuilt [string]
+ * generic/tclCompCmds.c (TclCompileString*Cmd): as an ensemble.
-2004-05-18 Kevin B. Kenny <kennykb@acm.org>
+2007-11-22 Donal K. Fellows <dkf@users.sf.net>
- * compat/strftime.c (_fmt, ISO8601Week):
- * doc/clock.n:
- * tests/clock.test: Major rework to the handling of ISO8601 week
- numbers. Now passes all the %G and %V test cases on Windows, Linux and
- Solaris [Bugs 500285, 500389, and 852944]
+ * generic/tclDictObj.c (Dict*Cmd,TclInitDictCmd): Rebuilt the [dict]
+ * generic/tclCompCmds.c (TclCompileDict*Cmd): command as an ensemble.
-2004-05-17 Kevin B. Kenny <kennykb.@acm.org>
+2007-11-22 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * generic/tclInt.decls: Restored TclpTime_t kludge to all places
- * generic/tclIntPlatDecls.h: where it appeared before the changes of
- * unix/tclUnixPort.h 14 May, because use of native time_t in
- * unix/tclUnixTime.h its place requires the 8.5 header
- * win/tclWinTime.h: reforms. [Bug 955146]
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd): Rewrote the [string] and
+ * generic/tclDictObj.c (Tcl_DictObjCmd): [dict] implementations to be
+ ready for conversion to ensembles.
-2004-05-17 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * tests/string.test (string-12.22): Flag shimmering bug found in
+ [string range].
- * doc/OpenFileChnl.3: Documented type of 'offset' argument to Tcl_Seek
- was wrong. [Bug 953374]
+2007-11-21 Donal K. Fellows <dkf@users.sf.net>
-2004-05-14 Kevin B. Kenny <kennykb@acm.org>
+ * generic/tclCompCmds.c (TclCompileEnsemble): Rewrote the ensemble
+ compiler to remove many of the limitations. Can now compile scripts
+ that use unique prefixes of subcommands, and which have mappings of a
+ command to multiple words (provided the first is a compilable command
+ of course).
- * generic/tclInt.decls: Promoted TclpLocaltime and TclpGmtime
- * generic/tclIntDecls.h: from Unix-specific stubs to the generic
- * generic/tclIntPlatDecls.h: internal Stubs table. Reran 'genstubs'
- * generic/tclStubInit.c:
- * unix/tclUnixPort.h:
+2007-11-21 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * generic/tclClock.c: Changed a buggy 'GMT' timezone specification to
- the correct 'GMT0'. [Bug 922848]
+ * generic/tclNamesp.c (TclMakeEnsemble): Factor out the code to set up
+ a core ensemble from a table of information about subcommands, ready
+ for reuse within the core.
- * unix/tclUnixThrd.c: Moved TclpGmtime and TclpLocaltime to
- unix/tclUnixTime.c where they belong.
+ * generic/various: Start to return more useful Error codes, currently
+ mainly on assorted lookup failures.
- * unix/tclUnixTime.c (TclpGmtime, TclpLocaltime, TclpGetTimeZone,
- (ThreadSafeGMTime[removed], ThreadSafeLocalTime[removed],
- (SetTZIfNecessary, CleanupMemory): Restructured to make sure that the
- same mutex protects all calls to localtime, gmtime, and tzset. Added a
- check in front of those calls to make sure that the TZ env var hasn't
- changed since the last call to tzset, and repeat tzset if necessary.
- [Bug 940278] Removed a buggy test of the Daylight Saving Time
- information in 'gettimeofday' in favor of applying 'localtime' to a
- known value. [Bug 922848]
+2007-11-20 Donal K. Fellows <dkf@users.sf.net>
- * tests/clock.test (clock-3.14): Added test to make sure that changes
- to $env(TZ) take effect immediately.
+ * generic/tclDictObj.c: Changed the underlying implementation of the
+ hash table used in dictionaries to additionally keep all entries in
+ the hash table in a linked list, which is only ever added to at the
+ end. This makes iteration over all entries in the dictionary in
+ key insertion order a trivial operation, and so cleans up a great deal
+ of complexity relating to dictionary representation and stability of
+ iteration order.
- * win/tclWinTime.c (TclpLocaltime, TclpGmtime): Added porting layer
- for 'localtime' and 'gmtime' calls.
+ ***POTENTIAL INCOMPATIBILITY***
+ For any code that depended on the (strange) old iteration order.
-2004-05-10 David Gravereaux <davygrvy@pobox.com>
+ * generic/tclConfig.c (QueryConfigObjCmd): Correct usage of
+ Tcl_WrongNumArgs.
- * win/tclWinPipe.c (BuildCommandLine): Append a space when the path
- got primed.
- (TclpCreateProcess): When under NT, with no console, and executing a
- DOS application, the path priming does not need an ending space as
- BuildCommandLine() will append one for us.
+2007-11-19 Don Porter <dgp@users.sourceforge.net>
-2004-05-07 Miguel Sofer <msofer@users.sf.net>
+ *** 8.5b3 TAGGED FOR RELEASE ***
- * doc/unset.n: added upvar.n to the "see also" list
+ * README: Bump version number to 8.5b3.
+ * generic/tcl.h:
+ * library/init.tcl:
+ * tools/tcl.wse.in:
+ * unix/configure.in:
+ * unix/tcl.spec:
+ * win/configure.in:
-2004-05-05 David Gravereaux <davygrvy@pobox.com>
+ * unix/configure: autoconf (2.59)
+ * win/configure:
- * generic/tclEvent.c: TclSetLibraryPath's use of caching the stringrep
- of the pathPtr object to TclGetLibraryPath called from another thread
- was ineffective if the original's stringrep had been invalidated as
- what happens when it gets muted to a list.
+ * changes: Updated for 8.5b3 release.
- * generic/tclEncoding.c: Added FreeEncoding(systemEncoding) in
- TclFinalizeEncodingSubsystem because its ref count was incremented in
- TclInitEncodingSubsystem.
+2007-11-19 Kevin Kenny <kennykb@users.sourceforge.net>
- * win/tclWin32Dll.c: Structured Exception Handling added around
- Tcl_Finalize called from DllMain's DLL_PROCESS_DETACH. We can't be
- 100% assured that Tcl is being unloaded by the OS in a stable
- condition and we need to protect the exit handlers should the stack be
- in a hosed state. AT&T style assembly for SEH under MinGW included,
- too. [Patch 858493]
+ * library/tzdata/Africa/Cairo:
+ * library/tzdata/America/Campo_Grande:
+ * library/tzdata/America/Caracas:
+ * library/tzdata/America/Cuiaba:
+ * library/tzdata/America/Havana:
+ * library/tzdata/America/Sao_Paulo:
+ * library/tzdata/Asia/Damascus:
+ * library/tzdata/Asia/Gaza:
+ * library/tzdata/Asia/Tehran: Olson's tzdata2007i imported.
- Also added DisableThreadLibraryCalls() for the DLL_PROCESS_ATTACH
- case. We're not interested in knowing about DLL_THREAD_ATTACH, so
- disable the notices.
+2007-11-18 Daniel Steffen <das@users.sourceforge.net>
- * generic/tclInt.h:
- * generic/tclThread.c:
- * generic/tclEvent.c:
- * unix/tclUnixThrd.c:
- * win/tclWinThrd.c: Provisions made so masterLock, initLock,
- allocLock and joinLock mutexes can be recovered during Tcl_Finalize.
+ * generic/tclExecute.c (TclExecuteByteCode:INST_EXIST_*): Fix read
+ traces not firing on non-existent array elements. [Bug 1833522]
- * win/tclWinSock.c:
- (SocketThreadExitHandler): Don't call TerminateThread when
- WaitForSingleObject returns a timeout. Tcl_Finalize called from
- DllMain will pause all threads. Trust that the thread will get the
- close notice at a later time if it does ever wake up before being
- cleaned up by the system anyway.
- (SocketEventProc): connect errors should fire both the readable and
- writable handlers because this is how it works on UNIX. [Bug 794839]
+2007-11-16 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * win/coffbase.txt: Added the tls extension to the list of preferred
- load addresses.
+ * generic/tclCmdIL.c (TclInitInfoCmd): Rename the implementation
+ commands for [info] to be something more "expected".
-2004-05-05 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclCompCmds.c (TclCompileInfoExistsCmd): Compiler for the
+ [info exists] subcommand.
+ (TclCompileEnsemble): Cleaned up version of ensemble compiler that was
+ in TclCompileInfoCmd, but which is now much more generally applicable.
- * tests/unixInit.test (unixInit-2.10): Test correction for Mac OSX.
- Be sure to consistently compare normalized path names. Thanks to
- Steven Abner (tauvan). [Bug 948177]
+ * generic/tclInt.h (ENSEMBLE_COMPILE): Added flag to allow for cleaner
+ turning on and off of ensemble bytecode compilation.
-2004-05-05 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * generic/tclCompile.c (TclCompileScript): Add the cmdPtr to the list
+ of arguments passed to command compilers.
- * doc/CrtObjCmd.3: Remove reference to Tcl_RenameCommand; there is no
- such API. [Bug 848440]
+2007-11-15 Don Porter <dgp@users.sourceforge.net>
-2004-05-04 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/regc_nfa.c: Fixed infinite loop in the regexp compiler.
+ [Bug 1810038]
- * generic/tclIOUtil.c (Tcl_FSChdir): Work-around crash condition
- * tests/winFCmd.test (winFCmd-16.12): triggered when $HOME is
- volumerelative (ie 'C:').
+ * generic/regc_nfa.c: Corrected looping logic in fixempties() to
+ avoid wasting time walking a list of dead states. [Bug 1832612]
- * tests/fileName.test (filename-12.9): use C:/ instead of the first
- item in file volumes - that's usually A:/, which for most will have
- nothing in it.
+2007-11-15 Donal K. Fellows <donal.k.fellows@man.ac.uk>
-2004-05-04 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclNamesp.c (NamespaceEnsembleCmd): Must pass a non-NULL
+ interp to Tcl_SetEnsemble* functions.
- * tests/tcltest.test: Test corrections for Mac OSX. Thanks to Steven
- Abner (tauvan). [Bug 947440]
+ * doc/re_syntax.n: Try to make this easier to read. It's still a very
+ difficult manual page!
-2004-05-03 Andreas Kupries <andreask@activestate.com>
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): Allow people to turn off the -rpath
+ option to their linker if they so desire. This is a configuration only
+ recommended for (some) vendors. Relates to [Patch 1231022].
- Applied [SF Tcl Patch 868853], fixing a mem leak in TtySetOptionProc.
- Report and Patch provided by Stuart Cassoff <stwo@users.sf.net>.
+2007-11-15 Pat Thoyts <patthoyts@users.sourceforge.net>
-2004-05-03 Kevin Kenny <kennykb@acm.org>
+ * win/tclWin32Dll.c: Prefer UINT_PTR to DWORD_PTR when casting pointers
+ to integer types for greater portability. [Bug 1831253]
- * win/tclWin32Dll.c (TclpCheckStackSpace):
- * tests/stack.test (stack-3.1): Fix for undetected stack overflow in
- TclReExec on Windows. [Bug 947070]
+2007-11-15 Daniel Steffen <das@users.sourceforge.net>
-2004-05-03 Don Porter <dgp@users.sourceforge.net>
+ * macosx/Tcl.xcodeproj/project.pbxproj: add new chanio.test.
+ * macosx/Tcl.xcode/project.pbxproj:
- * library/init.tcl: Corrected unique prefix matching of
- interactive command completion in [unknown]. [Bug 946952]
+2007-11-14 Donal K. Fellows <donal.k.fellows@man.ac.uk>
-2004-05-02 Miguel Sofer <msofer@users.sf.net>
+ * generic/tclCompile.c (TclCompileScript): Ensure that we get our count
+ in our INST_START_CMD calls right, even when there's a failure to
+ compile a command directly.
- * generic/tclProc.c (TclObjInvokeProc):
- * tests/proc.test (proc-3.6): fix for bad quoting of multi-word proc
- names in error messages [Bug 942757]
+ * generic/tclNamesp.c (Tcl_SetEnsembleSubcommandList)
+ (Tcl_SetEnsembleMappingDict): Special code to make sure that
+ * generic/tclCmdIL.c (TclInitInfoCmd): [info exists] is compiled right
+ while not allowing changes to the ensemble to cause havok.
-2004-04-23 Andreas Kupries <andreask@activestate.com>
+ * generic/tclCompCmds.c (TclCompileInfoCmd): Simple compiler for the
+ [info] command that only handles [info exists].
- * generic/tclIO.c (Tcl_SetChannelOption): Fixed [Bug 930851]. When
- changing the eofchar we have to zap the related flags to prevent them
- from prematurely aborting the next read.
+ * generic/tclExecute.c (TclExecuteByteCode:INST_EXIST_*): New
+ instructions to allow the testing of whether a variable exists.
-2004-04-07 Jeff Hobbs <jeffh@ActiveState.com>
+2007-11-14 Andreas Kupries <andreask@activestate.com>
- * win/configure:
- * win/configure.in: define TCL_LIB_FLAG, TCL_BUILD_LIB_SPEC,
- TCL_LIB_SPEC and TCL_PACKAGE_PATH in tclConfig.sh.
+ * tests/chanio.test: New file. This is essentially a duplicate of
+ 'io.test', with all channel commands converted to their 'chan xxx'
+ notation.
+ * tests/io.test: Fixed typo in test description.
-2004-04-06 Don Porter <dgp@users.sourceforge.net>
+2007-11-14 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * tests/unixInit.test (unixInit-3.1): Default encoding on Darwin
- systems is utf-8. Thanks to Steven Abner (tauvan). [Bug 928808]
+ * generic/regc*.c: Eliminate multi-char collating element code
+ completely. Simplifies the code quite a bit. If people still want the
+ full code, it will remain on the 8.4 branch. [Bug 1831425]
-2004-04-06 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+2007-11-13 Jeff Hobbs <jeffh@ActiveState.com>
- * tests/cmdAH.test (cmdAH-18.2): Added constraint because
- access(...,X_OK) is defined to be permitted to be meaningless when
- running as root, and OSX exhibits this. [Bug 929892]
+ * generic/tclCompCmds.c (TclCompileRegexpCmd): clean up comments, only
+ free dstring on OK from TclReToGlob.
+ (TclCompileSwitchCmd): simplify TclReToGlob usage.
-2004-04-02 Don Porter <dgp@users.sourceforge.net>
+2007-11-14 Donal K. Fellows <dkf@users.sf.net>
- * tests/tcltest.test: Corrected constraint typos: "nonRoot" ->
- "notRoot". Thanks to Steven Abner (tauvan). [Bug 928353]
+ * generic/regc*.c: #ifdef/comment out the code that deals with
+ multi-character collating elements, which have never been supported.
+ Cuts the memory consumption of the RE compiler. [Bug 1831425]
-2004-03-31 Don Porter <dgp@users.sourceforge.net>
+2007-11-13 Donal K. Fellows <dkf@users.sf.net>
- * doc/msgcat.n: Clarified message catalog file encodings. [Bug 811457]
- * library/msgcat/msgcat.tcl ([mcset], [ConvertLocale], [Init]):
- Corrected [mcset] to be able to successfully set a translation to
- the empty string. [mcset $loc $src {}] was incorrectly set the $loc
- translation of $src back to $src. Also changed [ConvertLocale] to
- minimally require a non-empty "language" part in the locale value. If
- not, an error raised prompts [Init] to keep looking for a valid locale
- value, or ultimately fall back on the "C" locale. [Bug 811461]
- * library/msgcat/pkgIndex.tcl: Bump to msgcat 1.3.2.
+ * generic/tclCompCmds.c (TclCompileSwitchCmd, TclCompileRegexpCmd):
+ Extend [switch] compiler to handle regular expressions as long as
+ things are not too complex. Fix [regexp] compiler so that non-trivial
+ literal regexps get fed to INST_REGEXP.
-2004-03-31 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * doc/mathop.n: Clarify definitions of some operations.
- * generic/tclObj.c (HashObjKey): Make sure this hashes the whole
- string rep of the object, instead of missing the last character.
+2007-11-13 Miguel Sofer <msofer@users.sf.net>
-2004-03-29 Jeff Hobbs <jeffh@ActiveState.com>
+ * unix/tclUnixInit.c: the TCL_NO_STACK_CHECK was being incorrectly
+ undefined here; this should be set (or not) in the compile options, it
+ is used elsewhere and needs to be consistent.
- * generic/tclInt.h:
- * generic/tclEncoding.c (TclFindEncodings, Tcl_FindExecutable):
- * mac/tclMacInit.c (TclpInitLibraryPath): Correct handling of UTF
- * unix/tclUnixInit.c (TclpInitLibraryPath): data that is actually
- * win/tclWinFile.c (TclpFindExecutable): "clean", allowing the
- * win/tclWinInit.c (TclpInitLibraryPath): loading of Tcl from paths
- that contain multi-byte chars on Windows [Bug 920667]
+2007-11-13 Pat Thoyts <patthoyts@users.sourceforge.net>
-2004-03-28 Miguel Sofer <msofer@users.sf.net>
+ * unix/tcl.m4: Added autoconf goo to detect and make use of
+ * unix/configure.in: getaddrinfo and friends.
+ * unix/configure: (regenerated)
- * generic/tclCompile.c (TclCompileScript): corrected possible segfault
- when a compilation returns TCL_OUTLINE_COMPILE after having grown the
- compile environment. [Bug 925121]
-
-2004-03-21 Jeff Hobbs <jeffh@ActiveState.com>
+2007-11-13 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * win/tclWinInt.h: define VER_PLATFORM_WIN32_CE if not already set.
- * win/tclWinInit.c (TclpSetInitialEncodings): recognize WIN32_CE
- as a unicode (WCHAR) platform.
+ * unix/tclUnixCompat.c (TclpGetHostByName): The six-argument form of
+ getaddressbyname_r() uses the fifth argument to indicate whether the
+ lookup succeeded or not on at least one platform. [Bug 1618235]
-2004-03-15 Miguel Sofer <msofer@users.sf.net>
+2007-11-13 Don Porter <dgp@users.sourceforge.net>
- * generic/tclCompile.c (TclCompileScript):
- * tests/compile.test (compile-3.5): corrected wrong test and behaviour
- in the earlier fix for [Bug 705406]; Don Porter reported this as [Bug
- 735055], and provided the solution. Fixed in HEAD on 2003-05-09, but
- backport to 8-4-branch was wrongly omitted; re-reported as [Bug
- 916795] by Roy Terry, diagnosed by dgp.
+ * generic/regcomp.c: Convert optst() from expensive no-op to a
+ cheap no-op.
-2004-03-08 Vince Darley <vincentdarley@users.sourceforge.net>
+2007-11-13 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * generic/tclFileName.c: Fix to 'glob -path' near the root
- * tests/fileName.test: of the filesystem. [Bug 910525]
+ * unix/tclUnixChan.c (CreateSocketAddress): Rewrote to use the
+ thread-safe version of gethostbyname() by forward-porting the code used
+ in 8.4, and added rudimentary support for getaddrinfo() (not enabled by
+ default, as no autoconf-ery written). Part of fix for [Bug 1618235].
-2004-03-01 Don Porter <dgp@users.sourceforge.net>
+2007-11-12 Jeff Hobbs <jeffh@ActiveState.com>
- *** 8.4.6 TAGGED FOR RELEASE ***
+ * generic/tclGet.c (Tcl_Get, Tcl_GetInt): revert use of TclGet* macros
+ due to compiler warning. These cases won't save time either.
- * unix/tcl.m4 (SC_CONFIG_CFLAGS): Allow 64-bit enabling on
- IRIX64-6.5* systems. [Bug 218561]
- * unix/configure: autoconf-2.13
+ * generic/tclUtil.c (TclReToGlob): add more comments, set interp result
+ if specified on error.
- * generic/tclCmdMZ.c (TclCheckInterpTraces): The TIP 62
- * generic/tclTest.c (TestcmdtraceCmd): implementation introduced a
- * tests/basic.test (basic-39.10): bug by testing the CallFrame
- level instead of the iPtr->numLevels level when deciding what traces
- created by Tcl_Create(Obj)Trace to call. Added test to expose the
- error, and made fix. [Request 462580]
+2007-11-12 Miguel Sofer <msofer@users.sf.net>
-2004-02-26 Daniel Steffen <das@users.sourceforge.net>
+ * generic/tclBasic.c: New macro TclResetResult, new iPtr flag
+ * generic/tclExecute.c: bit INTERP_RESULT_UNCLEAN: shortcut for
+ * generic/tclInt.h: Tcl_ResetResult for the "normal" case:
+ * generic/tclProc.c: TCL_OK, no return options, no errorCode
+ * generic/tclResult.c: nor errorInfo, return at normal level.
+ * generic/tclStubLib.c: [Patch 1830184]
+ * generic/tclUtil.c:
- * macosx/Makefile: fixed copyright year in Tcl.framework Info.plist
+ THIS PATCH WAS REVERTED: initial (mis)measurements overstated the
+ perfomance wins, which turn out to be tiny. Not worth the complication.
-2004-02-25 Don Porter <dgp@users.sourceforge.net>
+2007-11-11 Jeff Hobbs <jeffh@ActiveState.com>
- * tests/basic.test: Made several tests more robust to the
- * tests/cmdMZ.test: list-quoting of path names that might
- * tests/exec.test: contain Tcl-special chars like { or [.
- * tests/io.test: Should help us sort out Tcl Bug 554068.
- * tests/pid.test:
- * tests/socket.test:
- * tests/source.test:
- * tests/unixInit.test:
+ * generic/tclCompCmds.c, generic/tclCompile.c, generic/tclCompile.h:
+ * generic/tclExecute.c, generic/tclInt.decls, generic/tclIntDecls.h:
+ * generic/tclRegexp.c, generic/tclRegexp.h: Add INST_REGEXP and fully
+ * generic/tclStubInit.c, generic/tclUtil.c: compiled [regexp] for the
+ * tests/regexpComp.test: [Bug 1830166] simple cases. Also added
+ TclReToGlob function to convert RE to glob patterns and use these in
+ the possible cases.
-2004-02-25 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+2007-11-11 Miguel Sofer <msofer@users.sf.net>
- * unix/tclUnixChan.c (TcpGetOptionProc): Stop memory leak with very
- long hostnames. [Bug 888777]
+ * generic/tclResult.c (ResetObjResult): clarify the logic.
-2004-02-25 David Gravereaux <davygrvy@pobox.com>
+ * generic/tclBasic.c: Increased usage of macros to detect
+ * generic/tclBinary.c: and take advantage of objTypes. Added
+ * generic/tclClock.c: macros TclGet(Int|Long)FromObj,
+ * generic/tclCmdAH.c: TclGetIntForIndexM & TclListObjLength,
+ * generic/tclCmdIL.c: modified TclListObjGetElements.
+ * generic/tclCmdMZ.c:
+ * generic/tclCompCmds.c: The TclGetInt* macros are only a
+ * generic/tclCompExpr.c: shortcut on platforms where 'long' is
+ * generic/tclCompile.c: 'int'; it may be worthwhile to extend
+ * generic/tclDictObj.c: their functionality to other cases.
+ * generic/tclExecute.c:
+ * generic/tclGet.c: As this patch touches many files it has
+ * generic/tclIO.c: been recorded as [Patch 1830038] in
+ * generic/tclIOCmd.c: order to facilitate reviewing.
+ * generic/tclIOGT.c:
+ * generic/tclIndexObj.c:
+ * generic/tclInt.h:
+ * generic/tclInterp.c:
+ * generic/tclListObj.c:
+ * generic/tclLiteral.c:
+ * generic/tclNamesp.c:
+ * generic/tclObj.c:
+ * generic/tclParse.c:
+ * generic/tclProc.c:
+ * generic/tclRegexp.c:
+ * generic/tclResult.c:
+ * generic/tclScan.c:
+ * generic/tclStringObj.c:
+ * generic/tclUtil.c:
+ * generic/tclVar.c:
- * tests/winPipe.test:
- * win/tclWinPipe.c: backport of BuildCommandLine changes to mirror
- msvcrt's parse_cmdline() rules of quoting.
+2007-11-11 Daniel Steffen <das@users.sourceforge.net>
-2004-02-19 Mo DeJong <mdejong@users.sourceforge.net>
+ * unix/tclUnixTime.c (TclpWideClicksToNanoseconds): Fix issues with
+ * generic/tclInt.h: int64_t overflow.
- * win/tclWinInit.c (AppendEnvironment): Use the tail component of the
- passed in lib path instead of just blindly using lib+4. That worked
- when lib was "lib/..." but fails for other values. Thanks go to
- Patrick Samson for pointing this out.
+ * generic/tclBasic.c: Fix stack check failure case if stack grows up
+ * unix/tclUnixInit.c: Simplify non-crosscompiled case.
-2004-02-17 Don Porter <dgp@users.sourceforge.net>
+ * unix/configure: autoconf-2.59
+ * unix/tclConfig.h.in: autoheader-2.59
- * doc/tcltest.n:
- * library/tcltest/tcltest.tcl: Changed -verbose default value to
- {body error} so that detailed information on unexpected errors in
- tests is provided by default, even after the fix for [Bug 725253]
+2007-11-10 Miguel Sofer <msofer@users.sf.net>
-2004-02-17 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclExecute.c: Fast path for INST_LIST_INDEX when the index is
+ not a list.
- (reverted due to test failures on Solaris, but not Win/Lin :/)
- * generic/tclIOUtil.c: backport of rewrite of generic file
- normalization code to cope with links followed by '..'. [Bug 849514],
- and parts of [859251]
+ * generic/tclBasic.c:
+ * unix/configure.in:
+ * unix/tclUnixInit.c: Detect stack grwoth direction at compile time,
+ only fall to runtime detection when crosscompiling.
- * tests/unixInit.test: unixInit-7.1
- * unix/tclUnixInit.c (TclpInitPlatform): ensure the std fds exist to
- prevent crash condition [Bug 772288]
+ * unix/configure: autoconf 2.61
-2004-02-16 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclBasic.c:
+ * generic/tclInt.h:
+ * tests/interp.test:
+ * unix/tclUnixInit.c:
+ * win/tclWin32Dll.c: Restore simpler behaviour for stack checking, not
+ adaptive to stack size changes after a thread is launched. Consensus is
+ that "nobody does that", and so it is not worth the cost. Improved
+ failure comments (mistachkin).
- * generic/tclCmdMZ.c (TclTraceExecutionObjCmd)
- (TclTraceCommandObjCmd): fix possible mem leak in trace info.
+2007-11-10 Kevin Kenny <kennykb@acm.org>
-2004-02-12 Jeff Hobbs <jeffh@ActiveState.com>
+ * win/tclWin32Dll.c: Rewrote the Windows stack checking algorithm to
+ use information from VirtualQuery to determine the bound of the stack.
+ This change fixes a bug where the guard page of the stack was never
+ restored after an overflow. It also eliminates a nasty piece of
+ assembly code for structured exception handling on mingw. It introduces
+ an assumption that the stack is a single memory arena returned from
+ VirtualAlloc, but the code in MSVCRT makes the same assumption, so it
+ should be fairly safe.
- * README: update patchlevel to 8.4.6
- * generic/tcl.h:
- * tools/tcl.wse.in:
- * unix/configure, unix/configure.in, unix/tcl.spec:
- * win/README.binary, win/configure, win/configure.in:
+2007-11-10 Miguel Sofer <msofer@users.sf.net>
- * unix/tcl.m4: update HP-11 build libs setup
+ * generic/tclBasic.c:
+ * generic/tclInt.h:
+ * unix/tclUnixInit.c:
+ * unix/tclUnixPort.h:
+ * win/tclWin32Dll.c: Modify the stack checking algorithm to recheck in
+ case of failure. The working assumptions are now that (a) a thread's
+ stack is never moved, and (b) a thread's stack can grow but not shrink.
+ Port to windows - could be more efficient, but is already cheaper than
+ it was.
-2004-02-06 Don Porter <dgp@users.sourceforge.net>
+2007-11-09 Miguel Sofer <msofer@users.sf.net>
- * doc/clock.n: Removed reference to non-existent [file ctime].
+ * generic/tclResult.c (ResetObjResult): new shortcut.
-2004-02-04 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclAsync.c:
+ * generic/tclBasic.c:
+ * generic/tclExecute.c:
+ * generic/tclInt.h:
+ * generic/tclUnixInit.c:
+ * generic/tclUnixPort.h: New fields in interp (ekeko!) to cache TSD
+ data that is accessed at each command invocation, access macros to
+ replace Tcl_AsyncReady and TclpCheckStackSpace by much faster variants.
+ [Patch 1829248]
- * library/tcltest/tcltest.tcl: Corrected references to
- non-existent $name variable in [cleanupTests]. [Bug 833637]
+2007-11-09 Jeff Hobbs <jeffh@ActiveState.com>
-2004-02-03 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclInt.decls, generic/tclIntDecls.h: Use unsigned char for
+ * generic/tclExecute.c, generic/tclUtil.c: TclByteArrayMatch and
+ don't allow a nocase option. [Bug 1828296]
+ For INST_STR_MATCH, ignore pattern type for TclByteArrayMatch case.
- * library/tcltest/tcltest.tcl: Corrected parsing of single
- command line argument (option with missing value) [Bug 833910]
- * library/tcltest/pkgIndex.tcl: Bump to version 2.2.5.
+ * generic/tclBinary.c (Tcl_GetByteArrayFromObj): check type before
+ func jump (perf).
-2004-02-02 David Gravereaux <davygrvy@pobox.com>
+2007-11-07 Jeff Hobbs <jeffh@ActiveState.com>
- * generic/tclIO.c (Tcl_Ungets): fixes improper filling of the channel
- buffer. [Bug 405995]
+ * generic/tclStubInit.c: Added TclByteArrayMatch
+ * generic/tclInt.decls: for efficient glob
+ * generic/tclIntDecls.h: matching of ByteArray
+ * generic/tclUtil.c (TclByteArrayMatch): Tcl_Objs, used in
+ * generic/tclExecute.c (TclExecuteByteCode): INST_STR_MATCH. [Bug
+ 1827996]
-2004-01-13 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclIO.c (TclGetsObjBinary): Add an efficient binary path for
+ [gets].
+ (DoWriteChars): Special case for 1-byte channel write.
- * generic/tclFileName.c (Tcl_GlobObjCmd): Latest changes to
- management of the interp result by Tcl_GetIndexFromObj() exposed
- improper interp result management in the [glob] command procedure.
- Corrected by adopting the Tcl_SetObjResult(Tcl_NewStringObj) pattern.
- This stopped a segfault in test filename-11.36.
+2007-11-06 Miguel Sofer <msofer@users.sf.net>
-2004-01-13 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * generic/tclEncoding.c: Version of the embedded iso8859-1 encoding
+ handler that is faster (functions to do the encoding know exactly what
+ they're doing instead of pulling it from a table, though the table
+ itself has to be retained for use by shift encodings that depend on
+ iso8859-1). [Patch 1826906], committing for dkf.
- * generic/tclIndexObj.c (Tcl_GetIndexFromObjStruct, Tcl_WrongNumArgs):
- Create fresh objects instead of using the one currently in the
- interpreter, which isn't guaranteed to be fresh and unshared. The
- cost for the core will be minimal because of the object cache, and
- this fixes. [Bug 875395]
+2007-11-05 Andreas Kupries <andreask@activestate.com>
-2004-01-09 Vince Darley <vincentdarley@users.sourceforge.net>
+ * generic/tclConfig.c (Tcl_RegisterConfig): Modified to not extend the
+ config database if the encoding provided by the user is not found
+ (venc == NULL). Scripts expecting the data will error out, however we
+ neither crash nor provide bogus information. See [Bug 983509] for more
+ discussion.
- * generic/tclIOUtil.c: fix to infinite loop in TclFinalizeFilesystem.
- [Bug 873311]
+ * unix/tclUnixChan.c (TtyGetOptionProc): Accepted [Patch 1823576]
+ provided by Stuart Cassof <stwo@users.sourceforge.net>. The patch adds
+ the necessary utf/external conversions to the handling of the arguments
+ of option -xchar which will allow the use of \0 and similar characters.
-2003-12-17 Daniel Steffen <das@users.sourceforge.net>
+2007-11-03 Miguel Sofer <msofer@users.sf.net>
- * generic/tclBinary.c (DeleteScanNumberCache): fixed crashing bug when
- numeric scan-value cache contains NULL value.
+ * generic/tclTest.c (TestSetCmd2):
+ * generic/tclVar.c (TclObjLookupVarEx):
+ * tests/set.test (set-5.1): Fix error branch when array name looks
+ like array element (code not normally exercised).
-2003-12-17 Zoran Vasiljevic <zv@archiware.com>
+2007-11-01 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * generic/tclIOUtil.c: fixed 2 memory (object) leaks. This fixes [Bug
- 839519]
+ * tools/tcltk-man2html.tcl (output-directive): Convert .DS/.DE pairs
+ into tables since that is now all that they are used for.
-2003-12-12 Vince Darley <vincentdarley@users.sourceforge.net>
+ * doc/RegExp.3: Clarified documentation of RE flags. [Bug 1167840]
- * generic/tclCmdAH.c: fix to normalization of non-existent user name
- ('file normalize ~nobody') [Bug 858937]
+ * doc/refchan.n: Adjust internal name to be consistent with the file
+ name for reduced user confusion. After comment by Dan Steffen.
-2003-12-09 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd, UniCharIsAscii): Remember, the
+ NUL character is in ASCII too. [Bug 1808258]
- * unix/tclUnixPort.h: #ifdef'd out declarations of errno which
- * tools/man2tcl.c: are known to cause problems with recent
- glibc. [Bug 852369]
+ * doc/file.n: Clarified use of [file normalize]. [Bug 1185154]
-2003-12-03 Don Porter <dgp@users.sourceforge.net>
+2007-10-30 Don Porter <dgp@users.sourceforge.net>
- * generic/tcl.h: Bumped patch level to 8.4.5.1 to distinguish
- * unix/configure.in: CVS snapshots from 8.4.5 release.
+ * generic/tcl.h: Bump version number to 8.5b2.1 to distinguish
+ * library/init.tcl: CVS development snapshots from the 8.5b2
+ * unix/configure.in: release.
* unix/tcl.spec:
* win/configure.in:
- * unix/configure: autoconf (2.13)
+ * unix/configure: autoconf (2.59)
* win/configure:
-2003-12-02 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+2007-10-30 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * generic/tclBinary.c (DeleteScanNumberCache, ScanNumber): Made
- the numeric scan-value cache have proper references to the objects
- within it so strange patterns of writes won't cause references to
- freed objects. Thanks to Paul Obermeier for the report. [Bug 851747]
+ * doc/expr.n, doc/mathfunc.n: Improve documentation to try to make
+ clearer what is going on.
-2003-12-01 Miguel Sofer <msofer@users.sf.net>
+ * doc/interp.n: Shorten the basic descriptive text for some interp
+ subcommands so Solaris nroff doesn't truncate them. [Bug 1822268]
- * doc/lset.n: fix typo [Bug 852224]
+2007-10-30 Donal K. Fellows <dkf@users.sf.net>
-2003-11-21 Don Porter <dgp@users.sourceforge.net>
+ * tools/tcltk-man2html.tcl (output-widget-options): Enhance the HTML
+ generator so that it can produce multi-line option descriptions.
- *** 8.4.5 TAGGED FOR RELEASE ***
+2007-10-28 Miguel Sofer <msofer@users.sf.net>
- * tests/windFCmd.test (winFCmd-16.10): Corrected failure to
- initialize variable $dd that caused test suite failure.
+ * generic/tclUtil.c (Tcl_ConcatObj): optimise for some of the
+ concatenees being empty objs. [Bug 1447328]
-2003-11-20 Miguel Sofer <msofer@users.sf.net>
+2007-10-28 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclVar.c: fix flag bit collision between LOOKUP_FOR_UPVAR
- and TCL_PARSE_PART1 (deprecated) [Bug 835020]
+ * generic/tclEncoding.c (TclInitEncodingSubsystem): Hard code the
+ iso8859-1 encoding, as it's needed for more than just text (especially
+ binary encodings...) Note that other encodings rely on the encoding
+ being a table encoding (!) so we can't use more efficient encoding
+ mapping functions.
-2003-11-20 Vince Darley <vincentdarley@users.sourceforge.net>
+2007-10-27 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclIOUtil.c:
- * tests/winFCmd.test: fix to [Bug 845778] - Infinite recursion on [cd]
- (Windows only bug).
+ * generic/regc_lex.c (lexescape): Close off one of the problems
+ mentioned in [Bug 1810264].
-2003-11-18 Jeff Hobbs <jeffh@ActiveState.com>
+2007-10-27 Miguel Sofer <msofer@users.sf.net>
- * changes: updated for 8.4.5 release
+ * generic/tclNamesp.c (Tcl_FindCommand): insure that FQ command names
+ are searched from the global namespace, ie, bypassing resolvers of the
+ current namespace. [Bug 1114355]
-2003-11-17 Don Porter <dgp@users.sourceforge.net>
+ * doc/apply.n: fixed example [Bug 1811791]
+ * doc/namespace.n: improved example [Bug 1788984]
+ * doc/AddErrInfo.3: typo [Bug 1715087]
+ * doc/CrtMathFnc.3: fixed Tcl_ListMathFuncs entry [Bug 1672219]
- * generic/regcomp.c: Backported regexp bug fixes and tests. Thanks
- * generic/tclTest.c: to Pavel Goran and Vince Darley.
- * tests/reg.test: [Bugs 230589, 504785, 505048, 703709, 840258]
+ * generic/tclCompile.h:
+ * generic/tclInt.h: moved declaration of TclSetCmdNameObj from
+ tclCompile.h to tclInt.h, reverting linker [Bug 1821159] caused by
+ commit of 2007-10-11 (both I and gcc missed one dep).
-2003-11-12 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclVar.c: try to preserve Tcl_Objs when doing variable
+ lookups by name, partially addressing [Bug 1793601].
- * tests/cmdMZ.test (cmdMZ-1.4): change to nonPortable as more
- systems are using permissions caching, and this isn't really a Tcl
- controlled issue.
+2007-10-27 Donal K. Fellows <dkf@users.sf.net>
-2003-11-11 Jeff Hobbs <jeffh@ActiveState.com>
+ * tools/tcltk-man2html.tcl (make-man-pages, htmlize-text)
+ (process-text): Make the man->HTML scraper work better.
- * unix/configure:
- * unix/tcl.m4: improve AIX --enable-64bit handling
+2007-10-26 Don Porter <dgp@users.sourceforge.net>
-2003-11-10 Don Porter <dgp@users.sourceforge.net>
+ *** 8.5b2 TAGGED FOR RELEASE ***
- * tests/unixInit.test (unixInit-2.10): re-enabled.
- * unix/tclUnixInit.c (TclpInitLibraryPath): Alternative fix
- * win/tclWinInit.c (TclpInitLibraryPath): for [Bug 832657]
- that should not run afoul of startup constraints.
+ * changes: Updated for 8.5b2 release.
- * library/dde/pkgIndex.tcl: Added safeguards so that registry
- * library/reg/pkgIndex.tcl: and dde packages are not offered
- * win/tclWinDde.c: on non-Windows platforms. Bumped to
- * win/tclWinReg.c: registry 1.1.3 and dde 1.2.2.
+ * doc/*.1: Revert doc changes that broke
+ * doc/*.3: `make html` so we can get the release
+ * doc/*.n: out the door.
-2003-11-06 Jeff Hobbs <jeffh@ActiveState.com>
+ * README: Bump version number to 8.5b2.
+ * generic/tcl.h:
+ * library/init.tcl:
+ * tools/tcl.wse.in:
+ * unix/configure.in:
+ * unix/tcl.spec:
+ * win/configure.in:
- * tests/unixInit.test (unixInit-2.10): mark as knownBug
- * generic/tclEncoding.c (TclFindEncodings): revert patch from
- 2003-11-05. It wasn't valid in the sensitive startup init phase
- and broke Windows from working at all.
+ * unix/configure: autoconf (2.59)
+ * win/configure:
-2003-11-07 Daniel Steffen <das@users.sourceforge.net>
+2007-10-26 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * macosx/Makefile: optimized builds define NDEBUG to turn off
- ThreadAlloc range checking.
+ * tools/man2help2.tcl, tools/man2tcl.c: Made some of the tooling code
+ to do man->other formats work better with current manpage set. Long
+ way still to go.
-2003-11-05 Don Porter <dgp@users.sourceforge.net>
+2007-10-25 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
- * generic/tclEncoding.c (TclFindEncodings): Normalize the path
- of the executable before passing to TclpInitLibraryPath() to avoid
- buggy handling of paths containing "..". [Bug 832657]
- * tests/unixInit.test (unixInit-2.10): New test for fixed bug.
+ * generic/tclThread.c: Added TclpMasterLock/Unlock arround calls to
+ ForgetSyncObject in Tcl_MutexFinalize and Tcl_ConditionFinalize to
+ prevent from garbling the internal lists that track sync objects. [Bug
+ 1726873]
-2003-11-04 Daniel Steffen <das@users.sourceforge.net>
+2007-10-24 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * macosx/Makefile: added 'test' target.
+ * tools/man2html2.tcl (macro): Added support for converting the new
+ macros into HTML.
-2003-10-31 Vince Darley <vincentdarley@users.sourceforge.net>
+ * doc/man.macros (QW,PQ,QR,MT): New macros that hide the ugly mess
+ needed to get proper GOOBE quoting in the manual pages.
+ * doc/*.n, doc/*.3, doc/*.1: Lots of changes to take advantage of the
+ new macros.
- * generic/tclTest.c: fix test suite memory leak (backport error)
- * unix/tclUnixFile.c: ensure translated path (required for correct
- error messages) is freed in both code paths.
+2007-10-20 Miguel Sofer <msofer@users.sf.net>
-2003-10-23 Andreas Kupries <andreask@activestate.com>
+ * generic/tclCompile.c: Fix comments.
+ * generic/tclExecute.c:
- * unix/tclUnixChan.c (Tcl_MakeFileChannel): Applied [Patch 813606]
- fixing [Bug 813087]. Detection of sockets was off for Mac OS X which
- implements pipes as local sockets. The new code ensures that only IP
- sockets are detected as such.
+2007-10-18 David Gravereaux <davygrvy@pobox.com>
-2003-10-22 Andreas Kupries <andreask@activestate.com>
+ * tools/mkdepend.tcl: sort the dep list for a more humanly readable
+ output.
- * win/tclWinSock.c (TcpWatchProc): Watch for FD_CLOSE too when asked
- for writable events by the generic layer.
- (SocketEventProc): Generate a writable event too when a close is
- detected.
+2007-10-18 Don Porter <dgp@users.sourceforge.net>
- Together the changes fix [Bug 599468].
+ * generic/tclResult.c (TclMergeReturnOptions): Make sure any -code
+ values get pulled out of the dictionary, even if they are integer
+ valued.
-2003-10-22 Andreas Kupries <andreask@activestate.com>
+ * generic/tclCompCmds.c (TclCompileReturnCmd): Added code to more
+ optimally compile [return -level 0 $x] to "push $x". [RFE 1794073]
- * generic/tclIOUtil.c (FsListMounts, FsAddMountsToGlobResult): New
- functions. See below for context.
- (Tcl_FSMatchInDirectory): Modified to call on the new functions
- (above) to handle the mountpoints in the glob'bed directory correctly.
- Part of the patch by Vincent Darley to solve the [Bug 800106] for the
- 8.4.x series.
+ * compat/tmpnam.c (removed): The routine tmpnam() is no longer
+ * unix/Makefile.in: called by Tcl source code. Remove autogoo the
+ * unix/configure.in: supplied a replacement version on systems
+ * win/tcl.dsp: where the routine was not available. [RFE
+ 1811848]
- * generic/tcl.h (TCL_GLOB_TYPE_MOUNT): New definition. Part of the
- patch by Vincent Darley to solve [Bug 800106] for the 8.4.x series.
+ * unix/configure: autoconf-2.59
-2003-10-22 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tcl.h: Remove TCL_LL_MODIFIER_SIZE. [RFE 1811837]
- * generic/tclCmdAH.c (Tcl_FileObjCmd): Changed FILE_ prefix for option
- enumeration to FCMD_ to prevent collision with symbols defined by
- Cygwin/Mingw32 on NT. [Bug 822528]
+2007-10-17 David Gravereaux <davygrvy@pobox.com>
-2003-10-21 Daniel Steffen <das@users.sourceforge.net>
+ * tools/mkdepend.tcl: Improved defense from malformed object list
+ infile.
- * tools/tcltk-man2html.tcl: fixed incorrect html generated for .IP/.TP
- lists, now use <DL><DT>...<DD>...<P><DT>...<DD>...</DL> instead of
- illegal <DL><P><DT>...<DD>...<P><DT>...<DD>...</DL>. Added skipping of
- directives directly after .TP to avoid them being used as item
- descriptions, e.g. .TP\n.VS in clock.n.
+2007-10-17 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
-2003-10-21 Andreas Kupries <andreask@activestate.com>
+ * tools/man2html2.tcl: Convert .DS/.DE into HTML tables, not
+ preformatted text.
- * win/tclWinPipe.c (BuildCommandLine): Applied the patch coming with
- [Bug 805605] to the code, fixing the incorrect use of ispace noted by
- Ronald Dauster <ronaldd@users.sourceforge.net>.
+2007-10-17 Kevin B. Kenny <kennykb@acm.org>
-2003-10-14 David Gravereaux <davygrvy@pobox.com>
+ * generic/tclCompExpr.c: Moved a misplaced declaration that blocked
+ compilation on VC++.
+ * generic/tclExecute.c: Silenced several VC++ compiler warnings about
+ converting 'long' to 'unsigned short'.
- * win/tclAppInit.c (sigHandler): Punt gracefully if exitToken has
- already been destroyed.
+2007-10-16 David Gravereaux <davygrvy@pobox.com>
-2003-10-13 Vince Darley <vincentdarley@users.sourceforge.net>
+ * win/makefile.vc: removed old dependency cruft that is no longer
+ needed.
- * generic/tclCmdMZ.c:
- * tests/regexp.test: fix to [Bug 823524] in regsub; added three new
- tests.
+2007-10-15 Don Porter <dgp@users.sourceforge.net>
-2003-10-12 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclIOCmd.c: Revise [open] so that it interprets leading
+ zero strings passed as the "permissions" argument as octal numbers,
+ even if Tcl itself no longer parses integers in that way.
- * unix/tclUnixTest.c (TestalarmCmd): don't bother checking return
- value of alarm. [Bug 664755] (english)
+ * unix/tclUnixFCmd.c: Revise the "-permissions" [file attribute] so
+ that it interprets leading zero strings as octal numbers, even if Tcl
+ itself no longer parses integers in that way.
-2003-10-08 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclCompExpr.c: Corrections to code that produces
+ * generic/tclUtil.c: extended "bad octal" error messages.
- * generic/tclBasic.c: Save and restore the iPtr->flag bits that
- control the state of errorCode and errorInfo management when calling
- "leave" execution traces, so that all error information of the traced
- command is still available whether traced or not. Thanks to Yahalom
- Emet. [Bug 760947]
+ * tests/cmdAH.test: Test revisions so that tests pass whether or
+ * tests/cmdIL.test: not Tcl parses leading zero strings as octal.
+ * tests/compExpr-old.test:
+ * tests/compExpr.test:
+ * tests/compile.test:
+ * tests/expr-old.test:
+ * tests/expr.test:
+ * tests/incr.test:
+ * tests/io.test:
+ * tests/lindex.test:
+ * tests/link.test:
+ * tests/mathop.test:
+ * tests/parseExpr.test:
+ * tests/set.test:
+ * tests/string.test:
+ * tests/stringComp.test:
-2003-10-08 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2007-10-15 David Gravereaux <davygrvy@pobox.com>
- * generic/tclTest.c (TestNumUtfCharsCmd): Command to allow finer
- access to Tcl_NumUtfChars for testing.
- * generic/tclUtf.c (Tcl_NumUtfChars): Corrected string length
- determining when the length parameter is negative; the terminator is a
- zero byte, not (necessarily) a \u0000 character. [Bug 769812]
+ * tools/mkdepend.tcl: Produces usable output. Include path problem
+ * win/makefile.vc: fixed. Never fight city hall when it comes to
+ levels of quoting issues.
-2003-10-07 Don Porter <dgp@users.sourceforge.net>
+2007-10-15 Miguel Sofer <msofer@users.sf.net>
- * tests/exec.test: Corrected temporary file management
- * tests/fileSystem.test: issues uncovered by -debug 1 test
- * tests/io.test: operations. Also backported some
- * tests/ioCmd.test: other fixes from the HEAD.
- * tests/pid.test: [Bugs 675605, 675655, 675659]
- * tests/socket.test:
- * tests/source.test:
+ * generic/tclParse.c (Tcl_ParseBraces): fix for possible read after
+ the end of buffer. [Bug 1813528] (Joe Mistachkin)
- * tests/fCmd.test: Run tests with the [temporaryDirectory] as
- the current directory, so that tests can depend on ability to write
- files. [Bug 575837]
+2007-10-14 David Gravereaux <davygrvy@pobox.com>
- * doc/OpenFileChnl.3: Updated Tcl_Tell and Tcl_Seek documentation
- to reflect that they now return Tcl_WideInt (TIP 72) [Bug 787537]
+ * tools/mkdepend.tcl (new): Initial stab at generating automatic
+ * win/makefile.vc: dependencies.
- * tests/io.test: Corrected several tests that failed when paths
- * tests/ioCmd.test: included regexp-special chars. [Bug 775394]
+2007-10-12 Pat Thoyts <patthoyts@users.sourceforge.net>
-2003-10-06 Don Porter <dgp@users.sourceforge.net>
+ * win/makefile.vc: Mine all version information from headers.
+ * win/rules.vc: Sync tcl and tk and bring extension versions
+ * win/nmakehlp.c: closer together. Try and avoid using tclsh to do
+ substitutions as we may cross compile.
+ * win/coffbase.txt: Added offsets for snack dlls.
- * tests/regexp.test: Matched [makeFile] with [removeFile].
- * tests/regexpComp.test: [Bug 675652]
+2007-10-11 David Gravereaux <davygrvy@pobox.com>
- * tests/fCmd.test (fCmd-8.2): Test only that tilde-substitution
- happens, not for any particular result. [Bug 685991]
+ * win/makefile.vc: Fixed my bad spelling mistakes from years back.
+ Dedependency, duh! Rather funny.
- * unix/tcl.m4 (SC_PATH_TCLCONFIG): Corrected search path so
- that alpha and beta releases of Tcl are not favored. [Bug 608698]
+2007-10-11 Don Porter <dgp@users.sourceforge.net>
- * tests/reg.test: Corrected duplicate test names.
- * tests/resource.test: [Bugs 710370, 710358]
+ * generic/tclCmdMZ.c: Correct [string is (wide)integer] failure
+ * tests/string.test: to report correct failindex values for
+ non-decimal integer strings. [Bug 1805887]
- * tests/cmdMZ.test: Updated [package require tcltest] lines to
- * tests/fileSystem.test: indiciate that these test files
- * tests/notify.test: use features of tcltest 2. [Bug 706114]
- * tests/parseExpr.test:
- * tests/unixNotfy.test:
+ * compat/strtoll.c (removed): The routines strtoll() and strtoull()
+ * compat/strtoull.c (removed): are no longer called by the Tcl source
+ * generic/tcl.h: code. (Their functionality has been replaced
+ * unix/Makefile.in: by TclParseNumber().) Remove outdated comments
+ * unix/configure.in: and mountains of configury autogoo that
+ * unix/tclUnixPort.h: allegedly support the mythical systems where
+ * win/Makefile.in: these routines might not have been available.
+ * win/makefile.bc:
+ * win/makefile.vc:
+ * win/tclWinPort.h:
-2003-10-06 Vince Darley <vincentdarley@users.sourceforge.net>
+ * unix/configure: autoconf-2.59
- * generic/tclFileName.c:
- * generic/tclIOUtil.c: backport of volumerelative file normalization
- and 'file join' inconsistency fixes [Bug 767834, 813273].
+2007-10-11 Miguel Sofer <msofer@users.sf.net>
-2003-10-04 Chengye Mao <chengye.geo@yahoo.com>
+ * generic/tclObj.c: remove superfluous #include of tclCompile.h
- * win/tclWinPipe.c: fixed a bug in BuildCommandLine.
- This bug built a command line with a missing space between
- tclpipe.dll and the following arguments. It caused error
- in Windows 98 when exec command.com (e.g. dir) [Bug 789040]
+2007-10-08 George Peter Staplin <georgeps@xmission.com>
-2003-10-03 Don Porter <dgp@users.sourceforge.net>
+ * doc/Hash.3: Correct the valid usage of the flags member for the
+ Tcl_HashKeyType. It should be 0 or more of the flags mentioned.
- * generic/tclBasic.c: Fixed error in ref count management of command
- * generic/tclCmdMZ.c: and execution traces that caused access to
- freed memory in trace-32.1. [Bug 811483]
+2007-10-02 Jeff Hobbs <jeffh@ActiveState.com>
-2003-10-03 Vince Darley <vincentdarley@users.sourceforge.net>
+ * generic/tcl.h (Tcl_DecrRefCount): Update change from 2006-05-29 to
+ make macro more warning-robust in unbraced if code.
- * tests/fileName.test:
- * tests/winFCmd.test:
- * doc/FileSystem.3: backported various test and documentation changes
- from HEAD. Backport of actual code fixes to follow.
+2007-10-02 Don Porter <dgp@users.sourceforge.net>
-2003-10-02 Don Porter <dgp@users.sourceforge.net>
+ [core-stabilizer-branch]
- * README: Bumped patch level to 8.4.5 to prepare
- * generic/tcl.h: for next patch release.
+ * README: Bump version number to 8.5.0
+ * generic/tcl.h:
+ * library/init.tcl:
* tools/tcl.wse.in:
* unix/configure.in:
* unix/tcl.spec:
- * win/README.binary:
* win/configure.in:
- * unix/configure: autoconf (2.13)
+ * unix/configure: autoconf (2.59)
* win/configure:
- * library/http/http.tcl: Bumped to http 2.4.5
- * library/http/pkgIndex.tcl:
-
-2003-10-01 Daniel Steffen <das@users.sourceforge.net>
-
- * macosx/Makefile: fixed redo prebinding bug when DESTDIR="".
- * mac/tclMacResource.c: fixed possible NULL dereference (bdesgraupes).
+2007-10-02 Andreas Kupries <andreask@activestate.com>
-2003-09-29 Don Porter <dgp@users.sourceforge.net>
+ * library/tclIndex: Added 'tcl::tm::path' to the tclIndex. This fixes
+ [Bug 1806422] reported by Don Porter.
- * generic/tclBasic.c (CallCommandTraces): Added safety bit
- * tests/trace.test: masking to prevent any of the bit values
- TCL_TRACE_*_EXEC from leaking into the flags field of any Command
- struct. This does not fix [Bug 811483] but helps to contain some of
- its worst symptoms. Also backported the corrections to test trace-28.4
- from Vince Darley.
+2007-09-25 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
-2003-09-29 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclProc.c (Tcl_DisassembleObjCmd): Define a command,
+ ::tcl::unsupported::disassemble, which can disassemble procedures,
+ lambdas and general scripts.
+ * generic/tclCompile.c (TclDisassembleByteCodeObj): Split apart the
+ code to print disassemblies of bytecode so that there is reusable code
+ that spits it out in a Tcl_Obj and then that code is used when doing
+ tracing.
- * library/http/http.tcl (geturl): Correctly check the type of
- boolean-valued options. [Bug 811170]
+2007-09-20 Don Porter <dgp@users.sourceforge.net>
- * unix/tcl.m4 (SC_ENABLE_FRAMEWORK): Added note to make it clearer
- that this is an OSX feature, not a general Unix feature. [Bug 619440]
+ *** 8.5b1 TAGGED FOR RELEASE ***
-2003-09-28 David Gravereaux <davygrvy@pobox.com>
+ * changes: updates for 8.5b1 release.
- * win/tclWinPipe.c: The windows port of expect can call
- TclWinAddProcess before any of the other pipe functions. Added a
- missing PipeInit() call to make sure the initialization happens.
+2007-09-19 Don Porter <dgp@users.sourceforge.net>
-2003-09-25 Daniel Steffen <das@users.sourceforge.net>
-
- * macosx/Makefile: ensure SYMROOT exists if OBJROOT is overridden on
- command line. Replaced explict use of /usr/bin by ${BINDIR}.
-
-2003-09-23 Don Porter <dgp@users.sourceforge.net>
+ * README: Bump version number to 8.5b1
+ * generic/tcl.h: Merge from core-stabilizer-branch.
+ * library/init.tcl: Stabilizing toward 8.5b1 release now done on
+ * tools/tcl.wse.in: the HEAD. core-stabilizer-branch is now
+ * unix/configure.in: suspended.
+ * unix/tcl.spec:
+ * win/configure.in:
- * generic/tclCmdMZ.c: Fixed [Bug 807243] where
- * tests/trace.test (trace-31,32.*): the introspection results
- of both [trace info command] and [trace info execution] were getting
- co-mingled. Thanks to Mark Saye for the report.
+2007-09-19 Pat Thoyts <patthoyts@users.sourceforge.net>
- * library/init.tcl (auto_load, auto_import): Expanded Eric Melski's
- 2000-01-28 fix for [Bug 218871] to all potentially troubled uses of
- [info commands] on input data, where glob-special characters could
- cause problems.
+ * generic/tclStubLib.: Replaced isdigit with internal implementation.
-2003-09-19 Miguel Sofer <msofer@users.sf.net>
+2007-09-18 Don Porter <dgp@users.sourceforge.net>
- * generic/tclExecute.c: adding (DE)CACHE_STACK_INFO() pairs to protect
- all calls that may cause traces on ::errorInfo or ::errorCode to
- corrupt the stack [Bug 804681]
+ * generic/tclStubLib.c: Remove C library calls from Tcl_InitStubs() so
+ * win/makefile.vc: that we don't need the C library linked in to
+ libtclStub.
-2003-09-10 Don Porter <dgp@users.sourceforge.net>
+2007-09-17 Pat Thoyts <patthoyts@users.sourceforge.net>
- * library/opt/optparse.tcl: Overlooked dependence of opt 0.4.4
- * library/opt/pkgIndex.tcl: on Tcl 8.2. Bumped to opt 0.4.4.1.
+ * win/makefile.vc: Add crt flags for tclStubLib now it uses C-library
+ functions.
-2003-09-01 Zoran Vasiljevic <zoran@archiware.com>
+2007-09-17 Joe English <jenglish@users.sourceforge.net>
- * generic/tclIOUtil.c: backported fix from HEAD [Bug 788780]
+ * tcl.m4: use '${CC} -shared' instead of 'ld -Bshareable' to build
+ shared libraries on current NetBSDs. [Bug 1749251]
+ * unix/configure: regenerated (autoconf-2.59).
-2003-08-27 Don Porter <dgp@users.sourceforge.net>
+2007-09-17 Don Porter <dgp@users.sourceforge.net>
- * generic/tclUtil.c: Corrected [Bug 411825] and other bugs in
- TclNeedSpace() where non-breaking space (\u00A0) and backslash-escaped
- spaces were handled incorrectly.
- * tests/util.test: Added new tests util-8.[2-6].
+ * unix/Makefile.in: Update `make dist` so that tclDTrace.d is
+ included in the source code distribution.
-2003-08-06 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tcl.h: Revised Tcl_InitStubs() to restore Tcl 8.4
+ * generic/tclPkg.c: source compatibility with callers of
+ * generic/tclStubLib.c: Tcl_InitStubs(interp, TCL_VERSION, 1). [Bug
+ 1578344]
- * win/tclWinInit.c: recognize amd64 and ia32_on_win64 cpus and
- Windows CE platform.
+2007-09-17 Donal K. Fellows <donal.k.fellows@man.ac.uk>
-2003-08-06 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclTrace.c (Tcl_TraceObjCmd, TraceExecutionObjCmd)
+ (TraceCommandObjCmd, TraceVariableObjCmd): Generate literal values
+ * generic/tclNamesp.c (NamespaceCodeCmd): more efficiently using
+ * generic/tclFCmd.c (CopyRenameOneFile): TclNewLiteralStringObj
+ * generic/tclEvent.c (TclSetBgErrorHandler): macro.
- * library/msgcat/msgcat.tcl: Added escape so that non-Windows
- * library/msgcat/pkgIndex.tcl: platforms do not try to use the
- registry package. This can save a costly and pointless package
- search. Bumped to 1.3.1. Thanks to Dave Bodenstab. [Bug 781609]
+2007-09-15 Daniel Steffen <das@users.sourceforge.net>
-2003-08-05 Miguel Sofer <msofer@users.sf.net>
+ * unix/tcl.m4: replace all direct references to compiler by ${CC} to
+ enable CC overriding at configure & make time; run
+ check for visibility "hidden" with all compilers;
+ quoting fixes from TEA tcl.m4.
+ (SunOS-5.1x): replace direct use of '/usr/ccs/bin/ld' in SHLIB_LD by
+ 'cc' compiler driver.
+ * unix/configure: autoconf-2.59
- * generic/tclExecute.c (INST_INVOKE, INST_EVAL, INST_PUSH_RESULT):
- added a Tcl_ResetResult(interp) at each point where the interp's
- result is pushed onto the stack, to avoid keeping an extra reference
- that may cause costly Tcl_Obj duplication. Detected by Franco Violi,
- analyzed by Peter Spjuth and Donal Fellows. [Bug 781585]
+2007-09-14 Donal K. Fellows <donal.k.fellows@man.ac.uk>
-2003-07-24 Reinhard Max <max@suse.de>
+ * generic/tclBasic.c (Tcl_CreateObjCommand): Only invalidate along the
+ namespace path once; that is enough. [Bug 1519940]
- * library/package.tcl: Fixed a typo that broke pkg_mkIndex -verbose.
+2007-09-14 Daniel Steffen <das@users.sourceforge.net>
- * tests/pkgMkIndex.test: Added a test for [pkg_mkIndex -verbose].
+ * generic/tclDTrace.d (new file): Add DTrace provider for Tcl; allows
+ * generic/tclCompile.h: tracing of proc and command entry &
+ * generic/tclBasic.c: return, bytecode execution, object
+ * generic/tclExecute.c: allocation and more; with
+ * generic/tclInt.h: essentially zero cost when tracing
+ * generic/tclObj.c: is inactive; enable with
+ * generic/tclProc.c: --enable-dtrace configure arg
+ * unix/Makefile.in: (disabled by default, will only
+ * unix/configure.in: enable if DTrace is present). [Patch
+ 1793984]
+
+ * macosx/GNUmakefile: Enable DTrace support.
+ * macosx/Tcl-Common.xcconfig:
+ * macosx/Tcl.xcodeproj/project.pbxproj:
+
+ * generic/tclCmdIL.c: Factor out core of InfoFrameCmd() into
+ internal TclInfoFrame() for use by DTrace
+ probes.
-2003-07-23 Daniel Steffen <das@users.sourceforge.net>
+ * unix/configure: autoconf-2.59
+ * unix/tclConfig.h.in: autoheader-2.59
- * unix/Makefile.in: changes to html-tcl & html-tk targets for
- compatibility with non-gnu makes.
+2007-09-12 Don Porter <dgp@users.sourceforge.net>
- * unix/Makefile.in: added macosx/README to dist target.
+ * unix/Makefile.in: Perform missing updates of the tcltest Tcl
+ * win/Makefile.in: Module installed filename that should have
+ been part of the bump to tcltest 2.3b1. Thanks Larry Virden.
-2003-07-23 Pat Thoyts <patthoyts@users.sourceforge.net>
+2007-09-12 Pat Thoyts <patthoyts@users.sourceforge.net>
- * win/tclWinReg.c (OpenSubKey): Backported fix for [Bug 775976] which
- causes the registry set command to fail when built with VC7.
- * library/reg/pkgIndex.tcl: Incremented the version to 1.1.2.
+ * win/makefile.vc, win/rules.vc, win/nmakehlp.c: Use nmakehlp to
+ substitute values for tclConfig.sh (helps cross-compiling).
-2003-07-21 Jeff Hobbs <jeffh@ActiveState.com>
+2007-09-11 Don Porter <dgp@users.sourceforge.net>
- *** 8.4.4 TAGGED FOR RELEASE ***
+ * library/tcltest/tcltest.tcl: Accept underscores and colons in
+ * library/tcltest/pkgIndex.tcl: constraint names. Properly handle
+ constraint expressions that return non-numeric boolean results like
+ "false". Bump to tcltest 2.3b1. [Bug 1772989; RFE 1071322]
+ * tests/info.test: Disable fragile tests.
- * changes: updated for 8.4.4 release
+ * doc/package.n: Restored the functioning of [package require
+ * generic/tclPkg.c: -exact] to be compatible with Tcl 8.4. [Bug
+ * tests/pkg.test: 1578344]
-2003-07-18 Daniel Steffen <das@users.sourceforge.net>
+2007-09-11 Miguel Sofer <msofer@users.sf.net>
- * macosx/Makefile: added option to allow installing manpages in
- addition to default html help.
+ * generic/tclCompCmds.c (TclCompileDictCmd-update):
+ * generic/tclCompile.c (tclInstructionTable):
+ * generic/tclExecute.c (INST_DICT_UPDATE_END): fix stack management in
+ compiled [dict update]. [Bug 1786481]
-2003-07-18 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ ***POTENTIAL INCOMPATIBILITY***
+ Scripts that were precompiled on earlier versions of 8.5 and use [dict
+ update] will crash. Workaround: recompile.
- * doc/Utf.3: Tightened up documentation of Tcl_UtfNext and Tcl_UtfPrev
- to better match the behaviour. [Bug 769895]
+2007-09-11 Kevin B. Kenny <kennykb@acm.org>
-2003-07-18 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclExecute.c: Corrected an off-by-one error in the setting
+ of MaxBaseWide for certain powers. [Bug 1767293 - problem reported in
+ comments when bug was reopened]
- * generic/tclIOUtil.c: correct MT-safety issues with filesystem
- records. [Bug 753315] (vasiljevic)
+2007-09-10 Jeff Hobbs <jeffh@ActiveState.com>
- * library/http/pkgIndex.tcl: merged to v2.4.4 from head
- * library/http/http.tcl: add support for user:pass info in URL.
- * tests/http.test: [Bug 759888] (shiobara)
+ * generic/tclLink.c (Tcl_UpdateLinkedVar): guard against var being
+ unlinked. [Bug 1740631] (maros)
-2003-07-18 Don Porter <dgp@users.sourceforge.net>
+2007-09-10 Miguel Sofer <msofer@users.sf.net>
- * generic/tclBasic.c: Corrected several instances of unsafe
- * generic/tclCompile.c: truncation of UTF-8 strings that might break
- * generic/tclProc.c: apart a multi-byte character. [Bug 760872]
- * library/init.tcl:
- * tests/init.test:
-
- * doc/tcltest.n: Restored the [Eval] proc to replace
- * library/tcltest/tcltest.tcl: the [::puts] command when either the
- -output or -error option for [test] is in use, in order to capture
- data written to the output or error channels for comparison against
- what is expected. This is easier to document and agrees better with
- most user expectations than the previous attempt to replace [puts]
- only in the caller's namespace. Documentation made more precise on the
- subject. [Bug 706359]
-
- * doc/AddErrInfo.3: Improved consistency of documentation by using
- * doc/CrtTrace.3: "null" everywhere to refer to the character
- * doc/Encoding.3: '\0', and using "NULL" everywhere to refer to
- * doc/Eval.3: the value of a pointer that points to nowhere.
- * doc/GetIndex.3: Also dropped references to ASCII that are no
- * doc/Hash.3: longer true, and standardized on the
- * doc/LinkVar.3: hyphenated spelling of "null-terminated".
- * doc/Macintosh.3:
- * doc/OpenFileChnl.3:
- * doc/SetVar.3:
- * doc/StringObj.3:
- * doc/Utf.3:
+ * generic/tclCompile.c: fix tclInstructionTable entry for
+ dictUpdateEnd
- * doc/CrtSlave.3 (Tcl_MakeSafe): Removed warning about possible
- deprecation (no TIP on that).
+ * generic/tclExecute.c: remove unneeded setting of 'cleanup' variable
+ before jumping to checkForCatch.
-2003-07-17 Daniel Steffen <das@users.sourceforge.net>
+2007-09-10 Don Porter <dgp@users.sourceforge.net>
- * macosx/Makefile: added var to allow overriding of tclsh used during
- html help building (Landon Fuller).
+ * doc/package.n: Restored the document parallel syntax of the
+ * generic/tclPkg.c: [package present] and [package require]
+ * tests/pkg.test: commands. [Bug 1723675]
-2003-07-16 Mumit Khan <khan@nanotech.wisc.edu>
+2007-09-09 Don Porter <dgp@users.sourceforge.net>
- * generic/tclIOUtil.c (SetFsPathFromAny): Add Cygwin specific code to
- convert POSIX filename to native format.
- * generic/tclFileName.c (Tcl_TranslateFileName): And remove from here.
- (TclDoGlob): Adjust for cygwin and append / for dirs instead of \
- * win/tclWinFile.c (TclpObjChdir): Use chdir on Cygwin. [Patch 679315]
+ * generic/tclInt.h: Removed the "nsName" Tcl_ObjType from the
+ * generic/tclNamesp.c: registered set. Revised the management of the
+ * generic/tclObj.c: intrep of that Tcl_ObjType. Revised the
+ * tests/obj.test: TclGetNamespaceFromObj() routine to return
+ TCL_ERROR and write a consistent error message when a namespace is not
+ found. [Bug 1588842. Patch 1686862]
-2003-07-16 Jeff Hobbs <jeffh@ActiveState.com>
+ ***POTENTIAL INCOMPATIBILITY***
+ For callers of Tcl_GetObjType() on the name "nsName".
- * library/safe.tcl (FileInAccessPath): normalize paths before
- comparison. [Bug 759607] (myers)
+ * generic/tclExecute.c: Update TclGetNamespaceFromObj() callers.
+ * generic/tclProc.c:
- * unix/tclUnixNotfy.c (NotifierThreadProc): correct size of found and
- word vars from int to long. [Bug 767578] (hgo)
+ * tests/apply.test: Updated tests to expect new consistent
+ * tests/namespace-old.test: error message when a namespace is not
+ * tests/namespace.test: found.
+ * tests/upvar.test:
-2003-07-16 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclCompCmds.c: Use the new INST_REVERSE instruction
+ * tests/mathop.test: to correct the compiled versions of math
+ operator commands. [Bug 1724437]
- * doc/CrtSlave.3 (Tcl_MakeSafe): Updated documentation to strongly
- discourage use. IMHO code outside the core that uses this function is
- a bug... [Bug 655300]
+ * generic/tclCompile.c: New bytecode instruction INST_REVERSE to
+ * generic/tclCompile.h: reverse the order of N items at the top of
+ * generic/tclExecute.c: stack.
-2003-07-16 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclCompCmds.c (TclCompilePowOpCmd): Make a separate
+ routine to compile ** to account for its different associativity.
- * generic/tcl.h: Add recognition of -DTCL_UTF_MAX=6 on the
- * generic/regcustom.h: make line to support UCS-4 mode. No config arg
- at this time, as it is not the recommended build mode.
+2007-09-08 Miguel Sofer <msofer@users.sf.net>
- * generic/tclPreserve.c: In Result and Preserve'd routines, do not
- * generic/tclUtil.c: assume that ckfree == free, as that is not
- * generic/tclResult.c: always true. [Bug 756791] (fuller)
+ * generic/tclVar.c (Tcl_SetVar2, TclPtrSetVar): [Bug 1710710] fixed
+ correctly, reverted fix of 2007-05-01.
-2003-07-16 Mo DeJong <mdejong@users.sourceforge.net>
+2007-09-08 Donal K. Fellows <dkf@users.sf.net>
- * win/Makefile.in: Don't define TCL_DBGX symbol for every compile.
- Instead, define TCL_PIPE_DLL only when compiling tclWinPipe.c. This
- will break other build systems, so they will need to remove the
- TCL_DBGX define and replace it with a define for TCL_PIPE_DLL.
- * win/makefile.vc: Ditto.
- * win/tclWinPipe.c (TclpCreateProcess): Remove PREFIX_IDENT and
- DEBUG_IDENT from top of file. Use TCL_PIPE_DLL passed in from build
- env instead of trying to construct the dll name from already defined
- symbols. This approach is more flexible and better in the long run.
+ * generic/tclDictObj.c (DictUpdateCmd, DictWithCmd): Plug a hole that
+ * generic/tclExecute.c (TEBC,INST_DICT_UPDATE_END): allowed a careful
+ * tests/dict.test (dict-21.16,21.17,22.11): attacker to craft a dict
+ containing a recursive link to itself, violating one of Tcl's
+ fundamental datatype assumptions and causing a stack crash when the
+ dict was converted to a string. [Bug 1786481]
-2003-07-16 Don Porter <dgp@users.sourceforge.net>
+2007-09-07 Don Porter <dgp@users.sourceforge.net>
- * generic/tclFileName.c (Tcl_GlobObjCmd): [Bug 771840]
- * generic/tclIOUtil.c (Tcl_FSConvertToPathType):[Bug 771947]
- * unix/tclUnixFCmd.c (GetModeFromPermString): [Bug 771949]
- Silence compiler warnings about unreached lines.
+ * generic/tclEvent.c ([::tcl::Bgerror]): Corrections to Tcl's
+ * tests/event.test: default [interp bgerror] handler so that when
+ it falls back to a hidden [bgerror] in a safe interp, it gets the
+ right error context data. [Bug 1790274]
- * library/tcltest/tcltest.tcl (ProcessFlags): Corrected broken call
- * library/tcltest/pkgIndex.tcl: to [lrange]. Bumped to
- version 2.2.4. [Bug 772333]
+2007-09-07 Miguel Sofer <msofer@users.sf.net>
-2003-07-15 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tclProc.c (TclInitCompiledLocals): the refCount of resolved
+ variables was being managed without checking if they were Var or
+ VarInHash: itcl [Bug 1790184]
- * unix/dltest/pkga.c (Pkga_EqObjCmd): Fix typo that was causing a
- crash in load.test.
+2007-09-06 Don Porter <dgp@users.sourceforge.net>
-2003-07-15 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclResult.c (Tcl_GetReturnOptions): Take care that a
+ * tests/init.test: non-TCL_ERROR code doesn't cause existing
+ -errorinfo, -errorcode, and -errorline entries to be omitted.
+ * generic/tclEvent.c: With -errorInfo no longer lost, generate more
+ complete ::errorInfo when calling [bgerror] after a non-TCL_ERROR
+ background exception.
- * doc/array.n: Added some examples from David Welton [Patch 763312]
+2007-09-06 Don Porter <dgp@users.sourceforge.net>
-2003-07-15 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclInterp.c (Tcl_Init): Removed constraint on ability
+ to define a custom [tclInit] before calling Tcl_Init(). Until now the
+ custom command had to be a proc. Now it can be any command.
- * doc/http.n: Updated SYNOPSIS to match actual syntax of commands.
- [Bug 756112]
+ * generic/tclInt.decls: New internal routine TclBackgroundException()
+ * generic/tclEvent.c: that for the first time permits non-TCL_ERROR
+ exceptions to trigger [interp bgerror] handling. Closes a gap in TIP
+ 221. When falling back to [bgerror] (which is designed only to handle
+ TCL_ERROR), convert exceptions into errors complaining about the
+ exception.
- * unix/dltest/pkga.c: Updated to not use Tcl_UtfNcmp and counted
- strings instead of strcmp (not defined in any #include'd header) and
- presumed NULL-terminated strings.
+ * generic/tclInterp.c: Convert Tcl_BackgroundError() callers to call
+ * generic/tclIO.c: TclBackgroundException().
+ * generic/tclIOCmd.c:
+ * generic/tclTimer.c:
- * README: Bumped patch level to 8.4.4 in anticipation
- * generic/tcl.h: of another patch release.
- * tools/tcl.wse.in:
- * unix/configure.in:
- * unix/tcl.spec:
- * win/README.binary:
- * win/configure.in:
+ * generic/tclIntDecls.h: make genstubs
+ * generic/tclStubInit.c:
- * unix/configure: autoconf (2.13)
- * win/configure:
+2007-09-06 Daniel Steffen <das@users.sourceforge.net>
- * generic/tclCompCmds.c (TclCompileIfCmd): Prior fix of Bug 711371
- on 2003-04-07 introduced a buffer overflow. Corrected. [Bug 771613]
+ * macosx/Tcl.xcode/project.pbxproj: discontinue unmaintained support
+ * macosx/Tcl.xcode/default.pbxuser: for Xcode 1.5; replace by Xcode2
+ project for use on Tiger (with Tcl.xcodeproj to be used on Leopard).
-2003-07-15 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * macosx/Tcl.xcodeproj/project.pbxproj: updates for Xcode 2.5 and 3.0.
+ * macosx/Tcl.xcodeproj/default.pbxuser:
+ * macosx/Tcl.xcode/project.pbxproj:
+ * macosx/Tcl.xcode/default.pbxuser:
+ * macosx/Tcl-Common.xcconfig:
- * generic/tclCmdIL.c (SortCompare): Cleared up confusing error
- message. [Bug 771539]
+ * macosx/README: document project changes.
-2003-07-15 Daniel Steffen <das@users.sourceforge.net>
+2007-09-05 Don Porter <dgp@users.sourceforge.net>
- * macosx/Makefile: Rewrote buildsystem for Mac OS X framework build to
- be purely make driven; in order to become independent of Apple's
- closed-source IDE and build tool. The changes are intended to be
- transparent to the Makefile user, all existing make targets and cmd
- line variable overrides should continue to work. Changed build to only
- include tcl specific html help in Tcl.framework, the tk specific html
- help is now included in Tk.framework.
+ * generic/tclBasic.c: Removed support for the unmaintained
+ * generic/tclExecute.c: -DTCL_GENERIC_ONLY configuration. [Bug
+ * unix/Makefile.in: 1264623]
- * macosx/Tcl.pbproj/project.pbxproj:
- * macosx/Tcl.pbproj/jingham.pbxuser: Changed to purely call through to
- the make driven buildsystem; Tcl.framework is no longer assembled by
- ProjectBuilder. Set default SYMROOT in target options to simplify
- setting up PB (manually setting common build folder for tcl & tk no
- longer needed).
+2007-09-04 Don Porter <dgp@users.sourceforge.net>
- * tools/tcltk-man2html.tcl: Added options to allow building only the
- tcl or tk html help files; the default behaviour with none of the new
- options is to build both, as before.
+ * unix/Makefile.in: It's unreliable to count on the release
+ manager to remember to `make genstubs` before `make dist`. Let the
+ Makefile remember the dependency for us.
- * unix/Makefile.in: Added targets for building only the tcl or tk help.
+ * unix/Makefile.in: Corrections to `make dist` dependencies to be
+ sure that macosx/configure gets generated whenever it does not exist.
- * macosx/README (new): Tcl specific excerpts of tk/macosx/README.
+2007-09-03 Kevin B, Kenny <kennykb@acm.org>
- * generic/tcl.h: Updated reminder comment about editing
- macosx/Tcl.pbproj/project.pbxproj when version number changes.
+ * library/tzdata/Africa/Cairo:
+ * library/tzdata/America/Grand_Turk:
+ * library/tzdata/America/Port-au-Prince:
+ * library/tzdata/America/Indiana/Petersburg:
+ * library/tzdata/America/Indiana/Tell_City:
+ * library/tzdata/America/Indiana/Vincennes:
+ * library/tzdata/Antarctica/McMurdo:
+ * library/tzdata/Australia/Adelaide:
+ * library/tzdata/Australia/Broken_Hill:
+ * library/tzdata/Australia/Currie:
+ * library/tzdata/Australia/Hobart:
+ * library/tzdata/Australia/Lord_Howe:
+ * library/tzdata/Australia/Melbourne:
+ * library/tzdata/Australia/Sydney:
+ * library/tzdata/Pacific/Auckland:
+ * library/tzdata/Pacific/Chatham: Olson's tzdata2007g.
-2003-07-11 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclListObj.c (TclLindexFlat):
+ * tests/lindex.test (lindex-17.[01]): Added code to detect the error
+ when a script does [lindex {} end foo]; an overaggressive optimisation
+ caused this call to return an empty object rather than an error.
- * tests/binary.test (binary-46.*): Tests to help enforce the current
- behaviour.
- * doc/binary.n: Documented that [binary format a] and [binary scan a]
- do encoding conversion by dropping high bytes, unlike the rest of
- the core. [Bug 735364]
+2007-09-03 Daniel Steffen <das@users.sourceforge.net>
-2003-07-11 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclObj.c (TclInitObjSubsystem): restore registration of the
+ "wideInt" Tcl_ObjType for compatibility with 8.4 extensions that
+ access the tclWideIntType Tcl_ObjType; add setFromAnyProc for
+ tclWideIntType.
- * library/package.tcl: Corrected [pkg_mkIndex] bug reported on
- comp.lang.tcl. The indexer was searching for newly indexed packages
- instead of newly provided packages.
+2007-09-02 Donal K. Fellows <dkf@users.sf.net>
-2003-07-04 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * doc/lsearch.n: Added note that order of results with the -all option
+ is that of the input list. It always was, but this makes it crystal.
- * doc/expr.n: Tighten up the wording of some operations. [Bug 758488]
+2007-08-30 Don Porter <dgp@users.sourceforge.net>
- * tests/cmdAH.test: Made tests of [file mtime] work better on FAT
- filesystems. [Patch 760768] Also a little general cleanup.
+ * generic/tclCompile.c: Added fflush() calls following all callers of
+ * generic/tclExecute.c: TclPrintByteCodeObj() so that tcl_traceCompile
+ output is less likely to get mangled when writes to stdout interleave
+ with other code.
-2003-06-25 Mo DeJong <mdejong@users.sourceforge.net>
+2007-08-28 Don Porter <dgp@users.sourceforge.net>
- * unix/configure: Regen.
- * unix/tcl.m4 (SC_CONFIG_CFLAGS): Add -ieee when compiling with cc and
- add -mieee when compiling with gcc under OSF1-V5 "Tru64" systems. [Bug
- 748957]
+ * generic/tclCompExpr.c: Use a table lookup in ParseLexeme() to
+ determine lexemes with single-byte representations.
-2003-06-24 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclBasic.c: Used unions to better clarify overloading of
+ * generic/tclCompExpr.c: the fields of the OpCmdInfo and
+ * generic/tclCompile.h: TclOpCmdClientData structs.
- * doc/encoding.n: Corrected the docs to say that [source] uses the
- system encoding, which it always did anyway (since 8.1) [Bug 742100]
+2007-08-27 Don Porter <dgp@users.sourceforge.net>
-2003-06-23 Vince Darley <vincentdarley@users.sourceforge.net>
+ * generic/tclCompExpr.c: Call TclCompileSyntaxError() when
+ expression syntax errors are found when compiling expressions. With
+ this in place, convert TclCompileExpr to return void, since there's no
+ longer any need to report TCL_ERROR.
+ * generic/tclCompile.c: Update callers.
+ * generic/tclExecute.c:
- * generic/tclFCmd.c: fix to bad error message when trying to do 'file
- copy foo ""'. [Bug 756951]
- * tests/fCmd.test: added two new tests for the bug.
+ * generic/tclCompCmds.c: New routine TclCompileSyntaxError()
+ * generic/tclCompile.h: to directly compile bytecodes that report a
+ * generic/tclCompile.c: syntax error, rather than (ab)use a call to
+ TclCompileReturnCmd. Also, undo the most recent commit that papered
+ over some issues with that (ab)use. New routine produces a new opcode
+ INST_SYNTAX, which is a minor variation of INST_RETURN_IMM. Also a bit
+ of constification.
- * doc/FileSystem.3: documentation fix [Bug 720634]
+ * generic/tclCompile.c: Move the deallocation of local LiteralTable
+ * generic/tclCompExpr.c: entries into TclFreeCompileEnv().
+ * generic/tclExecute.c: Update callers.
-2003-06-18 Miguel Sofer <msofer@users.sf.net>
+ * generic/tclCompExpr.c: Force numeric and boolean literals in
+ expressions to register with their intreps intact, even if that means
+ overwriting existing intreps in already registered literals.
- * generic/tclNamesp.c (Tcl_Export): removed erroneous comments [Bug
- 756744]
+2007-08-25 Kevin B. Kenny <kennykb@acm.org>
-2003-06-17 Vince Darley <vincentdarley@users.sourceforge.net>
+ * generic/tclExecute.c (TclExecuteByteCode): Added code to handle
+ * tests/expr.test (expr-23.48-53) integer exponentiation
+ that results in 32- and 64-bit integer results, avoiding calls to wide
+ integer exponentiation routines in this common case. [Bug 1767293]
- * generic/tclCmdMZ.c:
- * tests/regexp.test: fixing of bugs related to regexp and regsub
- matching of empty strings. Addition of a number of new tests.
+ * library/clock.tcl (ParseClockScanFormat): Modified code to allow
+ * tests/clock.test (clock-60.*): case-insensitive matching
+ of time zone and month names. [Bug 1781282]
-2003-06-10 Miguel Sofer <msofer@users.sf.net>
+2007-08-24 Don Porter <dgp@users.sourceforge.net>
- * generic/tclBasic.c:
- * generic/tclExecute.c: let TclEvalObjvInternal call TclInterpReady
- instead of relying on its callers to do so; fix for the part of [Bug
- 495830] that is new in 8.4.
- * tests/interp.test: Added tests 18.9 (knownbug) and 18.10
+ * generic/tclCompExpr.c: Register literals found in expressions
+ * tests/compExpr.test: to restore literal sharing. Preserve numeric
+ intreps when literals are created for the first time. Correct memleak
+ in ExecConstantExprTree() and add test for the leak.
-2003-06-09 Don Porter <dgp@users.sourceforge.net>
+2007-08-24 Miguel Sofer <msofer@users.sf.net>
- * tests/string.test (string-4.15): Added test for [string first] bug
- reported in Tcl 8.3, where test for all-single-byte-encoded strings
- was not reliable.
+ * generic/tclCompile.c: replaced copy loop that tripped some compilers
+ with memmove. [Bug 1780870]
-2003-06-04 Joe Mistachkin <joe@mistachkin.com>
+2007-08-23 Don Porter <dgp@users.sourceforge.net>
- * tools/man2help.tcl: Added duplicate help section checking and
- * tools/index.tcl: corrected a comment typo for the getTopics proc
- in index.tcl. [Bug 748700]
+ * library/init.tcl ([auto_load_index]): Delete stray "]" that created
+ an expr syntax error (masked by a [catch]).
-2003-05-23 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclCompCmds.c (TclCompileReturnCmd): Added crash protection
+ to handle callers other than TclCompileScript() failing to meet the
+ initialization assumptions of the TIP 280 code in CompileWord().
- * generic/tclObj.c (tclCmdNameType): Converted internal rep
- management of the cmdName Tcl_ObjType the opposite way, to always use
- the twoPtrValue instead of always using the otherValuePtr. Previous
- fix on 2003-05-12 broke several extensions that wanted to poke around
- with the twoPtrValue.ptr2 value of a cmdName Tcl_Obj, like TclBlend
- and e4graph. [Bug 726018] Thanks to George Petasis for the bug report
- and Jacob Levy for testing assistance.
+ * generic/tclCompExpr.c: Suppress the attempt to convert to
+ numeric when pre-compiling a constant expresion indicates an error.
-2003-05-22 Daniel Steffen <das@users.sourceforge.net>
+2007-08-22 Miguel Sofer <msofer@users.sf.net>
- *** 8.4.3 TAGGED FOR RELEASE ***
+ * generic/tclExecute.c (TEBC): disable the new shortcut to frequent
+ INSTs for debug builds. REVERTED (collision with alternative fix)
- * macosx/tclMacOSXBundle.c: fixed a problem that caused only the first
- call to Tcl_MacOSXOpenVersionedBundleResources() for a given bundle
- identifier to succeed. This caused the tcl runtime library not to be
- found in all interps created after the inital one.
+2007-08-21 Don Porter <dgp@users.sourceforge.net>
-2003-05-20 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclMain.c: Corrected the logic of dropping the last
+ * tests/main.test: newline from an interactively typed command.
+ [Bug 1775878]
- * changes: updated for 8.4.3
+2007-08-21 Pat Thoyts <patthoyts@users.sourceforge.net>
- * unix/Makefile.in: do not run autoconf during 'make dist' as the
- configure is now a CVS-maintained file and should be up-to-date.
+ * tests/thread.test: thread-4.4: clear ::errorInfo in the thread as a
+ message is left here from init.tcl on windows due to no tcl_pkgPath.
-2003-05-19 Daniel Steffen <das@users.sourceforge.net>
+2007-08-20 Miguel Sofer <msofer@users.sf.net>
- * macosx/Tcl.pbproj/project.pbxproj: changed tclConfig.sh location in
- versioned framework subdirectories to be identical to location in
- framework toplevel; fixed stub library symbolic links to be Tcl
- version specific.
+ * generic/tclExecute.c (INST_SUB): fix usage of the new macro for
+ overflow detection in sums, adapt to subtraction. Lengthy comment
+ added.
-2003-05-16 Daniel Steffen <das@users.sourceforge.net>
+2007-08-19 Donal K. Fellows <dkf@users.sf.net>
- * macosx/Tcl.pbproj/project.pbxproj: updated copyright year.
+ * generic/tclExecute.c (Overflowing, TclIncrObj, TclExecuteByteCode):
+ Encapsulate Miguel's last change in a more mnemonic macro.
-2003-05-15 Jeff Hobbs <jeffh@ActiveState.com>
+2007-08-19 Miguel Sofer <msofer@users.sf.net>
- * win/tclWinFile.c (TclpMatchInDirectory): revert glob code to r1.44
- as 2003-04-14 optimizations broke Windows98 glob'ing.
+ * generic/tclExecute.c: changed the check for overflow in sums,
+ reducing objsize, number of branches and cache misses (according to
+ cachegrind). Non-overflow for s=a+b:
+ previous
+ ((a >= 0 || b >= 0 || s < 0) && (s >= 0 || b < 0 || a < 0))
+ now
+ (((a^s) >= 0) || ((a^b) < 0))
+ This expresses: "a and s have the same sign or else a and b have
+ different sign".
- * README: bumped version to 8.4.3
- * generic/tcl.h:
- * macosx/Tcl.pbproj/project.pbxproj:
- * tools/tcl.wse.in:
- * unix/configure:
- * unix/configure.in:
- * unix/tcl.spec:
- * win/README.binary:
- * win/configure:
- * win/configure.in:
+2007-08-19 Donal K. Fellows <dkf@users.sf.net>
- * doc/socket.n: nroff font handling correction.
+ * doc/interp.n (RESOURCE LIMITS): Added text to better explain why
+ time limits are described using absolute times. [Bug 1752148]
- * library/encoding/gb2312-raw.enc (new): This is the original
- gb2312.enc renamed to allow for it to still be used. This is needed by
- Tk (unix) because X fonts with gb2312* charsets really do want the
- original gb2312 encoding. [Bug 557030]
+2007-08-16 Miguel Sofer <msofer@users.sf.net>
-2003-05-14 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclVar.c: improved localVarNameType caching to leverage
+ the new availability of Tcl_Obj in variable names, avoiding string
+ comparisons to verify that the cached value is usable.
- * generic/tclCmdAH.c (Tcl_FormatObjCmd): Values which can't be
- anything but wide shouldn't be demoted to long. [consequence of HEAD
- fixes for Bug 699060]
+ * generic/tclExecute.c: check the two most frequent instructions
+ before the switch. Reduces both runtime and obj size a tiny bit.
-2003-05-14 Jeff Hobbs <jeffh@ActiveState.com>
+2007-08-16 Don Porter <dgp@users.sourceforge.net>
- * library/encoding/gb2312.enc: copy euc-cn.enc over original
- gb2312.enc. gb2312.enc appeared to not work as expected, and most uses
- of gb2312 really mean euc-cn (which may be the cause of the problem).
- [Bug 557030]
+ * generic/tclCompExpr.c: Added a "constant" field to the OpNode
+ struct (again "free" due to alignment requirements) to mark those
+ subexpressions that are completely known at compile time. Enhanced
+ CompileExprTree() and its callers to precompute these constant
+ subexpressions at compile time. This resolves the issue raised in [Bug
+ 1564517].
- * generic/tclEnv.c (TclUnsetEnv): Another putenv() copy behavior
- problem repaired when compiling on windows and using microsoft's
- runtime. [Bug 736421] (gravereaux)
+2007-08-15 Donal K. Fellows <donal.k.fellows@man.ac.uk>
-2003-05-13 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclIOUtil.c (TclGetOpenModeEx): Only set the O_APPEND flag
+ * tests/ioUtil.test (ioUtil-4.1): on a channel for the 'a'
+ mode and not for 'a+'. [Bug 1773127]
- * generic/tclIOUtil.c: add decl for FsThrExitProc to suppress warnings
+2007-08-14 Miguel Sofer <msofer@users.sf.net>
-2003-05-13 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclExecute.c (INST_INVOKE*): peephole opt, do not get the
+ interp's result if it will be pushed/popped.
- * generic/tclEvent.c (Tcl_Finalize): Removed unused variable to reduce
- compiler warnings. [Bug 664745]
+2007-08-14 Don Porter <dgp@users.sourceforge.net>
-2003-05-13 Joe Mistachkin <joe@mistachkin.com>
+ * generic/tclBasic.c: Use fully qualified variable names for
+ * tests/thread.test: ::errorInfo and ::errorCode so that string
+ * tests/trace.test: reported to variable traces are fully
+ qualified in agreement with Tcl 8.4 operations.
- * generic/tcl.decls: Changed Tcl_JoinThread parameter name from "id"
- * generic/tclDecls.h: to "threadId". [Bug 732477]
- * unix/tclUnixThrd.c:
- * win/tclWinThrd.c:
- * mac/tclMacThrd.c:
+2007-08-14 Daniel Steffen <das@users.sourceforge.net>
-2003-05-13 Daniel Steffen <das@users.sourceforge.net>
+ * unix/tclLoadDyld.c: use dlfcn API on Mac OS X 10.4 and later; fix
+ issues with loading from memory on intel and 64bit; add debug messages
- * generic/tcl.decls:
- * macosx/tclMacOSXBundle.c: added extended version of the
- Tcl_MacOSXOpenBundleResources() API taking an extra version number
- argument: Tcl_MacOSXOpenVersionedBundleResources(). This is needed to
- be able to access bundle resources in versioned frameworks such as Tcl
- and Tk, otherwise if multiple versions were installed, only the latest
- version's resources could be accessed. [Bug 736774]
+ * tests/load.test: add test load-10.1 for loading from vfs.
- * unix/tclUnixInit.c (Tcl_MacOSXGetLibraryPath): use new versioned
- bundle resource API to get tcl runtime library for TCL_VERSION.
- [Bug 736774]
+ * unix/dltest/pkga.c: whitespace & comment cleanup, remove
+ * unix/dltest/pkgb.c: unused pkgf.c.
+ * unix/dltest/pkgc.c:
+ * unix/dltest/pkge.c:
+ * unix/dltest/pkgf.c (removed):
+ * unix/dltest/pkgua.c:
+ * macosx/Tcl.xcodeproj/project.pbxproj:
- * generic/tclPlatDecls.h:
- * generic/tclStubInit.c: regen.
+2007-08-13 Don Porter <dgp@users.sourceforge.net>
- * unix/tclUnixPort.h: worked around the issue of realpath() not being
- thread-safe on Mac OS X by defining NO_REALPATH for threaded builds on
- Mac OS X. [Bug 711232]
+ * generic/tclExecute.c: Provide DECACHE/CACHE protection to the
+ * tests/trace.test: Tcl_LogCommandInfo() call. [Bug 1773040]
-2003-05-12 Don Porter <dgp@users.sourceforge.net>
+2007-08-12 Miguel Sofer <msofer@users.sf.net>
- * generic/tclInterp.c: (AliasObjCmd): Added refCounting of the words
- * tests/interp.test (interp-33.1): of the target of an interp
- alias during its execution. Also added test. [Bug 730244].
+ * generic/tclCmdMZ.c (Tcl_SplitObjCmd): use TclNewStringObj macro
+ instead of calling the function.
- * generic/tclBasic.c (TclInvokeObjectCommand): objv[argc] is no
- longer set to NULL (Tcl_CreateObjCommand docs already say that it
- should not be accessed).
+ * generic/tcl_Obj.c (TclAllocateFreeObjects): remove unneeded memset
+ to 0 of all allocated objects.
- * generic/tclObj.c (tclCmdNameType): Corrected variable use of the
- otherValuePtr or the twoPtrValue.ptr1 fields to store a
- (ResolvedCmdName *) as the internal rep. [Bug 726018].
+2007-08-10 Miguel Sofer <msofer@users.sf.net>
- * doc/Eval.3: Corrected prototype for Tcl_GlobalEvalObj [Bug 727622].
+ * generic/tclInt.h: remove redundant ops in TclNewStringObj macro.
-2003-05-12 Miguel Sofer <msofer@users.sf.net>
+2007-08-10 Miguel Sofer <msofer@users.sf.net>
- * generic/tclVar.c (TclObjLookupVar): [Bug 735335] temporary fix,
- disabling usage of tclNsVarNameType.
- * tests/var.test (var-15.1): test for [Bug 735335]
+ * generic/tclInt.h: fix the TclSetVarNamespaceVar macro, was causing a
+ leak.
-2003-05-10 Zoran Vasiljevic <zoran@archiware.com>
+2007-08-10 Don Porter <dgp@users.sourceforge.net>
- * unix/tclUnixThrd.c: corrected [Bug 723502]
+ * generic/tclCompExpr.c: Revise CompileExprTree() to use the
+ OpNode mark field scheme of tree traversal. This eliminates the need
+ to use magic values in the left and right fields for that purpose.
+ Also stop abusing the left field within ParseExpr() to store the
+ number of arguments in a parsed function call. CompileExprTree() now
+ determines that for itself at compile time. Then reorder code to
+ eliminate duplication.
-2003-05-10 Jeff Hobbs <jeffh@ActiveState.com>
+2007-08-09 Miguel Sofer <msofer@users.sf.net>
- * generic/tclIOUtil.c: ensure cd is thread-safe.
- [Bug 710642] (vasiljevic)
+ * generic/tclProc.c (TclCreateProc): better comments on the required
+ varflag values when loading precompiled procs.
- * win/tclWinSerial.c (SerialCloseProc): correct mem leak on closing a
- Windows serial port [Bug 718002] (schroedter)
+ * generic/tclExecute.c (INST_STORE_ARRAY):
+ * tests/trace.test (trace-2.6): whole array write traces on compiled
+ local variables were not firing. [Bug 1770591]
- * generic/tclCmdMZ.c (Tcl_StringObjCmd): prevent string repeat crash
- when overflow sizes were given (throws error). [Bug 714106]
+2007-08-08 Jeff Hobbs <jeffh@ActiveState.com>
-2003-05-09 Joe Mistachkin <joe@mistachkin.com>
+ * generic/tclProc.c (InitLocalCache): reference firstLocalPtr via
+ procPtr. codePtr->procPtr == NULL exposed by tbcload.
- * generic/tclThreadAlloc.c (TclFreeAllocCache): Fixed memory leak
- caused by treating cachePtr as a TLS index [Bug 731754].
+2007-08-08 Don Porter <dgp@users.sourceforge.net>
- * win/tclAppInit.c (Tcl_AppInit): Fixed memory leaks caused by not
- freeing the memory allocated by setargv and the async handler created
- by Tcl_AppInit. An exit handler has been created that takes care of
- both leaks. In addition, Tcl_AppInit now uses ckalloc instead of
- Tcl_Alloc to allow for easier leak tracking and to be more consistent
- with the rest of the Tcl core [Bugs 733156, 733221].
+ * generic/tclExecute.c: Corrected failure to compile/link in the
+ -DNO_WIDE_TYPE configuration.
- * tools/encoding/txt2enc.c (main): Fixed memory leak caused by failing
- to free the memory used by the toUnicode array of strings [Bug 733221]
+ * generic/tclExecute.c: Corrected improper use of bignum arguments to
+ * tests/expr.test: *SHIFT operations. [Bug 1770224]
-2003-05-05 Don Porter <dgp@users.sourceforge.net>
+2007-08-07 Miguel Sofer <msofer@users.sf.net>
- * library/tcltest/tcltest.tcl: The -returnCodes option to [test]
- failed to recognize the symbolic name "ok" for return code 0.
+ * generic/tclInt.h: remove comments refering to VAR_SCALAR, as that
+ flag bit does not exist any longer.
+ * generic/tclProc.c (InitCompiledLocals): removed optimisation for
+ non-resolved case, as the function is never called in that case.
+ Renamed the function to InitResolvedLocals to calrify the point.
-2003-05-05 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclInt.decls: Exporting via stubs to help xotcl adapt to
+ * generic/tclInt.h: VarReform.
+ * generic/tclIntDecls.h:
+ * generic/tclStubInit.c:
- * generic/tclBasic.c (Tcl_HideCommand): Fixed error message grammar
- and spelling.
+2007-08-07 Daniel Steffen <das@users.sourceforge.net>
-2003-04-29 Vince Darley <vincentdarley@users.sourceforge.net>
+ * generic/tclEnv.c: improve environ handling on Mac OS X (adapted
+ * unix/tclUnixPort.h: from Apple changes in Darwin tcl-64).
- * generic/tclFileName.c: fix to bug reported privately by Jeff where,
- for example, 'glob -path {[tcl]} *' gets confused by the leading
- special character (which is escaped internally), and instead lists
- files in '/'. Bug only occurs on Windows where '\' is also a
- directory separator. (Bug has been around at least since Tcl 8.3.)
- * tests/fileName.test: added test for the above bug.
+ * unix/Makefile.in: add support for compile flags specific to
+ object files linked directly into executables.
-2003-04-25 Don Porter <dgp@users.sourceforge.net>
+ * unix/configure.in (Darwin): only use -seg1addr flag when prebinding;
+ use -mdynamic-no-pic flag for object files linked directly into exes;
+ support overriding TCL_PACKAGE_PATH/TCL_MODULE_PATH in environment.
- * generic/tclBasic.c: Tcl_EvalObjv() failed to honor the
- TCL_EVAL_GLOBAL flag when resolving command names. Tcl_EvalEx passed a
- string rep including leading whitespace and comments to
- TclEvalObjvInternal().
+ * unix/configure: autoconf-2.59
-2003-04-25 Andreas Kupries <andreask@activestate.com>
+2007-08-06 Don Porter <dgp@users.sourceforge.net>
- * win/tclWinThrd.c: Applied [Patch 727271]. This patch changes the
- code to catch any errors returned by the windows functions handling
- TLS ASAP instead of waiting to get some mysterious crash later on due
- to bogus pointers. Patch provided by Joe Mistachkin.
+ * tests/parseExpr.test: Update source file name of expr parser code.
- This is a stop-gap measure to deal with the low number of ?TLS slots
- provided by some of the variants of Windows (60-80).
+ * generic/tclCompExpr.c: Added a "mark" field to the OpNode
+ struct, which is used to guide tree traversal. This field costs
+ nothing since alignement requirements used the memory already.
+ Rewrote ConvertTreeToTokens() to use the new field, which permitted
+ consolidation of utility routines CopyTokens() and
+ GenerateTokensForLiteral().
-2003-04-21 Don Porter <dgp@users.sourceforge.net>
+2007-08-06 Kevin B. Kenny <kennykb@users.sf.net>
- * library/tcltest/tcltest.tcl: When the return code of a test does
- not meet expectations, report that as the reason for test failure,
- and do not attempt to check the test result for correctness. [Bug
- 725253]
+ * generic/tclGetDate.y: Added a cast to the definition of YYFREE to
+ silence compiler warnings.
+ * generic/tclDate.c: Regenerated
+ * win/tclWinTest.c: Added a cast to GetSecurityDescriptorDacl call
+ to silence compiler warnings.
-2003-04-18 Jeff Hobbs <jeffh@ActiveState.com>
+2007-08-04 Miguel Sofer <msofer@users.sf.net>
- * generic/tclExecute.c (ExprCallMathFunc): remove incorrect
- extraneous cast from Tcl_WideAsDouble.
+ * generic/tclInt.decls: Exporting via stubs to help itcl adapt to
+ * generic/tclInt.h: VarReform. Added localCache initialization
+ * generic/tclIntDecls.h: to TclInitCompiledLocals (which only exists
+ * generic/tclProc.c: for itcl).
+ * generic/tclStubInit.c:
+ * generic/tclVar.c:
-2003-04-18 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2007-08-01 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * doc/open.n: Moved serial port options from [fconfigure]
- * doc/fconfigure.n: to [open] as it is up to the creator of a
- channel to describe the channel's special
- config options. [Bug 679010]
+ * library/word.tcl: Rewrote for greater efficiency. [Bug 1764318]
-2003-04-16 Don Porter <dgp@users.sourceforge.net>
+2007-08-01 Pat Thoyts <patthoyts@users.sourceforge.net>
- * generic/tcl.h Made changes so that the "wideInt" Tcl_ObjType
- * generic/tclObj.c is defined on all platforms, even those where
- * generic/tclPort.h TCL_WIDE_INT_IS_LONG is defined. Also made
- the Tcl_Value struct have a wideValue field on all platforms. This is
- a ***POTENTIAL INCOMPATIBILITY*** for TCL_WIDE_INT_IS_LONG platforms
- because that struct changes size. This is the same TIP 72
- incompatibility that was seen on other platforms at the 8.4.0 release,
- when this change should have happened as well. [Bug 713562]
+ * generic/tclInt.h: Added a TclOffset macro ala Tk_Offset to
+ * generic/tclVar.c: abstract out 'offsetof' which may not be
+ * generic/tclExceute.c: defined (eg: msvc6).
- * generic/tclInt.h: New internal macros TclGetWide() and
- TclGetLongFromWide() to deal with both forms of the "wideInt"
- Tcl_ObjType, so that conditional TCL_WIDE_INT_IS_LONG code
- is confined to the header file.
+2007-08-01 Miguel Sofer <msofer@users.sf.net>
- * generic/tclCmdAH.c: Replaced most coding that was conditional
- * generic/tclCmdIL.c: on TCL_WIDE_INT_IS_LONG with code that
- * generic/tclExecute.c: works across platforms, sometimes using
- * generic/tclTest.c: the new macros above to do it.
- * generic/tclUtil.c:
- * generic/tclVar.c:
+ * generic/tclVar.c (TclCleanupVar): fix [Bug 1765225], thx Larry
+ Virden.
-2003-04-17 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2007-07-31 Miguel Sofer <msofer@users.sf.net>
- * doc/socket.n: Added a paragraph to remind people to specify
- their encodings when using sockets. [Bug 630621]
+ * doc/Hash.3:
+ * generic/tclHash.c:
+ * generic/tclObj.c:
+ * generic/tclThreadStorage.c: (changes part of the patch below)
+ Stop Tcl_CreateHashVar from resetting hPtr->clientData to NULL after
+ calling the allocEntryProc for a custom table.
-2003-04-16 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tcl.h:
+ * generic/tclBasic.c:
+ * generic/tclCmdIL.c:
+ * generic/tclCompCmds.c:
+ * generic/tclCompile.c:
+ * generic/tclCompile.h:
+ * generic/tclExecute.c:
+ * generic/tclHash.c:
+ * generic/tclInt.decls:
+ * generic/tclInt.h:
+ * generic/tclIntDecls.h:
+ * generic/tclLiteral.c:
+ * generic/tclNamesp.c:
+ * generic/tclObj.c:
+ * generic/tclProc.c:
+ * generic/tclThreadStorage.c:
+ * generic/tclTrace.c:
+ * generic/tclVar.c: VarReform [Patch 1750051]
+
+ *** POTENTIAL INCOMPATIBILITY *** (tclInt.h and tclCompile.h)
+ Extensions that access internals defined in tclInt.h and/or
+ tclCompile.h may lose both binary and source compatibility. The
+ relevant changes are:
+ 1. 'struct Var' is completely changed, all acceses to its internals
+ (either direct or via the TclSetVar* and TclIsVar* macros) will
+ malfunction. Var flag values and semantics changed too.
+ 2. 'struct Bytecode' has an additional field that has to be
+ initialised to NULL
+ 3. 'struct Namespace' is larger, as the varTable is now one pointer
+ larger than a Tcl_HashTable. Direct access to its fields will
+ malfunction.
+ 4. 'struct CallFrame' grew one more field (the second such growth with
+ respect to Tcl8.4).
+ 5. API change for the functions TclFindCompiledLocal, TclDeleteVars
+ and many internal functions in tclVar.c
+
+ Additionally, direct access to variable hash tables via the standard
+ Tcl_Hash* interface is to be considered as deprecated. It still works
+ in the present version, but will be broken by further specialisation
+ of these hash tables. This concerns especially the table of array
+ elements in an array, as well as the varTable field in the Namespace
+ struct.
+
+2007-07-31 Miguel Sofer <msofer@users.sf.net>
+
+ * unix/configure.in: allow use of 'inline' in Tcl sources. [Patch
+ * win/configure.in: 1754128]
+ * win/makefile.vc: Regen with autoconf 2.61
+
+2007-07-31 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * unix/tclUnixInit.c (TclpSetVariables): Use the thread-safe getpwuid
+ replacement to fill the tcl_platform(user) field as it is not subject
+ to spoofing. [Bug 681877]
+
+ * unix/tclUnixCompat.c: Simplify the #ifdef logic.
+
+ * unix/tclUnixChan.c (FileWatchProc): Fix test failures.
+
+2007-07-30 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * unix/tclUnixChan.c (SET_BITS, CLEAR_BITS): Added macros to make this
+ file clearer.
+
+2007-07-24 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclBasic.c (TEOvI, GetCommandSource):
+ * generic/tclExecute.c (TEBC, TclGetSrcInfoForCmd):
+ * generic/tclInt.h:
+ * generic/tclTrace.c (TclCheck(Interp|Execution)Traces):
+ Removed the need for TEBC to inspect the command before calling TEOvI,
+ leveraging the TIP 280 infrastructure. Moved the generation of a
+ correct nul-terminated command string away from the trace code, back
+ into TEOvI/GetCommandSource.
- * doc/CrtMathFnc.3: Functions also have to deal with wide ints,
- but this was not documented. [Bug 709720]
+2007-07-20 Andreas Kupries <andreask@activestate.com>
-2003-04-15 Kevin Kenny <kennykb@acm.org>
+ * library/platform/platform.tcl: Fixed bug in 'platform::patterns'
+ * library/platform/pkgIndex.tcl: where identifiers not matching
+ * unix/Makefile.in: the special linux and solaris forms would not
+ * win/Makefile.in: get 'tcl' as an acceptable platform added to
+ * doc/platform.n: the result. Bumped package to version 1.0.3 and
+ * doc/platform_shell.n: updated documentation and Makefiles. Also
+ fixed bad version info in the documentation of platform::shell.
- * win/tclWinTime.c: Corrected use of types to make compilation
- compatible with VC++5.
+2007-07-19 Don Porter <dgp@users.sourceforge.net>
-2003-04-14 Kevin Kenny <kennykb@acm.org>
+ * generic/tclParse.c: In contexts where interp and parsePtr->interp
+ might be different, be sure to use the latter for error reporting.
+ Also pulled the interp argument back out of ParseTokens() since we
+ already had a parsePtr->interp to work with.
- * win/tclWinFile.c: added conditionals to restore compilation on
- VC++6, which was broken by recent changes.
+2007-07-18 Don Porter <dgp@users.sourceforge.net>
-2003-04-14 Vince Darley <vincentdarley@users.sourceforge.net>
+ * generic/tclCompExpr.c: Removed unused arguments and variables
- Merged various bug fixes from current cvs head:
+2007-07-17 Don Porter <dgp@users.sourceforge.net>
- * tests/cmdAH.test: better fix to test suite problem if /home is a
- symlink [Bug 703264]
+ * generic/tclCompExpr.c (ParseExpr): While adding comments to
+ explain the operations of ParseExpr(), made significant revisions to
+ the code so it would be easier to explain, and in the process made the
+ code simpler and clearer as well.
- * generic/tclIOUtil.c: fix bad error message with 'cd ""' [Bug 704917]
- * win/tclWinFile.c:
- * win/tclWin32Dll.c:
- * win/tclWinInt.h: allow Tcl to differentiate between reparse points
- which are symlinks and mounted volumes, and correctly handle the
- latter. This involves some elaborate code to find the actual drive
- letter (if possible) corresponding to a mounted volume. [Bug 697862]
- * tests/fileSystem.test: add constraints to stop tests running in
- ordinary tcl interpreter. [Bug 705675]
- * generic/tclIOUtil.c: Some re-arrangement of code to bring it closer
- to CVS HEAD. No functional changes.
+2007-07-15 Don Porter <dgp@users.sourceforge.net>
- * tests/fCmd.test:
- * win/tclWinFile.c: added some filesystem optimisation to the
- 'glob' implementation, and some new tests.
+ * generic/tclCompExpr.c: More commentary.
+ * tests/parseExpr.test: Several tests of syntax error messages
+ to check that when expression substrings are truncated they leave
+ visible the context relevant to the reported error.
- * tests/winFile.test:
- * tests/ioUtil.test:
- * tests/unixFCmd.test: renumbered tests with duplicate numbers. [Bug
- 710361]
+2007-07-12 Don Porter <dgp@users.sourceforge.net>
-2003-04-12 Kevin Kenny <kennykb@acm.org>
+ * generic/tclCompExpr.c: Factored out, corrected, and commented
+ common code for reporting syntax errors in LEAF elements.
- * tests/clock.test: Renumbered test cases to avoid duplicates [Bug
- 710310].
- * tests/winTime.test:
- * win/tclWinTest.c (TestwinclockCmd, TestwinsleepCmd):
- * win/tclWinTime.c (Tcl_WinTime, UpdateTimeEachSecond,
- (ResetCounterSamples, AccumulateSample, SAMPLES, TimeInfo): Made
- substantial changes to the phase-locked loop (replaced an IIR filter
- with an FIR one) in a quest for improved loop stability (Bug not
- logged at SF, but cited in private communication from Jeff Hobbs).
+2007-07-11 Miguel Sofer <msofer@users.sf.net>
-2003-04-11 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclCompCmds.c (TclCompileWhileCmd):
+ * generic/tclCompile.c (TclCompileScript):
+ Corrected faulty avoidance of INST_START_CMD when the first opcode in
+ a script is within a loop (as produced by 'while 1'), so that the
+ corresponding command is properly counted. [Bug 1752146]
+
+2007-07-11 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCompExpr.c: Added a "parseOnly" flag argument to
+ ParseExpr() to indicate whether the caller is Tcl_ParseExpr(), with an
+ end goal of filling a Tcl_Parse with Tcl_Tokens representing the
+ parsed expression, or TclCompileExpr() with the goal of compiling and
+ executing the expression. In the latter case, more aggressive
+ conversion of QUOTED and BRACED lexeme to literals is done. In the
+ former case, all such conversion is avoided, since Tcl_Token
+ production would revert it anyway. This enables simplifications to the
+ GenerateTokensForLiteral() routine as well.
+
+2007-07-10 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCompExpr.c: Added a field for operator precedence
+ to be stored directly in the parse tree. There's no memory cost to
+ this addition, since that memory would have been lost to alignment
+ issues anyway. Also, converted precedence definitions and lookup
+ tables to use symbolic constants instead of raw number for improved
+ readability, and continued extending/improving/correcting comments.
+ Removed some unused counter variables. Renamed some variables for
+ clarity and replaced some cryptic logic with more readable macros.
+
+2007-07-09 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCompExpr.c: Revision so that the END lexeme never
+ gets inserted into the parse tree. Later tree traversal never reaches
+ it since its location in the tree is not variable. Starting and
+ stopping with the START lexeme (node 0) is sufficient. Also finished
+ lexeme code commentary.
+
+ * generic/tclCompExpr.c: Added missing creation and return of
+ the Tcl_Parse fields that indicate error conditions. [Bug 1749987]
+
+2007-07-05 Don Porter <dgp@users.sourceforge.net>
- * generic/tclCmdMZ.c (Tcl_StringObjCmd,STR_IS_INT): Corrected
- inconsistent results of [string is integer] observed on systems
- where sizeof(long) != sizeof(int). [Bug 718878]
- * tests/string.test: Added tests for Bug 718878.
- * doc/string.n: Clarified that [string is integer] accepts
- 32-bit integers.
+ * library/init.tcl (unknown): Corrected inconsistent error message
+ in interactive [unknown] when empty command is invoked. [Bug 1743676]
-2003-04-11 Andreas Kupries <andreask@activestate.com>
+2007-07-05 Miguel Sofer <msofer@users.sf.net>
- * generic/tclIO.c (UpdateInterest): When dropping interest in
- TCL_READABLE now dropping interest in TCL_EXCEPTION too. This fixes a
- bug where Expect detects eof on a file prematurely on Solaris 2.6 and
- higher. A much more complete explanation is in the code itself (40
- lines of comments for a one-line change :)
+ * generic/tclNamesp.c (SetNsNameFromAny):
+ * generic/tclObj.c (SetCmdNameFromAny): Avoid unnecessary
+ ckfree/ckalloc when the old structs can be reused.
-2003-04-10 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2007-07-04 Miguel Sofer <msofer@users.sf.net>
- * doc/binary.n: Fixed typo in [binary format w] desc. [Bug 718543]
+ * generic/tclNamesp.c: Fix case where a FQ cmd or ns was being cached
+ * generic/tclObj.c: in a different interp, tkcon. [Bug 1747512]
-2003-04-08 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2007-07-03 Don Porter <dgp@users.sourceforge.net>
- * generic/tclCmdAH.c (Tcl_ErrorObjCmd): Strings are only empty if they
- have zero length, not if their first byte is zero, so fix test
- guarding Tcl_AddObjErrorInfo to take this into account. [Bug reported
- by Don Porter; no bug-id.]
+ * generic/tclCompExpr.c: Revised #define values so that there
+ is now more expansion room to define more BINARY operators.
-2003-04-07 Don Porter <dgp@users.sourceforge.net>
+2007-07-02 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclCompCmds.c (TclCompileIfCmd): Corrected string limits of
- arguments interpolated in error messages. [Bug 711371]
+ * generic/tclHash.c (CompareStringKeys): Always use the strcmp()
+ version; the operation is functionally equivalent, the speed is
+ identical (up to measurement limitations), and yet the code is
+ simpler. [FRQ 951168]
- * generic/tclCmdMZ.c (TraceExecutionProc): Added missing
- Tcl_DiscardResult() call to avoid memory leak.
+2007-07-02 Don Porter <dgp@users.sourceforge.net>
-2003-04-07 Donal K. Fellows <zzcgudf@ernie.mvc.mcc.ac.uk>
+ * generic/tcl.h: Removed TCL_PRESERVE_BINARY_COMPATIBILITY and
+ * generic/tclHash.c: any code enabled when it is set to 0. We will
+ * generic/tclStubInit.c: always want to preserve binary compat
+ of the structs that appear in the interface through the 8.* series of
+ releases, so it's pointless to drag around this never-enabled
+ alternative.
- * generic/tclObj.c (tclWideIntType, TclInitObjSubsystem):
- (SetBooleanFromAny): Make sure that tclWideIntType is defined and
- somewhat sensible everywhere. [Bug 713562]
+ * generic/tclIO.c: Removed dead code.
+ * unix/tclUnixChan.c:
-2003-04-02 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tclCompExpr.c: Removed dead code, old implementations
+ * generic/tclEvent.c: of expr parsing and compiling, including the
+ * generic/tclInt.h: routine TclFinalizeCompilation().
- * win/configure: Regen.
- * win/configure.in: Set stub lib flag based on new LIBFLAGSUFFIX
- variable.
- * win/tcl.m4 (SC_CONFIG_CFLAGS): Set new LIBFLAGSUFFIX that works like
- LIBSUFFIX, it is used when creating library names. The previous
- implementation would generate -ltclstub85 instead of -ltclstub85s when
- configured with --disable-shared.
+2007-06-30 Donal K. Fellows <dkf@users.sf.net>
-2003-04-01 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclCmdIL.c (Tcl_LsortObjCmd): Plug a memory leak caused by a
+ missing Tcl_DecrRefCount on an error path. [Bug 1717186]
- * tests/README: Direct [source] of *.test files is no longer
- recommended. The tests/*.test files should only be evaluated under the
- control of the [runAllTests] command in tests/all.tcl.
+2007-06-30 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
-2003-03-27 Miguel Sofer <msofer@users.sf.net>
+ * generic/tclThread.c: Prevent RemeberSyncObj() from growing the sync
+ object lists by reusing already free'd slots, if possible. See
+ discussion on Bug 1726873 for more information.
- * tests/encoding.test:
- * tests/proc-old.test:
- * tests/set-old.test: Altered test numers to eliminate duplicates,
- [Bugs 710313, 710320, 710352]
+2007-06-29 Donal K. Fellows <dkf@users.sf.net>
-2003-03-27 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * doc/DictObj.3 (Tcl_DictObjDone): Improved documentation of this
+ function to make it clearer how to use it. [Bug 1710795]
- * tests/parseOld.test: Altered test numers to eliminate duplicates.
- * tests/parse.test: [Bugs 710365, 710369]
- * tests/expr-old.test:
- * tests/expr.test:
+2007-06-29 Daniel Steffen <das@users.sourceforge.net>
- * tests/utf.test: Altered test numers to eliminate duplicates.
- * tests/trace.test: [Bugs 710322, 710327, 710349, 710363]
- * tests/lsearch.test:
- * tests/list.test:
- * tests/info.test:
- * tests/incr-old.test:
- * tests/if-old.test:
- * tests/format.test:
- * tests/foreach.test:
+ * generic/tclAlloc.c: on Darwin, ensure memory allocated by
+ * generic/tclThreadAlloc.c: the custom TclpAlloc()s is aligned to
+ 16 byte boundaries (as is the case with the Darwin system malloc).
-2003-03-26 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclGetDate.y: use ckalloc/ckfree instead of malloc/free.
+ * generic/tclDate.c: bison 1.875e
- * doc/tcltest.n:
- * library/tcltest/tcltest.tcl: Added reporting during [configure
- -debug 1] operations to warn about multiple uses of the same test
- name. [FR 576693] Replaced [regexp] and [regsub] with [string map]
- where possible. Thanks to David Welton. [Bugs 667456,667558]
- * library/tcltest/pkgIndex.tcl: Bumped to tcltest 2.2.3
+ * generic/tclBasic.c (TclEvalEx): fix warnings.
- * tests/msgcat.test (msgcat-2.2.1): changed test name to avoid
- duplication. [Bug 710356]
+ * macosx/Tcl.xcodeproj/project.pbxproj: better support for renamed tcl
+ * macosx/Tcl.xcodeproj/default.pbxuser: source dir; add 10.5 SDK build
+ * macosx/Tcl-Common.xcconfig: config; remove tclMathOp.c.
- * unix/dltest/pkg?.c: Changed all Tcl_InitStubs calls to pass argument
- exact = 0, so that rebuilds are not required when Tcl bumps to a new
- version. [Bug 701926]
+ * macosx/README: document Tcl.xcodeproj changes.
-2003-03-24 Miguel Sofer <msofer@users.sf.net>
+2007-06-28 Don Porter <dgp@users.sourceforge.net>
- * generic/tclVar.c:
- * tests/var.test: fixing ObjMakeUpvar's lookup algorithm for the
- created local variable, [Bugs 631741] (Chris Darroch) and [696893]
- (David Hilker).
+ * generic/tclBasic.c: Removed dead code, including the
+ * generic/tclExecute.c: entire file tclMathOp.c.
+ * generic/tclInt.h:
+ * generic/tclMathOp.c (removed):
+ * generic/tclTestObj.c:
+ * win/tclWinFile.c:
-2003-03-22 Kevin Kenny <kennykb@acm.org>
+ * unix/Makefile.in: Updated to reflect deletion of tclMathOp.c.
+ * win/Makefile.in:
+ * win/makefile.bc:
+ * win/makefile.vc:
- * library/dde/pkgIndex.tcl:
- * library/reg/pkgIndex.tcl: Fixed a bug where [package require dde] or
- [package require registry] attempted to load the release version of
- the DLL into a debug build. [Bug 708218] Thanks to Joe Mistachkin for
- the patch.
- * win/makefile.vc: Added quoting around the script name in the 'test'
- target; Joe Mistachkin insists that he has a configuration that fails
- to launch tcltest without it, and it appears harmless otherwise.
-
-2003-03-20 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclInt.h (tclOriginalNotifier):
- * generic/tclStubInit.c (tclOriginalNotifier):
- * mac/tclMacNotify.c (Tcl_SetTimer,Tcl_WaitForEvent):
- * unix/tclUnixNotfy.c (Tcl_SetTimer,Tcl_WaitForEvent,
- (Tcl_CreateFileHandler,Tcl_DeleteFileHandler):
- * win/tclWinNotify.c (Tcl_SetTimer,Tcl_WaitForEvent): Some linkers
- apparently use a different representation for a pointer to a function
- within the same compilation unit and a pointer to a function in a
- different compilation unit. This causes checks like those in the
- original notifier procedures to fall into infinite loops. The fix is
- to store pointers to the original notifier procedures in a struct
- defined in the same compilation unit as the stubs tables, and compare
- against those values. [Bug 707174]
-
- * generic/tclInt.h: Removed definition of ParseValue struct that is no
- longer used.
-
-2003-03-19 Miguel Sofer <msofer@users.sf.net>
+2007-06-28 Pat Thoyts <patthoyts@users.sourceforge.net>
- * generic/tclCompile.c:
- * tests/compile.test: bad command count on TCL_OUT_LINE_COMPILE
- [Bug 705406] (Don Porter).
+ * generic/tclBasic.c: Silence constness warnings for TclStackFree
+ * generic/tclCompCmds.c: when building with msvc.
+ * generic/tclFCmd.c:
+ * generic/tclIOCmd.c:
+ * generic/tclTrace.c:
-2003-03-19 Don Porter <dgp@users.sourceforge.net>
+2007-06-28 Miguel Sofer <msofer@users.sf.net>
- * doc/Eval.3 (Tcl_EvalObjEx): Corrected CONST and
- * doc/ParseCmd.3 (Tcl_EvalTokensStandard): return type errors in
- documentation. [Bug 683994]
+ * generic/tclVar.c (UnsetVarStruct): fix possible segfault.
-2003-03-18 Kevin Kenny <kennykb@users.sourceforge.net>
+2007-06-27 Don Porter <dgp@users.sourceforge.net>
- * tests/registry.test: Changed the conditionals to avoid an abort if
- [testlocale] is missing, as when running the test in tclsh rather than
- tcltest. [Bug 705677]
+ * generic/tclTrace.c: Corrected broken trace reversal logic in
+ * generic/tclTest.c: TclCheckInterpTraces that led to infinite loop
+ * tests/trace.test: when multiple Tcl_CreateTrace traces were set
+ and one of them did not fire due to level restrictions. [Bug 1743931]
-2003-03-18 Daniel Steffen <das@users.sourceforge.net>
+2007-06-26 Don Porter <dgp@users.sourceforge.net>
- * tools/tcltk-man2html.tcl: added support for building 'make html'
- from inside distribution directories named with 8.x.x version numbers.
- tcltk-man2html now uses the latest tcl8.x.x resp. tk8.x.x directories
- found inside its --srcdir argument.
+ * generic/tclBasic.c (TclEvalEx): Moved some arrays from the C
+ stack to the Tcl stack.
-2003-03-18 Vince Darley <vincentdarley@users.sourceforge.net>
+2007-06-26 Miguel Sofer <msofer@users.sf.net>
- * tests/cmdAH.test: fix test suite problem if /home is a symlink
- * generic/tclIOUtil.c: fix bad error message with 'cd ""'
- * win/tclWinFile.c: allow Tcl to differentiate between reparse points
- which are symlinks and mounted drives.
+ * generic/tclVar.c (UnsetVarStruct): more streamlining.
- These changes fix [Bugs 703264, 704917, 697862] respectively.
+2007-06-25 Don Porter <dgp@users.sourceforge.net>
-2003-03-17 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclExecute.c: Safety checks to avoid crashes in the
+ TclStack* routines when called with an incompletely initialized
+ interp. [Bug 1743302]
- * doc/lsearch.n: Altered documentation of -ascii options so
- * doc/lsort.n: they don't specify that they operate on
- ASCII strings, which they never did
- anyway. [Bug 703807]
+2007-06-25 Miguel Sofer <msofer@users.sf.net>
-2003-03-14 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclVar.c (UnsetVarStruct): fixing incomplete change, more
+ streamlining.
- * generic/tclCmdAH.c (Tcl_FileObjCmd): Remove assumption that file
- times and longs are the same size. [Bug 698146]
- (Tcl_FormatObjCmd): Stop surprising type conversions from
- happening when working with integer and wide values. [Bug 699060]
+2007-06-24 Miguel Sofer <msofer@users.sf.net>
- * generic/tclCmdAH.c (Tcl_FormatObjCmd): Only add the modifier that
- indicates we've got a wide int when we're formatting in an integer
- style. Stops some libc's from going mad. [Bug 702622]
- Also tidied whitespace.
+ * generic/tclVar.c (TclDeleteCompiledLocalVars): removed inlining that
+ ended up not really optimising (limited benchmarks). Now calling
+ UnsetVarStruct (streamlined old code is #ifdef'ed out, in case better
+ benchmarks do show a difference).
-2003-03-13 Kevin Kenny <kennykb@users.sourceforge.net>
+ * generic/tclVar.c (UnsetVarStruct): fixed a leak introduced in last
+ commit.
- * win/makefile.vc: Backed the version to 8.4 on the 8.4 branch. (I
- just loathe sticky tags).
+2007-06-23 Miguel Sofer <msofer@users.sf.net>
-2003-03-12 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclVar.c (UnsetVarStruct, TclDeleteVars): made the logic
+ slightly clearer, eliminated some duplicated code.
- * generic/tcl.h: Removed TCL_PREFIX_IDENT and TCL_DEBUG_IDENT
- * win/tclWinPipe.c: from tcl.h -- they are not part of Tcl's
- public interface. Put them in win/tclWinPipe.c where they are used.
+ *** POTENTIAL INCOMPATIBILITY *** (tclInt.h and Var struct users)
+ The core never builds VAR_LINK variable to have traces. Such a
+ "monster", should one exist, will now have its unset traces called
+ *before* it is unlinked.
- * generic/tclCmdMZ.c (Tcl_SubstObj): Corrected and added test for
- * tests/subst.test (subst-2.4): Tcl_SubstObj's incorrect
- halting of substitution at the first \x00 byte. [Bug 685106]
+2007-06-23 Daniel Steffen <das@users.sourceforge.net>
- * generic/tclInterp.c (Tcl_InterpObjCmd): Corrected and added
- * tests/interp.test (interp-2.13): test for option
- parsing beyond objc for [interp create --]. Thanks to Marco Maggi.
- [Bug 702383]
+ * macosx/tclMacOSXNotify.c (AtForkChild): don't call CoreFoundation
+ APIs after fork() on systems where that would lead to an abort().
-2003-03-11 Kevin Kenny <kennykb@users.sourceforge.net>
+2007-06-22 Don Porter <dgp@users.sourceforge.net>
- * win/makefile.vc: Added two missing uses of $(DBGX) so that
- tclpip8x.dll loads without panicking on Win9x.
+ * generic/tclExecute.c: Revised TclStackRealloc() signature to better
+ * generic/tclInt.h: parallel (and fall back on) Tcl_Realloc.
-2003-03-08 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclNamesp.c (TclResetShadowesCmdRefs): Replaced
+ ckrealloc based allocations with TclStackRealloc allocations.
- * doc/tcltest.n: Added missing "-body" to example. Thanks to
- Helmut Giese. [Bug 700011]
+ * generic/tclCmdIL.c: More conversions to use TclStackAlloc.
+ * generic/tclScan.c:
-2003-03-06 Don Porter <dgp@users.sourceforge.net>
+2007-06-21 Don Porter <dgp@users.sourceforge.net>
- * generic/TclUtf.c (Tcl_UniCharNcasecmp): Corrected failure to
- * tests/utf.test (utf-25.*): properly compare Unicode strings of
- different case in a case insensitive manner. [Bug 699042]
+ * generic/tclBasic.c: Move most instances of the Tcl_Parse struct
+ * generic/tclCompExpr.c: off the C stack and onto the Tcl stack. This
+ * generic/tclCompile.c: is a rather large struct (> 3kB).
+ * generic/tclParse.c:
-2003-03-03 Jeff Hobbs <jeffh@ActiveState.com>
+2007-06-21 Miguel Sofer <msofer@users.sf.net>
- *** 8.4.2 TAGGED FOR RELEASE ***
+ * generic/tclBasic.c (TEOvI): Made sure that leave traces
+ * generic/tclExecute.c (INST_INVOKE): that were created during
+ * tests/trace.test (trace-36.2): execution of an originally
+ untraced command do not fire [Bug 1740962], partial fix.
-2003-03-03 Daniel Steffen <das@users.sourceforge.net>
+2007-06-21 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- Mac OS Classic specific fixes:
- * generic/tclIOUtil.c (TclNewFSPathObj): on TCL_PLATFORM_MAC,
- skip potential directory separator at the beginning of addStrRep.
- * mac/tclMacChan.c (OpenFileChannel, CommonWatch): followup
- fixes to cut and splice implementation for file channels.
- * mac/tclMacFile.c (TclpUtime): pass native path to utime().
- * mac/tclMacFile.c (TclpObjLink): correctly implemented creation
- of alias files via new static proc CreateAliasFile().
- * mac/tclMacPort.h: define S_ISLNK macro to fix stat'ing of links.
- * mac/tclMacUtil.c (FSpLocationFromPathAlias): fix to enable
- stat'ing of broken links.
+ * generic/tcl.h, generic/tclCompile.h, generic/tclCompile.c: Remove
+ references in comments to obsolete {expand} notation. [Bug 1740859]
-2003-03-03 Kevin Kenny <kennykb@users.sourceforge.net>
+2007-06-20 Miguel Sofer <msofer@users.sf.net>
- * win/Makefile.vc: corrected bug introduced by 'g' for debug builds.
+ * generic/tclVar.c: streamline namespace vars deletion: only compute
+ the variable's full name if the variable is traced.
-2003-03-03 Don Porter <dgp@users.sourceforge.net>
+2007-06-20 Don Porter <dgp@users.sourceforge.net>
- * library/dde/pkgIndex.tcl: dde bumped to version 1.2.1 for
- * win/tclWinDde.c: bundled release with Tcl 8.4.2
+ * generic/tclInt.decls: Revised the interfaces of the routines
+ * generic/tclExecute.c: TclStackAlloc and TclStackFree to make them
+ easier for callers to use (or more precisely, harder to misuse).
+ TclStackFree now takes a (void *) argument which is the pointer
+ intended to be freed. TclStackFree will panic if that's not actually
+ the memory the call will free. TSA/TSF also now tolerate receiving
+ (interp == NULL), in which case they simply fall back to be calls to
+ Tcl_Alloc/Tcl_Free.
- * library/reg/pkgIndex.tcl: registry bumped to version 1.1.1 for
- * win/tclWinReg.c: bundled release with Tcl 8.4.2
+ * generic/tclIntDecls.h: make genstubs
- * library/opt/pkgIndex.tcl: updated package index to version 0.4.4
+ * generic/tclBasic.c: Updated callers
+ * generic/tclCmdAH.c:
+ * generic/tclCmdIL.c:
+ * generic/tclCompCmds.c:
+ * generic/tclCompExpr.c:
+ * generic/tclCompile.c:
+ * generic/tclFCmd.c:
+ * generic/tclFileName.c:
+ * generic/tclIOCmd.c:
+ * generic/tclIndexObj.c:
+ * generic/tclInterp.c:
+ * generic/tclNamesp.c:
+ * generic/tclProc.c:
+ * generic/tclTrace.c:
+ * unix/tclUnixPipe.c:
-2003-02-28 Jeff Hobbs <jeffh@ActiveState.com>
+2007-06-20 Jeff Hobbs <jeffh@ActiveState.com>
- * win/configure:
- * win/configure.in: check for 'g' for debug build type, not 'd'.
- * win/rules.vc (DBGX): correct to use 'g' for nmake win makefile
- to match the cygwin makefile for debug builds. [Bug 635107]
+ * tools/tcltk-man2html.tcl: revamp of html doc output to use CSS,
+ standardized headers, subheaders, dictionary sorting of names.
-2003-02-28 Vince Darley <vincentdarley@users.sourceforge.net>
+2007-06-18 Jeff Hobbs <jeffh@ActiveState.com>
- * doc/file.n: subcommand is 'file volumes' not 'file volume'
+ * tools/tcltk-man2html.tcl: clean up copyright merging and output.
+ clean up coding constructs.
-2003-02-27 Jeff Hobbs <jeffh@ActiveState.com>
+2007-06-18 Miguel Sofer <msofer@users.sf.net>
- * generic/tclIOUtil.c (MakeFsPathFromRelative): removed dead code
- check of typePtr (darley).
+ * generic/tclCmdIL.c (InfoFrameCmd):
+ * generic/tclCmdMZ.c (Tcl_SwitchObjCmd):
+ * generic/tclCompile.c (TclInitCompileEnv):
+ * generic/tclProc.c (Tcl_ProcObjCmd, SetLambdaFromAny): Moved the
+ CmdFrame off the C stack and onto the Tcl stack.
- * tests/winTime.test: added note about PCI hardware dependency
- issues with high performance clock.
+ * generic/tclExecute.c (TEBC): Moved the CmdFrame off the C stack and
+ onto the Tcl stack, between the catch and the execution stacks
-2003-02-27 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2007-06-18 Don Porter <dgp@users.sourceforge.net>
- * tests/lsearch.test (lsearch-10.7):
- * generic/tclCmdIL.c (Tcl_LsearchObjCmd): Stopped -start option from
- causing an option when used with an empty list. [Bug 694232]
+ * generic/tclBasic.c (TclEvalEx,TclEvalObjEx): Moved the CmdFrame off
+ the C stack and onto the Tcl stack.
-2003-02-26 Chengye Mao <chengye.geo@yahoo.com>
+2007-06-17 Donal K. Fellows <dkf@users.sf.net>
- * win/tclWinInit.c: fixed a bug in TclpSetVariables by initializing
- dwUserNameLen with the sizeof(szUserName) before calling GetUserName.
- Don't know if this bug has been recorded: it caused crash in starting
- Tcl or wish in Windows.
+ * generic/tclProc.c (TclObjInterpProcCore): Minor fixes to make
+ * generic/tclExecute.c (TclExecuteByteCode): compilation debugging
+ builds work again. [Bug 1738542]
-2003-02-26 Jeff Hobbs <jeffh@ActiveState.com>
+2007-06-16 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclCmdMZ.c (TraceCommandProc): Fix mem leak when
- deleting a command that had trace on it. [Bug 693564] (sofer)
+ * generic/tclProc.c (TclObjInterpProcCore): Use switch instead of a
+ chain of if's for a modest performance gain and a little more clarity.
-2003-02-25 Don Porter <dgp@users.sourceforge.net>
+2007-06-15 Miguel Sofer <msofer@users.sf.net>
- * doc/pkgMkIndex.n: Modified [pkg_mkIndex] to use -nocase matching
- * library/package.tcl: of -load patterns, to better accomodate
- common user errors due to confusion between [package names] names
- and [info loaded] names.
+ * generic/tclCompCmds.c: Simplified [variable] compiler and executor.
+ * generic/tclExecute.c: Missed updates to "there is always a valid
+ frame".
-2003-02-25 Andreas Kupries <andreask@activestate.com>
+ * generic/tclCompile.c: reverted TclEvalObjvInternal and INST_INVOKE
+ * generic/tclExecute.c: to essentially what they were previous to the
+ * generic/tclBasic.c: commit of 2007-04-03 [Patch 1693802] and the
+ subsequent optimisations, as they break the new trace tests described
+ below.
- * tests/pid.test: See below [Bug 678412].
- * tests/io.test: Made more robust against spaces in paths [Bug 678400]
+ * generic/trace.test: added tests 36 to 38 for dynamic trace creation
+ and addition. These tests expose a change in dynamics due to a recent
+ round of optimisations. The "correct" behaviour is not described in
+ docs nor TIP 62.
-2003-02-25 Miguel Sofer <msofer@users.sf.net>
+2007-06-14 Miguel Sofer <msofer@users.sf.net>
- * tests/execute.test: cleaning up testobj's at the end, to avoid leak
- warning by valgrind.
+ * generic/tclInt.decls: Modif to the internals of TclObjInterpProc
+ * generic/tclInt.h: to reduce stack consumption and improve task
+ * generic/tclIntDecls.h: separation. Changes the interface of
+ * generic/tclProc.c: TclObjInterpProcCore (patching TclOO
+ simultaneously).
-2003-02-22 Zoran Vasiljevic <zoran@archiwrae.com>
+ * generic/tclProc.c (TclObjInterpProcCore): simplified obj management
+ in wrongNumArgs calls.
- * generic/tclEvent.c (Tcl_FinalizeThread): Fix [Bug 571002]
+2007-06-14 Don Porter <dgp@users.sourceforge.net>
-2003-02-21 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclCompile.c: SetByteCodeFromAny() can no longer return any
+ * generic/tclExecute.c: code other than TCL_OK, so remove code that
+ * generic/tclProc.c: formerly handled exceptional codes.
- * tests/binary.test (binary-44.[34]):
- * generic/tclBinary.c (ScanNumber): Fixed problem with unwanted
- sign-bit propagation when scanning wide ints. [Bug 690774]
+2007-06-13 Miguel Sofer <msofer@users.sf.net>
-2003-02-21 Daniel Steffen <das@users.sourceforge.net>
+ * generic/tclExecute.c (TclCompEvalObj): missed update to "there is
+ always a valid frame".
- * mac/tclMacChan.c (TclpCutFileChannel, TclpSpliceFileChannel):
- Implemented missing cut and splice procs for file channels.
+ * generic/tclProc.c (TclObjInterpProcCore): call TEBC directly instead
+ of going through TclCompEvalObj - no need to check the compilation's
+ freshness, this has already been done. This improves speed and should
+ also provide some relief to [Bug 1066755].
-2003-02-21 Don Porter <dgp@users.sourceforge.net>
+2007-06-12 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * library/package.tcl (tclPkgUnknown): Minor performance tweaks to
- reduce the number of [file] invocations. Meant to improve startup
- times, at least a little bit. [Patch 687906]
+ * generic/tclBasic.c (Tcl_CreateInterp): Turn the [info] command into
+ * generic/tclCmdIL.c (TclInitInfoCmd): an ensemble, making it easier
+ for third-party code to plug into.
-2003-02-20 Daniel Steffen <das@users.sourceforge.net>
+ * generic/tclIndexObj.c (Tcl_WrongNumArgs):
+ * generic/tclNamesp.c, generic/tclInt.h (tclEnsembleCmdType): Make
+ Tcl_WrongNumArgs do replacement correctly with ensembles and other
+ sorts of complex replacement strategies.
- * unix/tcl.m4:
- * unix/tclUnixPipe.c: (macosx) use vfork() instead of fork() to create
- new processes, as recommended by Apple (vfork can be up to 100 times
- faster thank fork on macosx).
- * unix/configure: regen.
+2007-06-11 Miguel Sofer <msofer@users.sf.net>
-2003-02-20 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclExecute.c: comments added to explain iPtr->numLevels
+ management.
- * generic/tclEncoding.c (LoadTableEncoding):
- * library/encoding/cp932.enc: Correct jis round-trip encoding
- * library/encoding/euc-jp.enc: by adding 'R' type to .enc files.
- * library/encoding/iso2022-jp.enc: [Patch 689341] (koboyasi, taguchi)
- * library/encoding/jis0208.enc:
- * library/encoding/shiftjis.enc:
- * tests/encoding.test:
+ * generic/tclNamesp.c: tweaks to Tcl_GetCommandFromObj and
+ * generic/tclObj.c: TclGetNamespaceFromObj; modified the usage of
+ structs ResolvedCmdName and ResolvedNsname so that the field refNsPtr
+ is NULL for fully qualified names.
- * unix/tclUnixChan.c (Tcl_MakeTcpClientChannel): add
- MakeTcpClientChannelMode that takes actual mode flags to avoid
- hang on OS X (may be OS X bug, but patch works x-plat).
- [Bug 689835] (steffen)
+2007-06-10 Miguel Sofer <msofer@users.sf.net>
-2003-02-20 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclBasic.c: Further TEOvI split, creating a new
+ * generic/tclCompile.h: TclEvalObjvKnownCommand() function to handle
+ * generic/tclExecute.c: commands that are already known and are not
+ traced. INST_INVOKE now calls into this function instead of inlining
+ parts of TEOvI. Same perf, better isolation.
- * doc/regsub.n: Typo fix [Bug 688943]
+ ***POTENTIAL INCOMPAT*** There is a subtle issue with the timing of
+ execution traces that is changed here - first change appeared in my
+ commit of 2007-04-03 [Patch 1693802], which caused some divergence
+ between compiled and non-compiled code.
+ ***THIS CHANGE IS UNDER REVIEW***
-2003-02-19 Jeff Hobbs <jeffh@ActiveState.com>
+2007-06-10 Jeff Hobbs <jeffh@ActiveState.com>
- * unix/tclUnixThrd.c (TclpReaddir):
- * unix/tclUnixPort.h: update to Bug 689100 patch to ensure that
- there is a defined value of MAXNAMLEN (aka NAME_MAX in POSIX) and
- that we have some buffer allocated.
+ * README: updated links. [Bug 1715081]
-2003-02-19 Daniel Steffen <das@users.sourceforge.net>
+ * generic/tclExecute.c (TclExecuteByteCode): restore support for
+ INST_CALL_BUILTIN_FUNC1 and INST_CALL_FUNC1 bytecodes to support 8.4-
+ precompiled sources (math functions). [Bug 1720895]
- * generic/tclStringObj.c: restored Tcl_SetObjLength() side-effect of
- always invalidating unicode rep (if the obj has a string rep). Added
- hasUnicode flag to String struct, allows decoupling of validity of
- unicode rep from buffer size allocated to it (improves memory
- allocation efficiency). [Bugs 686782, 671138, 635200]
+2007-06-10 Miguel Sofer <msofer@users.sf.net>
- * macosx/Tcl.pbproj/project.pbxproj:
- * macosx/Makefile: reworked embedded build to no longer require
- relinking but to use install_name_tool instead to change the
- install_names for embedded frameworks. [Bug 644510]
+ * generic/tclInt.h:
+ * generic/tclNamesp.c:
+ * generic/tclObj.c:
+ * generic/tclvar.c: new macros TclGetCurrentNamespace() and
+ TclGetGlobalNamespace(); Tcl_GetCommandFromObj and
+ TclGetNamespaceFromObj rewritten to make the logic clearer; slightly
+ faster too.
+
+2007-06-09 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c (INST_INVOKE): isolated two vars to the small
+ block where they are actually used.
+
+ * generic/tclObj.c (Tcl_GetCommandFromObj): rewritten to make the
+ logic clearer; slightly faster too.
+
+ * generic/tclBasic.c: Split TEOv in two, by separating a processor
+ for non-TCL_OK returns. Also split TEOvI in a full version that
+ handles non-existing and traced commands, and a separate shorter
+ version for the regular case.
+
+ * generic/tclBasic.c: Moved the generation of command strings for
+ * generic/tclTrace.c: traces: previously in Tcl_EvalObjv(), now in
+ TclCheck[Interp|Execution]Traces(). Also insured that the strings are
+ properly NUL terminated at the correct length. [Bug 1693986]
+
+ ***POTENTIAL INCOMPATIBILITY in internal API***
+ The functions TclCheckInterpTraces() and TclCheckExecutionTraces() (in
+ internal stubs) used to be noops if the command string was NULL, this
+ is not true anymore: if the command string is NULL, they generate an
+ appropriate string from (objc,objv) and use it to call the traces. The
+ caller might as well not call them with a NULL string if he was
+ expecting a noop.
+
+ * generic/tclBasic.c: Extend usage of TclLimitReady() and
+ * generic/tclExecute.c: (new) TclLimitExceeded() macros.
+ * generic/tclInt.h:
+ * generic/tclInterp.c:
- * macosx/Tcl.pbproj/project.pbxproj: preserve mod dates when running
- 'make install' to build framework (avoids bogus rebuilds of dependent
- frameworks because tcl headers appear changed).
+ * generic/tclInt.h: New TclCleanupCommandMacro for core usage.
+ * generic/tclBasic.c:
+ * generic/tclExecute.c:
+ * generic/tclObj.c:
- * tests/ioCmd.test (iocmd-1.8): fix failure when system encoding is
- utf-8: use iso8859-1 encoding explicitly.
+2007-06-09 Daniel Steffen <das@users.sourceforge.net>
-2003-02-18 Miguel Sofer <msofer@users.sf.net>
+ * macosx/Tcl.xcodeproj/project.pbxproj: add new Tclsh-Info.plist.in.
- * generic/tclCompile.c (TclCompileExprWords): remove unused variable
- "range" [Bug 664743]
- * generic/tclExecute.c (ExprSrandFunc): remove unused variable
- "result" [Bug 664743]
- * generic/tclStringObj.c (UpdateStringOfString): remove unused
- variable "length" [Bug 664751]
- * tests/execute.test (execute-7.30): fix for [Bug 664775]
+2007-06-08 Donal K. Fellows <dkf@users.sf.net>
-2003-02-18 Andreas Kupries <andreask@activestate.com>
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd): Changed [string first] and
+ * doc/string.n: [string last] so that they have clearer descriptions
+ for those people who know the adage about needles and haystacks. This
+ follows suggestions on comp.lang.tcl...
- * unix/tcl.m4: [Bug 651811] Added definition of _XOPEN_SOURCE and
- linkage of 'xnet' library to HP 11 branch. This kills a lot of
- socket-related failures in the testsuite when Tcl was compiled in 64
- bit mode (both PA-RISC 2.0W, and IA 64).
+2007-06-06 Miguel Sofer <msofer@users.sf.net>
- * unix/configure: Regenerated.
+ * generic/tclParse.c: fix for uninit read. [Bug 1732414]
-2003-02-18 Jeff Hobbs <jeffh@ActiveState.com>
+2007-06-06 Daniel Steffen <das@users.sourceforge.net>
- * generic/tclIO.c (HaveVersion): correctly decl static
+ * macosx/Tcl.xcodeproj/project.pbxproj: add settings for Fix&Continue.
- * unix/tclUnixThrd.c (TclpReaddir): reduce size of name string in
- tsd to NAME_MAX instead of PATH_MAX. [Bug 689100] (waters)
+ * unix/configure.in (Darwin): add plist for tclsh; link the
+ * unix/Makefile.in (Darwin): Tcl and tclsh plists into
+ * macosx/Tclsh-Info.plist.in (new): their binaries in all cases.
+ * macosx/Tcl-Common.xcconfig:
-2003-02-18 Mo DeJong <mdejong@users.sourceforge.net>
+ * unix/tcl.m4 (Darwin): fix CF checks in fat 32&64bit builds.
+ * unix/configure: autoconf-2.59
- * unix/configure: Regen.
- * unix/tcl.m4 (SC_ENABLE_THREADS): Make sure -lpthread gets passed on
- the link line when checking for the pthread_attr_setstacksize symbol.
+2007-06-05 Don Porter <dgp@users.sourceforge.net>
-2003-02-18 Vince Darley <vincentdarley@users.sourceforge.net>
+ * generic/tclBasic.c: Added interp flag value ERR_LEGACY_COPY to
+ * generic/tclInt.h: control the timing with which the global
+ * generic/tclNamesp.c: variables ::errorCode and ::errorInfo get
+ * generic/tclProc.c: updated after an error. This keeps more
+ * generic/tclResult.c: precise compatibility with Tcl 8.4.
+ * tests/result.test (result-6.2): [Bug 1649062]
- * generic/tclTest.c: cleanup of new 'simplefs' test code, and better
- documentation.
+2007-06-05 Miguel Sofer <msofer@users.sf.net>
-2003-02-17 Miguel Sofer <msofer@users.sf.net>
+ * generic/tclInt.h:
+ * generic/tclExecute.c: Tcl-stack reform, [Patch 1701202]
- * generic/tclBasic.c (TclRenameCommand): fixing error in previous
- commit.
+2007-06-03 Daniel Steffen <das@users.sourceforge.net>
-2003-02-17 Jeff Hobbs <jeffh@ActiveState.com>
+ * unix/Makefile.in: add datarootdir to silence autoconf-2.6x warning.
- * generic/tclExecute.c (TclExecuteByteCode INST_STR_MATCH):
- * generic/tclCmdMZ.c (Tcl_StringObjCmd STR_MATCH):
- * generic/tclUtf.c (TclUniCharMatch):
- * generic/tclInt.decls: add private TclUniCharMatch function that
- * generic/tclIntDecls.h: does string match on counted unicode
- * generic/tclStubInit.c: strings. Tcl_UniCharCaseMatch has the
- * tests/string.test: failing that it can't handle strings or
- * tests/stringComp.test: patterns with embedded NULLs. Added
- tests that actually try strings/pats with NULLs. TclUniCharMatch
- should be TIPed and made public in the next minor version rev.
+2007-05-30 Don Porter <dgp@users.sourceforge.net>
-2003-02-17 Miguel Sofer <msofer@users.sf.net>
+ * generic/tclBasic.c: Removed code that dealt with
+ * generic/tclCompile.c: TCL_TOKEN_EXPAND_WORD tokens representing
+ * generic/tclCompile.h: expanded literal words. These sections were
+ mostly in place to enable [info frame] to discover line information in
+ expanded literals. Since the parser now generates a token for each
+ post-expansion word referring to the right location in the original
+ script string, [info frame] gets all the data it needs.
- * generic/tclBasic.c (TclRenameCommand): 'oldFullName' object was not
- being freed on all function exits, causing a memory leak. [Bug 684756]
+ * generic/tclInt.h: Revised the parser so that it never produces
+ * generic/tclParse.c: TCL_TOKEN_EXPAND_WORD tokens when parsing an
+ * tests/parse.test: expanded literal word; that is, something like
+ {*}{x y z}. Instead, generate the series of TCL_TOKEN_SIMPLE_WORD
+ tokens to represent the words that expansion of the literal string
+ produces. [RFE 1725186]
-2003-02-17 Mo DeJong <mdejong@users.sourceforge.net>
+2007-05-29 Jeff Hobbs <jeffh@ActiveState.com>
- * generic/tclIO.c (Tcl_GetsObj): Minor change so that eol is only
- assigned at the top of the TCL_TRANSLATE_AUTO case block. The other
- cases assign eol so this does not change any functionality.
+ * unix/tclUnixThrd.c (Tcl_JoinThread): fix for 64-bit handling of
+ pthread_join exit return code storage. [Bug 1712723]
-2003-02-17 Kevin Kenny <kennykb@users.sourceforge.net>
+2007-05-22 Don Porter <dgp@users.sourceforge.net>
- * tests/notify.test: Removed Windows line terminators. [Bug 687913].
+ [core-stabilizer-branch]
-2003-02-15 Miguel Sofer <msofer@users.sf.net>
+ * unix/configure: autoconf-2.59 (FC6 fork)
+ * win/configure:
- * generic/tclBasic.c (Tcl_EvalEx):
- * generic/tclCompExpr.c (CompileSubExpr):
- * generic/tclCompile.c (TclCompileScript):
- * generic/tclParse.c (Tcl_ParseCommand, ParseTokens):
- * generic/tclParseExpr.c (ParsePrimaryExpr):
- * tests/basic.test (47.1):
- * tests/main.test (3.4):
- * tests/misc.test (1.2):
- * tests/parse.test (6.18):
- * tests/parseExpr.test (15.35):
- * tests/subst.test (8.6): Don Porter's fix for bad parsing of
- nested scripts [Bug 681841].
-
-2003-02-15 Kevin Kenny <kennykb@users.sourceforge.net>
-
- * tests/notify.test (new-file):
- * generic/tclTest.c (TclTest_Init, EventtestObjCmd, EventtestProc,
- (EventTestDeleteProc):
- * generic/tclNotify.c (Tcl_DeleteEvents): Fixed Tcl_DeleteEvents
- not to get a pointer smash when deleting the last event in the
- queue. Added test code in 'tcltest' and a new file of test cases
- 'notify.test' to exercise this functionality; several of the new
- test cases fail for the original code and pass for the corrected
- code. [Bug 673714]
-
- * unix/tclUnixTest.c (TestfilehandlerCmd): Corrected a couple
- of typos in error messages. [Bug 596027]
-
-2003-02-14 Jeff Hobbs <jeffh@ActiveState.com>
-
- * README: Bumped to version 8.4.2.
+ * README: Bump version number to 8.5b1
* generic/tcl.h:
+ * library/init.tcl:
* tools/tcl.wse.in:
- * unix/configure:
* unix/configure.in:
- * unix/tcl.m4:
* unix/tcl.spec:
- * win/README.binary:
- * win/configure:
* win/configure.in:
- * macosx/Tcl.pbproj/project.pbxproj:
-
- * generic/tclStringObj.c (Tcl_GetCharLength): perf tweak
-
- * unix/tcl.m4: correct HP-UX ia64 --enable-64bit build flags
-
-2003-02-14 Kevin Kenny <kennykb@users.sourceforge.net>
-
- * win/tclWinTime.c: Added code to test and compensate for forward
- leaps of the performance counter. See the MSDN Knowledge Base article
- Q274323 for the hardware problem that makes this necessary on certain
- machines.
- * tests/winTime.test: Revised winTime-2.1 - it had a tolerance of
- thousands of seconds, rather than milliseconds. (What's six orders of
- magnitude among friends?
-
- Both the above changes are triggered by a problem reported at
- http://aspn.activestate.com/ASPN/Mail/Message/ActiveTcl/1536811
- although the developers find it difficult to believe that it accounts
- for the observed behavior and suspect a fault in the RTC chip.
-
-2003-02-13 Kevin Kenny <kennykb@users.sourceforge.net>
-
- * win/tclWinInit.c: Added conversion from the system encoding to
- tcl_platform(user), so that it works with non-ASCII7 user names. [Bug
- 685926]
-
- * doc/tclsh.1: Added language to describe the handling of the
- end-of-file character \u001a embedded in a script file. [Bug 685485]
-
-2003-02-11 Vince Darley <vincentdarley@users.sourceforge.net>
-
- * tests/fileName.test:
- * unix/tclUnixFile.c: fix for [Bug 685445] when using 'glob -l' on
- broken symbolic links. Added two new tests for this bug.
-
-2003-02-11 Kevin Kenny <kennykb@users.sourceforge.net>
-
- * tests/http.test: Corrected a problem where http-4.14 would fail when
- run in an environment with a proxy server. Replaced references to
- scriptics.com by tcl.tk.
-
-2003-02-11 Jeff Hobbs <jeffh@ActiveState.com>
-
- * tests/lsearch.test:
- * generic/tclCmdIL.c (Tcl_LsearchObjCmd): protect against the case
- that lsearch -regepx list and pattern objects are equal.
-
- * tests/stringObj.test:
- * generic/tclStringObj.c (Tcl_GetCharLength): correct ascii char
- opt of 2002-11-11 to not stop early on \x00. [Bug 684699]
-
- * tests.parse.test: remove excess EOF whitespace
-
- * generic/tclParse.c (CommandComplete): more paranoid check to
- break on (p >= end) instead of just (p == end).
-
-2003-02-11 Miguel Sofer <msofer@users.sf.net>
-
- * generic/tclParse.c (CommandComplete):
- * tests/parse.test: fix for [Bug 684744], by Don Porter.
-
-2003-02-11 Jeff Hobbs <jeffh@ActiveState.com>
- * generic/tclIOUtil.c (Tcl_FSJoinPath, Tcl_FSGetNormalizedPath):
- (UpdateStringOfFsPath): revert the cwdLen == 0 check and instead
- follow a different code path in Tcl_FSJoinPath.
- (Tcl_FSConvertToPathType, Tcl_FSGetNormalizedPath):
- (Tcl_FSGetFileSystemForPath): Update string rep of path objects
- before freeing the internal object. (darley)
-
- * tests/fileSystem.test: added test 8.3
- * generic/tclIOUtil.c (Tcl_FSGetNormalizedPath):
- (UpdateStringOfFsPath): handle the cwdLen == 0 case
-
- * unix/tclUnixFile.c (TclpMatchInDirectory): simplify the hidden
- file match check.
-
-2003-02-10 Mo DeJong <mdejong@users.sourceforge.net>
+2007-05-18 Don Porter <dgp@users.sourceforge.net>
+ * unix/configure: autoconf-2.59 (FC6 fork)
* win/configure:
- * win/configure.in: Generate error when attempting to build under
- Cygwin. The Cygwin port of Tcl/Tk does not build and people are filing
- bug reports under the mistaken impression that someone is actually
- maintaining the Cygwin port. A post to comp.lang.tcl asking someone to
- volunteer as an area maintainer has generated no results. Closing
- [Bugs 680840, 630199, 634772] and marking as "Won't fix".
-
-2003-02-10 Donal K. Fellows <fellowsd@cs.man.ac.uk>
-
- * doc/append.n: Return value was not documented. [Bug 683188]
-
-2003-02-10 Vince Darley <vincentdarley@users.sourceforge.net>
-
- * doc/FileSystem.3:
- * generic/tclIOUtil.c:
- * generic/tclInt.h:
- * tests/fileSystem.test:
- * unix/tclUnixFCmd.c:
- * unix/tclUnixFile.c:
- * win/tclWinFile.c: further filesystem optimization, applying
- [Patch 682500]. In particular, these code examples are faster now:
- foreach f $flist { if {[file exists $f]} {file stat $f arr;...}}
- foreach f [glob -dir $dir *] { # action and/or recursion on $f }
- cd $dir
- foreach f [glob *] { # action and/or recursion on $f }
- cd ..
-
- * generic/tclTest.c: Fix for [Bug 683181] where test suite left files
- in 'tmp'.
-
-2003-02-08 Jeff Hobbs <jeffh@ActiveState.com>
-
- * library/safe.tcl: code cleanup of eval and string comp use.
-
-2003-02-07 Vince Darley <vincentdarley@users.sourceforge.net>
-
- * win/tclWinFCmd.c: cleanup long lines
- * win/tclWinFile.c: sped up pure 'glob' by a factor of 2.5 ('foreach f
- [glob *] { file exists $f }' is still slow)
- * tests/fileSystem.text:
- * tests/fileName.test: added new tests to ensure correct behaviour in
- optimized filesystem code.
-
-2003-02-07 Vince Darley <vincentdarley@users.sourceforge.net>
-
- * generic/tclTest.c:
- * tests/fileSystem.text: fixed test 7.2 to avoid a possible crash, and
- not change the pwd.
-
- * tests/http.text: added comment to test 4.15, that it may fail if you
- use a proxy server.
-2003-02-06 Mo DeJong <mdejong@users.sourceforge.net>
-
- * generic/tclCompCmds.c (TclCompileIncrCmd):
- * tests/incr.test: Don't include the text "(increment expression)" in
- the errorInfo generated by the compiled version of the incr command
- since it does not match the message generated by the non-compiled
- version of incr. It is also not possible to match this error output
- under Jacl, which does not support a compiler.
-
-2003-02-06 Mo DeJong <mdejong@users.sourceforge.net>
-
- * generic/tclExecute.c (TclExecuteByteCode): When an error is
- encountered reading the increment value during a compiled call to
- incr, add a "(reading increment)" error string to the errorInfo
- variable. This makes the errorInfo variable set by the compiled incr
- command match the value set by the non-compiled version.
- * tests/incr-old.test: Change errorInfo result for the compiled incr
- command case to match the modified implementation.
- * tests/incr.test: Add tests to make sure the compiled and
- non-compiled errorInfo messages are the same.
-
-2003-02-06 Don Porter <dgp@users.sourceforge.net>
-
- * library/tcltest/tcltest.tcl: Filename arguments to [outputChannel]
- and [errorChannel] (also -outfile and -errfile) were [open]ed but
- never [closed]. Also, [cleanupTests] could remove output or error
- files. [Bug 676978].
- * library/tcltest/pkgIndex.tcl: Bumped to version 2.2.2.
-
-2003-02-05 Mo DeJong <mdejong@users.sourceforge.net>
-
- * tests/interp.test:
- * tests/set-old.test: Run test cases that depend on hash order through
- lsort so that the tests also pass under Jacl. Does not change test
- results under Tcl.
+ * README: Bump version number to 8.5a7
+ * generic/tcl.h:
+ * library/init.tcl:
+ * tools/tcl.wse.in:
+ * unix/configure.in:
+ * unix/tcl.spec:
+ * win/configure.in:
-2003-02-04 Vince Darley <vincentdarley@users.sourceforge.net>
+ * generic/tclParse.c: Disable and remove the ALLOW_EXPAND sections
+ * tests/info.test: that continued to support the deprecated
+ * tests/mathop.test: {expand} syntax. Updated the few remaining
+ users of that syntax in the test suite.
- * generic/tclIOUtil.c:
- * generic/tclEvent.c:
- * generic/tclInt.h:
- * mac/tclMacFCmd.c:
- * unix/tclUnixFCmd.c:
- * win/tclWin32Dll.c:
- * win/tclWinFCmd.c:
- * win/tclWinInit.c:
- * win/tclWinInt.h:
- * tests/fileSystem.test: fix to finalization/unloading/encoding issues
- to make filesystem much less dependent on encodings for its cleanup,
- and therefore allow it to be finalized later in the exit process. This
- fixes fileSystem.test-7.1. Also fixed one more bug in setting of
- modification dates of files which have undergone cross-platform
- copies. [Patch 676271]
-
- * tests/basic.test:
- * tests/exec.test:
- * tests/fileName.test:
- * tests/io.test: fixed some test failures when tests are run from a
- directory containing spaces.
+2007-05-17 Donal K. Fellows <dkf@users.sf.net>
- * tests/fileSystem.test:
- * generic/tclTest.c: added regression test for the modification
- date setting of cross-platform file copies.
+ * generic/tclExecute.c (TclLimitReady): Created a macro version of
+ Tcl_LimitReady just for TEBC, to reduce the amount of times that the
+ bytecode engine calls out to external functions on the critical path.
+ * generic/tclInterp.c (Tcl_LimitReady): Added note to remind anyone
+ doing maintenance that there is a macro version to update.
-2003-02-03 Kevin Kenny <kennykb@users.sourceforge.net>
+2007-05-17 Daniel Steffen <das@users.sourceforge.net>
- * generic/tclBasic.c: Changed [trace add command] so that 'rename'
- callbacks get fully qualified names of the command. [Bug 651271].
- ***POTENTIAL INCOMPATIBILITY***
- * tests/trace.test: Modified the test cases for [trace add command] to
- expect fully qualified names on the 'rename' callbacks. Added a case
- for renaming a proc within a namespace.
- * doc/trace.n: Added language about use of fully qualified names in
- trace callbacks.
-
-2003-02-01 Kevin Kenny <kennykb@users.sourceforge.net>
-
- * generic/tclCompCmds.c: Removed an unused variable that caused
- compiler warnings on SGI. [Bug 664379]
+ * generic/tcl.decls: workaround 'make checkstubs' failures from
+ tclStubLib.c MODULE_SCOPE revert. [Bug 1716117]
- * generic/tclLoad.c: Changed the code so that if Tcl_StaticPackage is
- called to report the same package as being loaded in two interps, it
- shows up in [info loaded {}] in both of them (previously, it didn't
- appear in the static package list in the second.
-
- * tests/load.test Added regression test for the above bug. [Bug
- 670042]
-
- * generic/tclClock.c: Fixed a bug that incorrectly allowed [clock
- clicks {}] and [clock clicks -] to be accepted as if they were [clock
- clicks -milliseconds].
-
- * tests/clock.test: Added regression tests for the above bug. [Bug
- 675356]
-
- * tests/unixNotfy.test: Added cleanup of working files [Bug 675609]
-
- * doc/Tcl.n: Added headings to the eleven paragraphs, to improve
- formatting in the tools that attempt to extract tables of contents
- from the manual pages. [Bug 627455]
-
- * generic/tclClock.c: Expanded mutex protection around the setting of
- env(TZ) and the thread-unsafe call to tzset(). [Bug 656660]
-
-2003-01-31 Don Porter <dgp@users.sourceforge.net>
-
- * tests/tcltest.test: Cleaned up management of file/directory
- creation/deletion to improve "-debug 1" output. [Bug 675614] The
- utility [slave] command failed to properly [list]-quote a constructed
- [open] command, causing failure when the pathname contained
- whitespace. [Bug 678415]
-
- * tests/main.test: Stopped main.test from deleting existing file.
- Test suite should not delete files that already exist. [Bug 675660]
-
-2003-01-28 Don Porter <dgp@users.sourceforge.net>
-
- * tests/main.test: Constrain tests that do not work on Windows. [Bug
- 674387]
-
-2003-01-28 Vince Darley <vincentdarley@users.sourceforge.net>
-
- * generic/tclIOUtil.c: fix to setting modification date in
- TclCrossFilesystemCopy. Also added 'panic' in
- Tcl_FSGetFileSystemForPath under illegal calling circumstances which
- lead to hard-to-track-down bugs.
-
- * generic/tclTest.c: added test suite code to allow exercising a
- vfs-crash-on-exit bug in Tcl's finalization caused by the encodings
- being cleaned up before unloading occurs.
- * tests/fileSystem.test: added new 'knownBug' test 7.1 to demonstrate
- the crash on exit.
-
-2003-01-28 Mo DeJong <mdejong@users.sourceforge.net>
-
- * generic/tcl.h: Add TCL_PREFIX_IDENT and TCL_DEBUG_IDENT, used only
- by TclpCreateProcess.
- * unix/Makefile.in: Define TCL_DBGX.
- * win/Makefile.in: Define TCL_DBGX.
- * win/tclWinPipe.c (TclpCreateProcess): Check that the Tcl pipe dll
- actually exists in the Tcl bin directory and panic if it is not
- found. Incorporate TCL_DBGX into the Tcl pipe dll name. This fixes a
- really mysterious error that would show up when exec'ing a 16 bit
- application under Win95 or Win98 when Tcl was compiled with symbols.
- The error seemed to indicate that the executable could not be found,
- but it was actually the Tcl pipe dll that could not be found.
-
-2003-01-26 Mo DeJong <mdejong@users.sourceforge.net>
-
- * win/README: Update msys+mingw URL to release 6. This version bundles
- gcc 3.
-
-2003-01-26 Mo DeJong <mdejong@users.sourceforge.net>
-
- * win/configure: Regen.
- * win/configure.in: Add test that checks to see if the compiler can
- cast to a union type.
- * win/tclWinTime.c: Squelch compiler warning about union initializer
- by casting to union type when compiling with gcc.
-
-2003-01-25 Mo DeJong <mdejong@users.sourceforge.net>
-
- * generic/tclIO.c (Tcl_CutChannel, Tcl_SpliceChannel): Invoke
- TclpCutFileChannel and TclpSpliceFileChannel.
- * generic/tclInt.h: Declare TclpCutFileChannel and
- TclpSpliceFileChannel.
- * unix/tclUnixChan.c (FileCloseProc, TclpOpenFileChannel,
- (Tcl_MakeFileChannel, TclpCutFileChannel,
- (TclpSpliceFileChannel): Implement thread load data cut and splice for
- file channels. This avoids an invalid memory ref when compiled with
- -DDEPRECATED.
- * win/tclWinChan.c (FileCloseProc, TclpCutFileChannel,
- (TclpSpliceFileChannel): Implement thread load data cut and splice for
- file channels. This avoids an invalid memory ref that was showing up
- in the thread extension.
+2007-05-16 Joe English <jenglish@users.sourceforge.net>
-2003-01-25 Mo DeJong <mdejong@users.sourceforge.net>
-
- * win/tclWin32Dll.c (TclpCheckStackSpace, squelch_warnings):
- * win/tclWinChan.c (Tcl_MakeFileChannel, squelch_warnings):
- * win/tclWinFCmd.c (DoRenameFile, DoCopyFile, squelch_warnings):
- Re-implement inline ASM SEH handlers for gcc. The esp and ebp
- registers are now saved on the stack instead of in global variables so
- that the code is thread safe. Add additional checks when TCL_MEM_DEBUG
- is defined to be sure the values were recovered from the stack
- properly. Remove squelch_warnings functions and add a dummy call in
- the handler methods to squelch compiler warnings.
+ * generic/tclStubLib.c: Change Tcl_InitStubs(), tclStubsPtr, and the
+ auxilliary stubs table pointers back to public visibility.
-2003-01-25 Mo DeJong <mdejong@users.sourceforge.net>
+ These symbols need to be exported so that stub-enabled extensions may
+ be statically linked into an extended tclsh or Big Wish with a
+ dynamically-linked libtcl. [Bug 1716117]
- * win/configure:
- * win/configure.in: Define HAVE_ALLOCA_GCC_INLINE when we detect that
- no alloca function is found in malloc.h and we are compiling with
- GCC. Remove HAVE_NO_ALLOC_DECL define.
- * win/tclWin32Dll.c (TclpCheckStackSpace): Don't define alloca as a
- cdecl function. Doing this caused a tricky runtime bug because the
- _alloca function expects the size argument to be passed in a register
- and not on the stack. To fix this problem, we use inline ASM when
- compiling with gcc to invoke _alloca with the size argument loaded
- into a register.
+2007-05-15 Don Porter <dgp@users.sourceforge.net>
-2003-01-24 Jeff Hobbs <jeffh@ActiveState.com>
+ * win/configure: autoconf-2.59 (FC6 fork)
- * win/tclWinDde.c (Dde_Init): clarified use of tsdPtr.
- (DdeServerProc): better refcount handling of returnPackagePtr.
+ * library/reg/pkgIndex.tcl: Bump to registry 1.2.1 to account for
+ * win/configure.in: [Bug 1682211] fix.
+ * win/makefile.bc:
+ * win/tclWinReg.c:
- * generic/tclEvent.c (Tcl_Finalize): revert finalize change on
- 2002-12-04 to correct the issue with extensions that have TSD needing
- to finalize that before they are unloaded. This issue needs further
- clarification.
+2007-05-11 Pat Thoyts <patthoyts@users.sourceforge.net>
- * tests/unixFCmd.test: only do groups check on unix
+ * generic/tclInt.h: Removed TclEvalObjEx and TclGetSrcInfoForPc from
+ tclInt.h now they are in the internal stubs table.
-2003-01-24 Vince Darley <vincentdarley@users.sourceforge.net>
+2007-05-09 Don Porter <dgp@users.sourceforge.net>
- * generic/tclStringObj.c: proper fixes for Tcl_SetObjLength and
- Tcl_AttemptSetObjectLength dealing with string objects with both
- pure-unicode and normal internal representations. Previous fix didn't
- handle all cases correctly.
- * generic/tclIO.c: Add 'Tcl_GetString()' to ensure the object has a
- valid 'objPtr->bytes' field before manipulating it directly.
+ * generic/tclInt.h: TclFinalizeThreadAlloc() is always defined, so
+ make sure it is also always declared (with MODULE_SCOPE).
- This fixes [Bug 635200] and [Bug 671138], but may reduce performance
- of Unicode string handling in some cases. A further patch will be
- applied to address this, once the code is known to be correct.
+2007-05-09 Daniel Steffen <das@users.sourceforge.net>
-2003-01-24 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tclInt.h: fix warning when building threaded with -DPURIFY.
- * win/configure: Regen.
- * win/configure.in: Add test to see if alloca is undefined in
- malloc.h.
- * win/tclWin32Dll.c (TclpCheckStackSpace): Rework the SEH exception
- handler logic to avoid using the stack since alloca will modify the
- stack. This was causing a nasty bug that would set the exception
- handler to 0 because it tried to pop the previous exception handler
- off the top of the stack.
+ * macosx/Tcl.xcodeproj/project.pbxproj: add 'DebugUnthreaded' &
+ * macosx/Tcl.xcodeproj/default.pbxuser: 'DebugLeaks' configs and env
+ var settings needed to run the 'leaks' tool.
-2003-01-23 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2007-05-07 Don Porter <dgp@users.sourceforge.net>
- * doc/lset.n: Fixed fault in return values from lset in documentation
- examples [Bug 658463] and tidied up a bit at the same time.
+ [Tcl Bug 1706140]
-2003-01-21 Joe English <jenglish@users.sourceforge.net>
- * doc/namespace.n (namespace inscope): Clarified documentation
- [Patch 670110]
+ * generic/tclLink.c (LinkTraceProc): Update Tcl_VarTraceProcs so
+ * generic/tclNamesp.c (Error*Read): they call Tcl_InterpDeleted()
+ * generic/tclTrace.c (Trace*Proc): for themselves, and do not
+ * generic/tclUtil.c (TclPrecTraceProc): rely on (frequently buggy)
+ setting of the TCL_INTERP_DESTROYED flag by the trace core.
-2003-01-21 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tclVar.c: Update callers of TclCallVarTraces to not pass
+ in the TCL_INTERP_DESTROYED flag. Also apply filters so that public
+ routines only pass documented flag values down to lower level routines
- * win/configure: Regen.
- * win/tcl.m4 (SC_CONFIG_CFLAGS): Set SHLIB_SUFFIX so that
- TCL_SHLIB_SUFFIX will be set to a useful value in the generated
- tclConfig.sh. Set SHLIB_LD_LIBS to "" or '${LIBS}' based on the
- --enable-shared flag. This matches the UNIX implementation.
+ * generic/tclTrace.c (TclCallVarTraces): The setting of the
+ TCL_INTERP_DESTROYED flag is now done entirely within the
+ TclCallVarTraces routine, the only place it can be done right.
-2003-01-18 Jeff Hobbs <jeffh@ActiveState.com>
+2007-05-06 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclCkalloc.c: change %ud to %u as appropriate.
+ * generic/tclInt.h (ExtraFrameInfo): Create a new mechanism for
+ * generic/tclCmdIL.c (InfoFrameCmd): conveying what information needs
+ to be added to the results of [info frame] to replace the hack that
+ was there before.
+ * generic/tclProc.c (Tcl_ApplyObjCmd): Use the new mechanism for the
+ [apply] command, the only part of Tcl itself that needs it (so far).
-2003-01-17 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tclInt.decls (TclEvalObjEx, TclGetSrcInfoForPc): Expose
+ these two functions through the internal stubs table, necessary for
+ extensions that need to integrate deeply with TIP#280.
- * win/tclWinDde.c (DdeServerProc): Deallocate the Tcl_Obj returned by
- ExecuteRemoteObject if it was not saved in a connection object.
+2007-05-05 Donal K. Fellows <dkf@users.sf.net>
-2003-01-17 Mo DeJong <mdejong@users.sourceforge.net>
+ * win/tclWinFile.c (TclpGetUserHome): Squelch type-pun warnings in
+ * win/tclWinInit.c (TclpSetVariables): Win-specific code not found
+ * win/tclWinReg.c (AppendSystemError): during earlier work on Unix.
- * generic/tcl.h: Revert earlier change that defined TCL_WIDE_INT_TYPE
- as long long and TCL_LL_MODIFIER as L when compiling with mingw. This
- change ended up causing some test case failures when compiling with
- mingw.
- * generic/tclObj.c (UpdateStringOfWideInt): Describe the warning
- generated by mingw and why it needs to be ignored so that someone is
- not tempted to "fix" this problem again in the future.
+2007-05-04 Kevin B. Kenny <kennykb@acm.org>
-2003-01-16 Vince Darley <vincentdarley@users.sourceforge.net>
+ * generic/tclIO.c (TclFinalizeIOSubsystem): Added an initializer to
+ silence a spurious gcc warning about use of an uninitialized
+ variable.
+ * tests/encoding.test: Modified so that encoding tests happen in a
+ private namespace, to avoid polluting the global one. This problem was
+ discovered when running the test suite '-singleproc 1 -skip exec.test'
+ because the 'path' variable in encoding.test conflicted with the one
+ in io.test.
+ * tests/io.test: Made more of the working variables private to the
+ namespace.
+
+2007-05-02 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclTest.c (SimpleMatchInDirectory): Corrected a refcount
+ imbalance that affected the filesystem-[147]* tests in the test suite.
+ Thanks to Don Porter for the patch. [Bug 1710707]
+ * generic/tclPathObj.c (Tcl_FSJoinPath, Tcl_FSGetNormalizedPath):
+ Corrected several memory leaks that caused refcount imbalances
+ resulting in memory leaks on Windows. Thanks to Joe Mistachkin for the
+ patch.
+
+2007-05-01 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclVar.c (TclPtrSetVar): fixed leak whenever newvaluePtr had
+ refCount 0 and was used for appending (but not lappending). Thanks to
+ mistachkin and kbk. [Bug 1710710]
+
+2007-05-01 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclIO.c (DeleteChannelTable): Made changes so that
+ DeleteChannelTable tries to close all open channels, not just the
+ first. [Bug 1710285]
+ * generic/tclThread.c (TclFinalizeSynchronization): Make sure that TSD
+ blocks get freed on non-threaded builds. [Bug 1710825]
+ * tests/utf.test (utf-25.1--utf-25.4): Modified tests to clean up
+ after the 'testobj' extension to avoid spurious reports of memory
+ leaks.
+
+2007-05-01 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCmdMZ.c (STR_MAP): When [string map] has a pure dict map,
+ a missing Tcl_DictObjDone() call led to a memleak. [Bug 1710709]
- * generic/tclStringObj.c: Tcl_SetObjLength fix for when the object has
- a unicode string rep. Fixes [Bug 635200]
- * tests/stringObj.test: removed 'knownBug' constraint from test 14.1
- now that this bug is fixed.
+2007-04-30 Daniel Steffen <das@users.sourceforge.net>
- * generic/tclInt.h:
- * generic/tclBasic.c:
- * generic/tclCmdMZ.z:
- * tests/trace.test: execution and command tracing bug fixes and
- cleanup. In particular fixed [Bugs 655645, 615043, 571385]
- - fixed some subtle cleanup problems with tracing. This required
- replacing Tcl_Preserve/Tcl_Release with a more robust refCount
- approach. Solves at least one known crash caused by memory
- corruption.
- - fixed some confusion in the code between new style traces (Tcl
- 8.4) and the very limited 'Tcl_CreateTrace' which existed before.
- - made behaviour consistent with documentation (several tests even
- contradicted the documentation before).
- - fixed some minor error message details
- - added a number of new tests
-
-2003-01-16 Jeff Hobbs <jeffh@ActiveState.com>
-
- * win/tclWinSerial.c (SerialOutputProc): add casts for bytesWritten to
- allow strict compilation (no warnings).
-
- * tests/winDde.test:
- * win/tclWinDde.c (Tcl_DdeObjCmd): Prevent crash when empty service
- name is passed to 'dde eval' and goto errorNoResult in request and
- poke error cases to free up any allocated data.
-
-2003-01-16 Mo DeJong <mdejong@users.sourceforge.net>
-
- * win/tclWin32Dll.c (squelch_warnings): Squelch compiler warnings from
- SEH ASM code.
- * win/tclWinChan.c (squelch_warnings): Squelch compiler warnings from
- SEH ASM code.
- * win/tclWinDde.c: Add casts to avoid compiler warnings. Pass pointer
- to DWORD instead of int to avoid compiler warnings.
- * win/tclWinFCmd.c (squelch_warnings): Add casts and fixup decls to
- avoid compiler warnings. Squelch compiler warnings from SEH ASM code.
- * win/tclWinFile.c: Add casts and fixup decls to avoid compiler
- warnings. Remove unused variable.
- * win/tclWinNotify.c: Declare as DWORD instead of int to avoid
- compiler warning.
- * win/tclWinReg.c: Add casts to avoid compiler warning. Fix assignment
- in if expression bug.
- * win/tclWinSerial.c: Add casts to avoid compiler warnings. Remove
- unused variable.
- * win/tclWinSock.c: Add casts and fixup decls to avoid compiler
- warnings.
-
-2003-01-14 Jeff Hobbs <jeffh@ActiveState.com>
-
- * generic/tclClock.c (FormatClock): corrected typo that incorrectly
- conditionally defined savedTZEnv and savedTimeZone.
-
-2003-01-13 Mo DeJong <mdejong@users.sourceforge.net>
-
- Fix mingw build problems and compiler warnings.
-
- * generic/tcl.h: Add if defined(__MINGW32__) check to code that sets
- the TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER.
- * generic/tclClock.c (FormatClock): Don't define savedTimeZone and
- savedTZEnv if we are not going to use them.
- * generic/tclEnv.c: Add cast to avoid warning.
- * win/tclWinChan.c: Use DWORD instead of int to avoid compiler warning
- * win/tclWinThrd.c: Only define allocLock, allocLockPtr, and dataKey
- when TCL_THREADS is defined. This avoid a compiler warning about
- unused variables.
-
-2003-01-12 Mo DeJong <mdejong@users.sourceforge.net>
-
- * win/README: Update msys + mingw URL, the new release includes the
- released 1.0.8 version of msys which includes a number of bug fixes.
-
-2003-01-12 Mo DeJong <mdejong@users.sourceforge.net>
-
- * win/configure: Regen.
- * win/tcl.m4 (SC_CONFIG_CFLAGS): Pull in addition of shell32.lib to
- LIBS_GUI that was added to the Tk tcl.m4 but never made it back into
- the Tcl version.
-
-2003-01-12 Mo DeJong <mdejong@users.sourceforge.net>
-
- * generic/tcl.h: Skip Tcl's define of CHAR, SHORT, and LONG when
- HAVE_WINNT_IGNORE_VOID is defined. This avoids a bunch of compiler
- warnings when building with Cygwin or Mingw.
- * win/configure: Regen.
- * win/configure.in: Define HAVE_WINNT_IGNORE_VOID when we detect a
- winnt.h that still defines CHAR, SHORT, and LONG when VOID has already
- been defined.
- * win/tcl.m4 (SC_LOAD_TCLCONFIG): Subst the TCL_DEFS loaded from
- tclConfig.sh so that Tcl defines can make it into the Tk Makefile.
-
-2003-01-12 Mo DeJong <mdejong@users.sourceforge.net>
-
- * win/configure: Regen.
- * win/configure.in: Check for typedefs like LPFN_ACCEPT in winsock2.h
- and define HAVE_NO_LPFN_DECLS if not found.
- * win/tclWinSock.c: Define LPFN_* typedefs if HAVE_NO_LPFN_DECLS is
- defined. This fixes the build under Mingw and Cygwin, it was broken by
- the changes made on 2002-11-26.
-
-2003-01-10 Vince Darley <vincentdarley@users.sourceforge.net>
+ * unix/Makefile.in: add 'tclsh' dependency to install targets that
+ rely on tclsh, fixes parallel 'make install' from empty build dir.
- * 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
- filesystem.
+2007-04-30 Andreas Kupries <andreask@gactivestate.com>
- * win/makefile.vc: fix to minor VC++ 5.2 syntax problem
+ * generic/tclIO.c (FixLevelCode): Corrected reference count
+ mismanagement of newlevel, newcode. Changed to allocate the Tcl_Obj's
+ as late as possible, and only when actually needed. [Bug 1705778, leak
+ K29]
-2003-01-09 Don Porter <dgp@users.sourceforge.net>
+2007-04-30 Kevin B. Kenny <kennykb@acm.org>
- * generic/tclCompCmds.c (TclCompilerReturnCmd): Corrected off-by-one
- problem with recent commit. [Bug 633204]
+ * generic/tclProc.c (Tcl_ProcObjCmd, SetLambdaFromAny): Corrected
+ reference count mismanagement on the name of the source file in the
+ TIP 280 code. [Bug 1705778, leak K02 among other manifestations]
-2003-01-09 Vince Darley <vincentdarley@users.sourceforge.net>
+2007-04-25 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclFileName.c: remove unused variable 'macSpecialCase' [Bug
- 664749]
+ *** 8.5a6 TAGGED FOR RELEASE ***
- * generic/tclIOUtil.c:
- * generic/tclInt.h:
- * unix/tclUnixFile.c:
- * mac/tclMacFile.c:
- * win/tclWinFile.c:
- * win/tclWinInt.h:
- * win/tclWin32Dll.c:
- * tests/cmdAH.test: fix to non-ascii chars in paths when setting mtime
- and atime through 'file (a|m)time $path $time'. [Bug 634151]
+ * generic/tclProc.c (TclObjInterpProcCore): Only allocate objects for
+ error message generation when associated with argument names that are
+ really used. [Bug 1705778, leak K15]
-2003-01-08 Don Porter <dgp@users.sourceforge.net>
+2007-04-25 Kevin B. Kenny <kennykb@acm.org>
- * generic/tclExecute.c (TclExprFloatError): Use the IS_NAN macro for
- greater clarity of code.
+ * generic/tclIOUtil.c (Tcl_FSChdir): Changed the memory management so
+ that the path returned from Tcl_FSGetNativePath is not duplicated
+ before being stored as the current directory, to avoid a memory leak.
+ [Bug 1705778, leak K01 among other manifestations]
-2003-01-07 Don Porter <dgp@users.sourceforge.net>
+2007-04-25 Don Porter <dgp@users.sourceforge.net>
- * generic/tclCompCmds.c (TclCompileReturnCmd):
- * tests/compile.test: Corrects failure of bytecompiled [catch
- {return}] to have result TCL_RETURN (not TCL_OK) [Bug 633204]. This
- patch is a workaround for 8.4.X. A new opcode INST_RETURN is a better
- long term solution for 8.5 and later.
+ * generic/tclCompExpr.c (ParseExpr): Revised to be sure that an
+ error return doesn't prevent all literals getting placed on the
+ litList to be returned to the caller for freeing. Corrects some
+ memleaks. [Bug 1705778, leak K23]
-2003-01-04 David Gravereaux <davygrvy@pobox.com>
+2007-04-25 Daniel Steffen <das@users.sourceforge.net>
- * win/makefile.vc:
- * win/rules.vc: Fixed INSTALLDIR macro problem that blanked itself by
- accident causing the install target to put the tree at the root of the
- drive built on. Whoops..
+ * unix/Makefile.in (dist): add macosx/*.xcconfig files to src dist;
+ copy license.terms to dist macosx dir; fix autoheader bits.
- Renamed the 'linkexten' option to be 'staticpkg'. Added 'thrdalloc' to
- allow the switching _on_ of the thread allocator. Under testing, I
- found it not to be benificial under windows for the purpose of the
- application I was using it for. It was more important for this app
- that resources for tcl threads be returned to the system rather than
- saved/moved to the global recycler. Be extra clean or extra fast for
- the default threaded build? Let's move to clean and allow it to be
- switched on for users who find it benificial for their use of threads.
+2007-04-24 Miguel Sofer <msofer@users.sf.net>
-2002-12-18 David Gravereaux <davygrvy@pobox.com>
+ * generic/tclListObj.c: reverting [Patch 738900] (committed on
+ 2007-04-20). Causes some Tk test breakage of unknown importance, but
+ the impact of the patch itself is likely to be so small that it does
+ not warrant investigation at this time.
- * win/makefile.vc: some uses of xcopy swapped to the @$(CPY) macro.
- Reported by Joe Mistachkin <joe@mistachkin.com>.
+2007-04-24 Donal K. Fellows <dkf@users.sf.net>
-2002-12-17 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclDictObj.c (DictKeysCmd): Rewrote so that the lock on the
+ internal representation of a dict is only set when necessary. [Bug
+ 1705778, leak K04]
+ (DictFilterCmd): Added code to drop the lock in the trivial match
+ case. [Bug 1705778, leak K05]
- * generic/tclNotify.c (TclFinalizeNotifier, Tcl_SetServiceMode):
- (Tcl_ThreadAlert): Check that the stub functions are non-NULL before
- calling them. They could be set to NULL by Tcl_SetNotifier.
+2007-04-24 Kevin B. Kenny <kennykb@acm.org>
-2002-12-16 David Gravereaux <davygrvy@pobox.com>
+ * generic/tclBinary.c: Addressed several code paths where the error
+ return from the 'binary format' command leaked the result buffer.
+ * generic/tclListObj.c (TclLsetFlat): Fixed a bug where the new list
+ under construction was leaked in the error case. [Bug 1705778, leaks
+ K13 and K14]
- * generic/tclPipe.c (TclCleanupChildren):
- * tests/winPipe.test:
- * win/tclWinPipe.c (Tcl_WaitPid):
- * win/tclWinTest.c: Gave Tcl_WaitPid the ability to return a Win32
- exception code translated into a posix style SIG*. This allows [close]
- to report "CHILDKILLED" without the meaning getting lost in a
- truncated exit code. In TclCleanupChildren(), TclpGetPid() had to get
- moved to before Tcl_WaitPid() as the the handle is removed from the
- list taking away the ability to get the process id after the wait is
- done. This shouldn't effect the unix implimentaion unless waitpid is
- called with a pid of zero, meaning "any". I don't think it is..
+2007-04-24 Jeff Hobbs <jeffh@ActiveState.com>
-2002-12-13 Don Porter <dgp@users.sourceforge.net>
+ * unix/Makefile.in (dist): add platform library package to src dist
- * unix/configure.in: Updated configure of CVS snapshots to reflect
- * win/configure.in: the 8.4.1.1 patchlevel.
+2007-04-24 Don Porter <dgp@users.sourceforge.net>
- * unix/configure: autoconf
- * win/configure autoconf
+ * generic/tclCompExpr.c (ParseExpr): Memory leak in error case; the
+ literal Tcl_Obj was not getting freed. [Bug 1705778, leak #1 (new)]
-2002-12-11 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclNamesp.c (Tcl_DeleteNamespace): Corrected flaw in the
+ flag marking scheme to be sure that global namespaces are freed when
+ their interp is deleted. [Bug 1705778]
- * generic/tclProc.c (ProcessProcResultCode): Fix failure to propagate
- negative return codes up the call stack. [Bug 647307]
- * tests/proc.test (proc-6.1): Test for Bug 647307
+2007-04-24 Kevin B. Kenny <kennykb@acm.org>
- * generic/tclParseExpr.c (TclParseInteger): Return 1 for the
- string "0x" (recognize leading "0" as an integer). [Bug 648441].
- * tests/parseExpr.test (parseExpr-19.1): Test for Bug 648441.
+ * generic/tclExecute.c (TclExecuteByteCode): Plugged six memory leaks
+ in bignum arithmetic.
+ * generic/tclIOCmd.c (Tcl_ReadObjCmd): Plugged a leak of the buffer
+ object if the physical read returned an error and the bypass area had
+ no message.
+ * generic/tclIORChan.c (TclChanCreateObjCmd): Plugged a leak of the
+ return value from the "initialize" method of a channel handler.
+ (All of the above under [Bug 1705778])
-2002-12-09 Jeff Hobbs <jeffh@ActiveState.com>
+2007-04-23 Daniel Steffen <das@users.sourceforge.net>
- * win/tclWinThrd.c (TclpMasterUnlock):
- * generic/tclThread.c (TclFinalizeThreadData): TclpMasterUnlock must
- exist and be called unconditional of TCL_THREADS. [Bug 651139]
+ * generic/tclCkalloc.c: fix warnings from gcc build configured with
+ * generic/tclCompile.c: --enable-64bit --enable-symbols=all.
+ * generic/tclExecute.c:
-2002-12-08 David Gravereaux <davygrvy@pobox.com>
+ * unix/tclUnixFCmd.c: add workaround for crashing bug in fts_open()
+ * unix/tclUnixInit.c: without FTS_NOSTAT on 64bit Darwin 8 or earlier.
- * win/tclWinSock.c (SocketThreadExitHandler, InitSockets): Check that
- the tsdPtr is valid before dereferencing as we call it from the exit
- handler, too [Bug 650353]. Another WSAStartup() loaded version
- comparison byte swap issue fixed. Although 0x0101 byte swapped is
- still 0x0101, properly claiming which is major/minor is more correct.
+ * unix/tclLoadDyld.c (TclpLoadMemory): fix (void*) arithmetic.
-2002-12-06 Jeff Hobbs <jeffh@ActiveState.com>
+ * macosx/Tcl-Common.xcconfig: enable more warnings.
- * generic/tclStubInit.c: regen
- * generic/tclIntPlatDecls.h: regen
- * generic/tclInt.decls: added TclWinResetInterface
+ * macosx/Tcl.xcodeproj/project.pbxproj: add 'DebugMemCompile' build
+ configuration that calls configure with --enable-symbols=all; override
+ configure check for __attribute__((__visibility__("hidden"))) in Debug
+ configuration to restore availability of ZeroLink.
- * win/tclWin32Dll.c (TclWinResetInterfaces):
- * win/tclWinInit.c (TclpSetInitialEncodings, WinEncodingsCleanup):
- add exit handler that resets the encoding information to a state where
- we can reuse Tcl. Following these changes, it is possible to reuse Tcl
- (following Tcl_FindExecutable or Tcl_CreateInterp) following a
- Tcl_Finalize.
+ * macosx/tclMacOSXNotify.c: fix warnings.
- * generic/tclIOUtil.c (TclFinalizeFilesystem): reset statics to their
- original values on finalize to allow reuse of the library.
+ * macosx/tclMacOSXFCmd.c: const fixes.
-2002-12-04 David Gravereaux <davygrvy@pobox.com>
+ * macosx/Tcl-Common.xcconfig: fix whitespace.
+ * macosx/Tcl-Debug.xcconfig:
+ * macosx/Tcl-Release.xcconfig:
+ * macosx/README:
- * win/tclWinPipe.c: reverted back to -r1.27 due to numerous test
- failures that need to be resolved first. The idea was good, but the
- details aren't.
+ * macosx/GNUmakefile: fix/add copyright and license refs.
+ * macosx/tclMacOSXBundle.c:
+ * macosx/Tcl-Info.plist.in:
+ * macosx/Tcl.xcode/project.pbxproj:
+ * macosx/Tcl.xcodeproj/project.pbxproj:
-2002-12-04 David Gravereaux <davygrvy@pobox.com>
+ * unix/configure.in: install license.terms into Tcl.framework.
+ * unix/configure: autoconf-2.59
- * win/tclWinPipe.c (Tcl_WaitPid): When a process exits with an
- exception, pass this notice on to the caller with a SIG* code rather
- than truncating the exit code and missing the meaning. This allows
- TclCleanupChildren() to report "CHILDKILLED".
+2007-04-23 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclVar.c (UnsetVarStruct): Make sure the
+ TCL_INTERP_DESTROYED flags gets passed to unset trace routines so they
+ can respond appropriately. [Bug 1705778, leak #9]
+
+2007-04-23 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompile.c (TclFreeCompileEnv): Tip 280's new field
+ extCmdMapPtr was not being freed. [Bug 1705778, leak #1]
+
+2007-04-23 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclCompCmds.c (TclCompileUpvarCmd): Plugged a memory leak in
+ 'upvar' when compiling (a) upvar outside a proc, (b) upvar with a
+ syntax error, or (c) upvar where the frame index is not known at
+ compile time.
+ * generic/tclCompExpr.c (ParseExpr): Plugged a memory leak when
+ parsing expressions that contain syntax errors.
+ * generic/tclEnv.c (ReplaceString): Clear memory correctly when
+ growing the cache to avoid reads of uninitialised data.
+ * generic/tclIORChan.c (TclChanCreateObjCmd, FreeReflectedChannel):
+ Plugged two memory leaks.
+ * generic/tclStrToD.c (AccumulateDecimalDigit): Fixed a mistake where
+ we'd run beyond the end of the 'pow10_wide' array if a number begins
+ with a string of more than 'maxpow10_wide' zeroes.
+ * generic/tclTest.c (Testregexpobjcmd): Removed an invalid access
+ beyond the end of 'objv' in 'testregexp -about'.
+ All of these issues reported under [Bug 1705778] - detected with the
+ existing test suite, no new regression tests required.
+
+2007-04-22 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclVar.c (TclDeleteNamespaceVars): fixed access to freed
+ memory detected by valgrind: Tcl_GetCurrentNamespace was being
+ called after freeing root CallFrame (on interp deletion).
+
+2007-04-20 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclListObj.c (SetListFromAny): avoid discarding internal
+ reps of objects converted to singleton lists. [Patch 738900]
+
+2007-04-20 Kevin B. Kenny <kennykb@acm.org>
+
+ * doc/clock.n: Corrected a silly error (transposed 'uppercase' and
+ 'lowercase' in clock.n. [Bug 1656002]
+ Clarified that [clock scan] does not recognize a locale's alternative
+ calendar.
+ Deleted an entirely superfluous (and also incorrect) remark about the
+ effect of Daylight Saving Time on relative times in [clock scan]. [Bug
+ 1582951]
+ * library/clock.tcl: Corrected an error in skipping over the %Ey field
+ on input.
+ * library/msgs/ja.msg:
+ * tools/loadICU.tcl: Corrected several localisation faults in the
+ Japanese locale (most notably, incorrect dates for the Emperors'
+ eras). [Bug 1637471]. Many thanks to SourceForge user 'nyademo' for
+ pointing this out and developing a fix.
+ * generic/tclPathObj.c: Corrected a 'const'ness fault that caused
+ bitter complaints from MSVC.
+ * tests/clock.test (clock-40.1, clock-58.1, clock-59.1): Corrected a
+ test case that depended on ":localtime" being able to handle dates
+ prior to the Posix epoch. [Bug 1618445] Added a test case for the
+ dates of the Japanese emperors. [Bug 1637471] Added a regression test
+ for military time zone input conversion. [Bug 1586828]
+ * generic/tclGetDate.y (MilitaryTable): Fixed an ancient bug where the
+ military NZA time zones had the signs reversed. [Bug 1586828]
+ * generic/tclDate.c: Regenerated.
+ * doc/Notifier.3: Documented Tcl_SetNotifier and Tcl_ServiceModeHook.
+ Quite against my better judgment. [Bug 414933]
+ * generic/tclBasic.c, generic/tclCkalloc.c, generic/tclClock.c:
+ * generic/tclCmdIL.c, generic/tclCmdMZ.c, generic/tclFCmd.c:
+ * generic/tclFileName.c, generic/tclInterp.c, generic/tclIO.c:
+ * generic/tclIOUtil.c, generic/tclNamesp.c, generic/tclObj.c:
+ * generic/tclPathObj.c, generic/tclPipe.c, generic/tclPkg.c:
+ * generic/tclResult.c, generic/tclTest.c, generic/tclTestObj.c:
+ * generic/tclVar.c, unix/tclUnixChan.c, unix/tclUnixTest.c:
+ * win/tclWinLoad.c, win/tclWinSerial.c: Replaced commas in varargs
+ with string concatenation where possible. [Patch 1515234]
+ * library/tzdata/America/Tegucigalpa:
+ * library/tzdata/Asia/Damascus: Olson's tzdata 2007e.
+
+2007-04-19 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * generic/regcomp.c, generic/regc_cvec.c, generic/regc_lex.c,
+ * generic/regc_locale.c: Improve the const-correctness of the RE
+ compiler.
- This has a different behavior than unix in that closing the read pipe
- to a process sends the SIGPIPE signal which is returned as a SIGPIPE
- exit status. On windows, we send the process a CTRL_BREAK_EVENT and
- get back a CONTROL_C_EXIT which is documented to mean a SIGINT which
- seems wrong as a system, but is the correct exit status.
+2007-04-18 Miguel Sofer <msofer@users.sf.net>
-2002-12-04 Vince Darley <vincentdarley@users.sourceforge.net>
+ * generic/tclExecute.c (INST_LSHIFT): fixed a mistake introduced in
+ version 1.266 ('=' became '=='), which effectively turned the block
+ that handles native shifts into dead code. This explains why the
+ testsuite did not pick this mistake. Rewrote to make the intention
+ clear.
- * generic/tclIOUtil.c: fix to redirected 'load' in virtual filesystem
- for some Unix systems.
+ * generic/tclInt.h (TclDecrRefCount): change the order of the
+ branches, use empty 'if ; else' to handle use in unbraced outer
+ if/else conditions (as already done in tcl.h)
- * generic/tclEvent.c: the filesystem must be cleaned up before the
- encoding subsystem because it needs access to encodings. Fixes crash
- on exit observed in embedded applications.
+ * generic/tclExecute.c: slight changes in Tcl_Obj management.
- * generic/tclTestObj.c: patch omitted from previous change of
- 2002-11-13
+2007-04-17 Kevin B. Kenny <kennykb@acm.org>
-2002-12-03 Jeff Hobbs <jeffh@ActiveState.com>
+ * library/clock.tcl: Fixed the naming of
+ ::tcl::clock::ReadZoneinfoFile because (yoicks!) it was in the global
+ namespace.
+ * doc/clock.n: Clarified the cases in which legacy time zone is
+ recognized. [Bug 1656002]
- * generic/tclStubLib.c (Tcl_InitStubs): prevent the cached check of
- tclStubsPtr to allow for repeated load/unload of the Tcl dll by
- hosting apps. [Bug 615304]
+2007-04-17 Miguel Sofer <msofer@users.sf.net>
-2002-12-03 David Gravereaux <davygrvy@pobox.com>
+ * generic/tclExecute.c: fixed checkInterp logic [Bug 1702212]
- * win/tclAppInit.c (sigHandler): Protect from trying to close a NULL
- handle.
+2007-04-16 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * win/tclWinPipe.c (PipeClose2Proc, TclpCreateProcess): Send a real
- Win32 signal (CTRL_C_EVENT) when the read channel is brought down to
- alert the child to close on its side. Start the process with
- CREATE_NEW_PROCESS_GROUP to allow the ability to send these signals.
- The following test case now brings down the child without the use of
- an external [kill] command.
+ * various (including generic/tclTest.c): Complete the purge of K&R
+ function definitions from manually-written code.
- % set p [open "|[info name]" w+]
- file8d5380
- % pid $p
- 2876
- % close $p <- now doesn't block in Tcl_WaitPid()
- %
+2007-04-15 Kevin B. Kenny <kennykb@acm.org>
- * win/tclWinPipe.c (PipeClose2Proc): Changed CTRL_C_EVENT to
- CTRL_BREAK_EVENT as it can't be ignored by the child and proved to
- work on [open "|netstat 1" w+] where CTRL_C_EVENT didn't.
+ * generic/tclCompCmds.c: added a cast to silence a compiler error on
+ VC2005.
+ * library/clock.tcl: Restored unique-prefix matching of keywords on
+ the [clock] command. [Bug 1690041]
+ * tests/clock.test: Added rudimentary test cases for unique-prefix
+ matching of keywords.
-2002-11-27 David Gravereaux <davygrvy@pobox.com>
+2007-04-14 Miguel Sofer <msofer@users.sf.net>
- * win/tclWinPort.h: Don't turn off winsock prototypes! TclX didn't
- like it. Even though the core doesn't use the prototypes, do offer
- them.
+ * generic/tclExecute.c: removed some code at INST_EXPAND_SKTOP that
+ duplicates functionality already present at checkForCatch.
- * win/tclWinSock.c: Removed shutdown() from the function table as it
- wasn't referenced anywhere and cleaned-up some casting that that
- wasn't needed.
+2007-04-12 Miguel Sofer <msofer@users.sf.net>
- * win/tclWinSock.c: WSAStartup() loaded version comparison error which
- resulted in 2.0 looking less than 1.1.
+ * generic/tclExecute.c: new macros OBJ_AT_TOS, OBJ_UNDER_TOS,
+ OBJ_AT_DEPTH(n) and CURR_DEPTH that remove all direct references to
+ tosPtr from TEBC (after initialisation and the code at the label
+ cleanupV_pushObjResultPtr).
- * win/tclWinChan.c (Tcl_MakeFileChannel): return of DuplicateHandle()
- incorrectly used [Bug 618852].
+2007-04-11 Miguel Sofer <msofer@users.sf.net>
-2002-11-26 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclCompCmds.c: moved all exceptDepth management to the
+ macros - the decreasing half was managed by hand.
- * generic/tclEncoding.c (TclFinalizeEncodingSubsystem): properly
- cleanup all encodings by using Tcl_FirstHashEntry in the while loop.
+2007-04-10 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * unix/Makefile.in (valgrind): add simple valgrind target
+ * generic/tclInt.h (TclNewLiteralStringObj): New macro to make
+ allocating literal string objects (i.e. objects whose value is a
+ constant string) easier and more efficient, by allowing the omission
+ of the length argument. Based on [Patch 1529526] (afredd)
+ * generic/*.c: Make use of this (in many files).
- * tests/exec.test: unset path var to allow singleproc testing
+2007-04-08 Miguel Sofer <msofer@users.sf.net>
- * generic/tclInterp.c (AliasCreate): preserve/release interps to
- prevent possible FMR error in bad alias cases.
+ * generic/tclCompile (tclInstructionTable): Fixed bugs in description
+ of dict instructions.
-2002-11-26 David Gravereaux <davygrvy@pobox.com>
+2007-04-07 Miguel Sofer <msofer@users.sf.net>
- * win/tclWinPort.h:
- * win/tclWinSock.c: This patch does two things:
+ * generic/tclCompile (tclInstructionTable): Fixed bug in description
+ of INST_START_COMMAND.
- 1) Cleans-up the winsock typedefs by using the typedefs provided by
- winsock2.h. This has no effect on how winsock is initialized; just
- makes the source code easier to read. [Patch 561305, 561301]
+ * generic/tclExecute.c (TEBC): Small code reduction.
- 2) Revamps how the socket message handler thread is brought up and
- down to allow for cleaner exits without the use of TerminateThread().
- TerminateThread is evil. No attempt has been made to resolve [Bug
- 593810] which may need a new channel driver version for adding a
- registering function within the transfered thread to init the handler
- thread. IOW, initialization of the TSD structure is getting bypassed
- through the thread extension's [thread::transfer] command.
+2007-04-06 Miguel Sofer <msofer@users.sf.net>
-2002-11-26 David Gravereaux <davygrvy@pobox.com>
+ * generic/tclExecute.c (TEBC):
+ * generic/tclNamespace.c (NsEnsembleImplementationCmd):
+ * generic/tclProc.c (InitCompiledLocals, ObjInterpProcEx)
+ (TclObjInterpProcCore, ProcCompileProc): Code reordering to reduce
+ branching and improve branch prediction (assume that forward branches
+ are typically not taken).
- * win/tclWinConsole.c:
- * win/tclWinPipe.c:
- * win/tclWinSerial.c:
- * win/tclWinSock.c:
- * win/tclWinThrd.c:
- * win/tclWinTime.c: General cleanup of all worker threads used by the
- channel drivers. Eliminates the normal case where the worker thread is
- terminated ('cept the winsock one). Instead, use kernel events to
- signal a clean exit. Only when the worker thread is blocked on an I/O
- call is the thread terminated. Essentially, this makes all other
- channel worker threads behave like the PipeReaderThread() function for
- it's cleaner exit behavior. This appears to fix [Bug 597924] but needs
- 3rd party confirmation to close the issue.
+2007-04-03 Miguel Sofer <msofer@users.sf.net>
-2002-11-26 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tclExecute.c: INST_INVOKE optimisation. [Patch 1693802]
- * win/README: Update msys build env URL. This release #4 build both
- tcl and tk without problems.
+2007-04-03 Don Porter <dgp@users.sourceforge.net>
-2002-11-22 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclNamesp.c: Revised ErrorCodeRead and ErrorInfoRead trace
+ routines so they guarantee the ::errorCode and ::errorInfo variable
+ always appear to exist. [Bug 1693252]
- * library/init.tcl: code cleanup to reduce use of
- * library/opt/optparse.tcl: string compare
+2007-04-03 Miguel Sofer <msofer@users.sf.net>
- * tests/interp.test: interp-14.4
- * generic/tclInterp.c (TclPreventAliasLoop): prevent seg fault when
- creating an alias command over the interp name. [Bug 641195]
+ * generic/tclInt.decls: Moved TclGetNamespaceFromObj() to the
+ * generic/tclInt.h: internal stubs table; regen.
+ * generic/tclIntDecls.h:
+ * generic/tclStubInit.c:
-2002-11-18 Jeff Hobbs <jeffh@ActiveState.com>
+2007-04-02 Miguel Sofer <msofer@users.sf.net>
- * generic/tclUtil.c (SetEndOffsetFromAny): handle integer offset
- after the "end-" prefix.
+ * generic/tclBasic.c: Added bytecode compilers for the variable
+ * generic/tclCompCmds.c: linking commands: 'global', 'variable',
+ * generic/tclCompile.h: 'upvar', 'namespace upvar' [Patch 1688593]
+ * generic/tclExecute.c:
+ * generic/tclInt.h:
+ * generic/tclVar.c:
- * generic/get.test:
- * generic/string.test:
- * generic/tclObj.c (SetIntFromAny, SetWideIntFromAny):
- * generic/tclGet.c (TclGetLong, Tcl_GetInt): simplify sign handling
- before calling strtoul(l). [Bug 634856]
+2007-04-02 Don Porter <dgp@users.sourceforge.net>
-2002-11-18 David Gravereaux <davygrvy@pobox.com>
+ * generic/tclBasic.c: Replace arrays on the C stack and ckalloc
+ * generic/tclExecute.c: calls with TclStackAlloc calls to use memory
+ * generic/tclFCmd.c: on Tcl's evaluation stack.
+ * generic/tclFileName.c:
+ * generic/tclIOCmd.c:
+ * generic/tclIndexObj.c:
+ * generic/tclInterp.c:
+ * generic/tclNamesp.c:
+ * generic/tclTrace.c:
+ * unix/tclUnixPipe.c:
- * win/tclWinThrd.c (Tcl_CreateThread/TclpThreadExit): Fixed improper
- compiler macros that missed the VC++ compiler. This resulted in VC++
- builds using CreateThread()/ExitThread() in place of the proper
- _beginthreadex()/_endthreadex(). This was a large error and am
- surprised I missed seeing it earlier.
+2007-04-01 Donal K. Fellows <dkf@users.sf.net>
-2002-11-13 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclCompile.c (TclCompileScript, TclPrintInstruction):
+ * generic/tclExecute.c (TclExecuteByteCode): Changed the definition of
+ INST_START_CMD so that it knows how many commands start at the current
+ location. This makes the interpreter command counter correct without
+ requiring a large number of instructions to be issued. (See my change
+ from 2007-01-19 for what triggered this.)
- * generic/regexpComp.test: added tests 22.*
- * generic/tclCompCmds.c (TclCompileRegexpCmd): add left and right
- anchoring (^ and $) recognition and check starting or ending .* to
- extend the number of REs that can be compiled to string match or
- string equal.
+2007-03-30 Don Porter <dgp@users.sourceforge.net>
-2002-11-13 Vince Darley <vincentdarley@users.sourceforge.net>
+ * generic/tclCompile.c:
+ * generic/tclCompExpr.c:
+ * generic/tclCompCmds.c: Replace arrays on the C stack and
+ ckalloc calls with TclStackAlloc calls to use memory on Tcl's
+ evaluation stack.
- * generic/tclCmdMZ.c:
- * tests/trace.test: applied patch from Hemang Levana to fix [Bug
- 615043] in execution traces with 'return -code error'.
+ * generic/tclCmdMZ.c: Revised [string to* $s $first $last]
+ implementation to reduce number of allocs/copies.
- * generic/tclTestObj.c:
- * tests/stringObj.test: added 'knownBug' test for [Bug 635200]
- * generic/tclStringObj.c: corrected typos in comments
+ * tests/string.test: More [string reverse] tests.
- * generic/tclFileName.c:
- * tests/fileName.test: applied patch for bug reported against tclvfs
- concerning handling of Windows serial ports like 'com1', 'lpt3' by the
- virtual filesystem code.
+2007-03-30 Miguel Sofer <msofer@users.sf.net>
- * doc/RegExp.3: clarification of the 'extendMatch' return values.
+ * generic/tclExecute.c: optimise the lookup of elements of indexed
+ arrays.
-2002-11-11 Jeff Hobbs <jeffh@ActiveState.com>
+2007-03-29 Miguel Sofer <msofer@users.sf.net>
- * generic/tclUtil.c (Tcl_Backslash): use TclUtfToUniChar.
- (Tcl_StringCaseMatch): use TclUtfToUniChar and add further
- optimizations for the one-byte/char case.
+ * generic/tclProc.c (Tcl_ApplyObjCmd):
+ * tests/apply.test (9.3): Fixed Tcl_Obj leak on error return; an
+ unneeded ref to lambdaPtr was being set and not released on an error
+ return path.
- * generic/tclUtf.c: make use of TclUtfToUniChar macro throughout the
- functions, and add extra optimization to Tcl_NumUtfChars for
- one-byte/char case.
+2007-03-28 Don Porter <dgp@users.sourceforge.net>
- * generic/tclVar.c (DisposeTraceResult, CallVarTraces): add proper
- static declarations.
+ * generic/tclCmdMZ.c (STR_REVERSE): Implement the actual [string
+ reverse] command in terms of the new TclStringObjReverse() routine.
- * generic/tclStringObj.c (Tcl_GetCharLength): optimize for the ascii
- char case.
- (Tcl_GetUniChar): remove unnecessary use of Tcl_UtfToUniChar.
- (FillUnicodeRep): Use TclUtfToUniChar.
+ * generic/tclInt.h (TclStringObjReverse): New internal routine
+ * generic/tclStringObj.c (TclStringObjReverse): that implements the
+ [string reverse] operation, making use of knowledge/surgery of the
+ String intrep to minimize the number of allocs and copies needed to do
+ the job.
- * generic/tclHash.c (HashStringKey): move string++ lower to save an
- instruction.
+2007-03-27 Don Porter <dgp@users.sourceforge.net>
- * generic/tclExecute.c (TclExecuteByteCode): improve INST_STR_CMP to
- use memcmp in the one-byte/char case, also use direct index for
- INST_STR_INDEX in that case.
+ * generic/tclCmdMZ.c (STR_MAP): Replace ckalloc calls with
+ TclStackAlloc calls.
- * generic/tclEncoding.c (UtfToUtfProc, UtfToUnicodeProc):
- (TableFromUtfProc, EscapeFromUtfProc): Use TclUtfToUniChar.
- (UnicodeToUtfProc, TableToUtfProc): add 1-byte char optimizations
- for Tcl_UniCharToUtf call. These improve encoded channel conversion
- speeds by up to 20%.
+2007-03-24 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
- * tests/split.test: added 1-char string split tests
- * generic/tclCmdMZ.c (Tcl_SplitObjCmd): Use TclUtfToUniChar. Also
- added a special case for single-ascii-char splits.
- (Tcl_StringObjCmd): Use TclUtfToUniChar. For STR_RANGE, support
- getting ranges of ByteArrays (reverts change from 2000-05-26).
- (TraceExecutionProc) add proper static declaration.
+ * win/tclWinThrd.c: Thread exit handler marks the current thread as
+ un-initialized. This allows exit handlers that are registered later to
+ re-initialize this subsystem in case they need to use some sync
+ primitives (cond variables) from this file again.
- * generic/tclInt.h: add macro version of Tcl_UtfToUniChar
- (TclUtfToUniChar) that does the one-byte utf-char check without
- calling Tcl_UtfToUniChar, for use by the core. This brings notable
- speedups for primarily ascii string handling.
+2007-03-23 Miguel Sofer <msofer@users.sf.net>
- * generic/tcl.h (TCL_PATCH_LEVEL): bump to 8.4.1.1 for patchlevel
- only. This interim number will only be reflected by [info patchlevel]
+ * generic/tclBasic.c (DeleteInterpProc): pop the root frame pointer
+ before deleting the global namespace [Bug 1658572]
-2002-11-11 Kevin Kenny <kennykb@acm.org>
+2007-03-23 Kevin B. Kenny <kennykb@acm.org>
- * doc/Tcl.n: Corrected indentation of the new language. Oops.
+ * win/Makefile.in: Added code to keep a Cygwin path name from leaking
+ into LIBRARY_DIR when doing 'make test' or 'make runtest'.
-2002-11-10 Kevin Kenny <kennykb@acm.org>
+2007-03-22 Don Porter <dgp@users.sourceforge.net>
- * doc/Tcl.n: Added language to the Endekalogue to make it clear that
- substitutions always take place from left to right. [Bug 635644]
+ * generic/tclCmdAH.c (Tcl_ForeachObjCmd): Replaced arrays on the
+ C stack and ckalloc calls with TclStackAlloc calls to use memory on
+ Tcl's evaluation stack.
-2002-11-06 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tclExecute.c: Revised GrowEvaluationStack to take an
+ argument specifying the growth required by the caller, so that a
+ single reallocation / copy is the most that will ever be needed even
+ when required growth is large.
- * changes: Note TclInExit TclInThreadExit changes.
- * generic/tclEvent.c (TclInExit, TclInThreadExit):
- Split out functionality of TclInExit to make it clear which one should
- be called in each situation.
- * generic/tclInt.decls: Declare TclInThreadExit.
- * generic/tclIntDecls.h: Regen.
- * generic/tclStubInit.c: Regen.
- * mac/tclMacChan.c (StdIOClose):
- * unix/tclUnixChan.c (FileCloseProc):
- * win/tclWinChan.c (FileCloseProc):
- * win/tclWinConsole.c (ConsoleCloseProc):
- * win/tclWinPipe.c (TclpCloseFile):
- * win/tclWinSerial.c (SerialCloseProc): Invoke the new TclInThreadExit
- method instead of TclInExit.
+2007-03-21 Don Porter <dgp@users.sourceforge.net>
-2002-11-06 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tclExecute.c: More ckalloc -> ckrealloc conversions.
+ * generic/tclLiteral.c:
+ * generic/tclNamesp.c:
+ * generic/tclParse.c:
+ * generic/tclPreserve.c:
+ * generic/tclStringObj.c:
+ * generic/tclUtil.c:
- * unix/configure: Regen.
- * unix/tcl.m4 (SC_CONFIG_CFLAGS): Generate a fatal configure error if
- no ar program can be found on the path. [Bug 582039]
- * win/configure: Regen.
- * win/configure.in: Check that AR, RANLIB, and RC are found on the
- path when building with gcc.
+2007-03-20 Don Porter <dgp@users.sourceforge.net>
-2002-11-03 David Gravereaux <davygrvy@pobox.com>
+ * generic/tclEnv.c: Some more ckalloc -> ckrealloc replacements.
+ * generic/tclLink.c:
- * win/tclAppInit.c: Calls Registry_Init() and Dde_Init() when
- STATIC_BUILD and TCL_USE_STATIC_PACKAGES macros are set.
+2007-03-20 Kevin B. Kenny <kennykb@acm.org>
- * win/makefile.vc:
- * win/rules.vc: linkexten option now sets the TCL_USE_STATIC_PACKAGES
- macro which also adds the registry and dde object files to the link
- of the shell. [Patch 479697] Also factored some additional macros
- that will be helpful for extension authors. Version grepping of tcl.h
- will need to be added to complete this.
+ * generic/tclDate.c: Rebuilt, despite Donal Fellows's comment when
+ committing it that no rebuild was required.
+ * generic/tclGetDate.y: According to Donal Fellows, "Introduce modern
+ formatting standards; no need for rebuild of tclDate.c."
- * win/buildall.vc.bat: Added more descriptive commentary.
+ * library/tzdata/America/Cambridge_Bay:
+ * library/tzdata/America/Havana:
+ * library/tzdata/America/Inuvik:
+ * library/tzdata/America/Iqaluit:
+ * library/tzdata/America/Pangnirtung:
+ * library/tzdata/America/Rankin_Inlet:
+ * library/tzdata/America/Resolute:
+ * library/tzdata/America/Yellowknife:
+ * library/tzdata/Asia/Choibalsan:
+ * library/tzdata/Asia/Dili:
+ * library/tzdata/Asia/Hovd:
+ * library/tzdata/Asia/Jakarta:
+ * library/tzdata/Asia/Jayapura:
+ * library/tzdata/Asia/Makassar:
+ * library/tzdata/Asia/Pontianak:
+ * library/tzdata/Asia/Ulaanbaatar:
+ * library/tzdata/Europe/Istanbul: Upgraded to Olson's tzdata2007d.
-2002-11-01 David Gravereaux <davygrvy@pobox.com>
+ * generic/tclListObj.c (TclLsetList, TclLsetFlat):
+ * tests/lset.test: Changes to deal with shared internal representation
+ for lists passed to the [lset] command. Thanks to Don Porter for
+ fixing this issue. [Bug 1677512]
- * win/tclWinReg.c: Changed the Tcl_PkgProvide() line to declare the
- registry extension at version 1.1 from 1.0.
+2007-03-19 Don Porter <dgp@users.sourceforge.net>
-2002-10-31 Andreas Kupries <andreask@activestate.com>
+ * generic/tclCompile.c: Revise the various expansion routines for
+ CompileEnv fields to use ckrealloc() where appropriate.
- * library/word.tcl: Changed $tcl_platform to $::tcl_platform to avoid
- possible scope trouble.
+ * generic/tclBinary.c (Tcl_SetByteArrayLength): Replaced ckalloc() /
+ memcpy() sequence with ckrealloc() call.
-2002-10-29 Vince Darley <vincentdarley@users.sourceforge.net>
+ * generic/tclBasic.c (Tcl_CreateMathFunc): Replaced some calls to
+ * generic/tclEvent.c (Tcl_CreateThread): Tcl_Alloc() with calls
+ * generic/tclObj.c (UpdateStringOfBignum): to ckalloc(), which
+ * unix/tclUnixTime.c (SetTZIfNecessary): better supports memory
+ * win/tclAppInit.c (setargv): debugging.
- * win/tclWinInt.h:
- * win/tclWin32Dll.c: added comments about certain NULL function
- pointers which will be filled in when Tcl_FindExecutable is called, so
- that users don't report invalid bugs on this topic. (No code changes
- at all).
+2007-03-19 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
-2002-10-29 Daniel Steffen <das@users.sourceforge.net>
+ * doc/regsub.n: Corrected example so that it doesn't recommend
+ potentially unsafe practice. Many thanks to Konstantin Kushnir
+ <chpock@gmail.com> for reporting this.
- * unix/tclLoadDyld.c (TclpFindSymbol): pass all dyld error messages
- upstream [Bug 627546].
+2007-03-17 Kevin B. Kenny <kennykb@acm.org>
-2002-10-28 Andreas Kupries <andreask@activestate.com>
+ * win/tclWinReg.c (GetKeyNames): Size the buffer for enumerating key
+ names correctly, so that Unicode names exceeding 127 chars can be
+ retrieved without crashing. [Bug 1682211]
+ * tests/registry.test (registry-4.9): Added test case for the above
+ bug.
- * library/dde/pkgIndex.tcl:
- * library/reg/pkgIndex.tcl: Changed the hardwired debug suffix (d) to
- the correct suffix (g).
+2007-03-15 Mo DeJong <mdejong@users.sourceforge.net>
-2002-10-28 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclIOUtil.c (Tcl_Stat): Reimplement workaround to avoid gcc
+ warning by using local variables. When the macro argument is of type
+ long long instead of long, the incorrect warning is not generated.
- * library/auto.tcl: Converted the Mac-specific [package unknown]
- * library/init.tcl: behavior to use a chaining mechanism to extend
- * library/package.tcl: the default [tclPkgUnknown]. [Bug 627660]
- * library/tclIndex: [Patch 624509] (steffen)
+2007-03-15 Mo DeJong <mdejong@users.sourceforge.net>
-2002-10-26 David Gravereaux <davygrvy@pobox.com>
+ * win/Makefile.in: Fully qualify LIBRARY_DIR so that `make test` does
+ not depend on working dir.
- * win/makefile.vc: xcopy on NT 4.0 doesn't support the /Y switch
- (overwrite). Added logic to handle this. [Bug 618019]
+2007-03-15 Mo DeJong <mdejong@users.sourceforge.net>
-2002-10-23 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * tests/parse.test: Add two backslash newline parse tests.
- * generic/tclInt.h: Removed definitions of obsolete HistoryEvent and
- HistoryRev structures (the history mechanism has been written in Tcl
- for some time now).
+2007-03-12 Don Porter <dgp@users.sourceforge.net>
-2002-10-22 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclExecute.c (INST_FOREACH_STEP4): Make private copy of
+ * tests/foreach.test (foreach-10.1): value list to be assigned to
+ variables so that shimmering of that list doesn't lead to invalid
+ pointers. [Bug 1671087]
- *** 8.4.1 TAGGED FOR RELEASE ***
+ * generic/tclEvent.c (HandleBgErrors): Make efficient private copy
+ * tests/event.test (event-5.3): of the command prefix for the interp's
+ background error handling command to avoid panics due to pointers to
+ memory invalid after shimmering. [Bug 1670155]
- * changes: updated for 8.4.1 release
+ * generic/tclNamesp.c (NsEnsembleImplementationCmd): Make efficient
+ * tests/namespace.test (namespace-42.8): private copy of the
+ command prefix as we invoke the command appropriate to a particular
+ subcommand of a particular ensemble to avoid panic due to shimmering
+ of the List intrep. [Bug 1670091]
- * win/Makefile.in: removed @MEM_DEBUG_FLAGS@ subst.
- * win/configure: regen
- * win/configure.in: removed SC_ENABLE_MEMDEBUG call
- * win/tcl.m4: replaced SC_ENABLE_MEMDEBUG with a more intelligent
- SC_ENABLE_SYMBOLS that takes yes|no|mem|compile|all as options now.
+ * generic/tclVar.c (TclArraySet): Make efficient private copy of
+ * tests/var.test (var-17.1): the "list" argument to [array set] to
+ avoid crash due to shimmering invalidating pointers. [Bug 1669489]
-2002-10-22 Daniel Steffen <das@users.sourceforge.net>
+2007-03-12 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * library/auto.tcl (tcl_findLibrary):
- * library/package.tcl (tclPkgUnknown): on macosx, search inside the
- Resources/Scripts subdirectory of any potential package directory
- * macosx/Tcl.pbproj/project.pbxproj: add standard Frameworks dirs to
- TCL_PACKAGE_PATH make argument.
- * unix/tclUnixInit.c (TclpSetVariables): on macosx, add embedded
- framework dirs to tcl_pkgPath: @executable_path/../Frameworks and
- @executable_path/../PrivateFrameworks (if they exist), as well as the
- dirs in DYLD_FRAMEWORK_PATH (if set). [Patch 624509] use standard
- MAXPATHLEN instead of literal 1024
+ * generic/tclCmdIL.c (Tcl_LsortObjCmd): Fix problems with declaration
+ positioning and memory leaks. [Bug 1679072]
-2002-10-22 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2007-03-11 Donal K. Fellows <dkf@users.sf.net>
- * doc/StringObj.3, doc/Object.3: Documented that Tcl_Obj's
- standard string form is a modified UTF-8; apparently, this was not
- mentioned anywhere in the main docs, and lead to [Bug 624919].
+ * generic/tclCmdIL.c (Tcl_LreverseObjCmd): Ensure that a list is
+ correctly reversed even if its internal representation is shared
+ without the object itself being shared. [Bug 1675044]
-2002-10-21 Daniel Steffen <das@users.sourceforge.net>
+2007-03-10 Miguel Sofer <msofer@users.sf.net>
- * macosx/Tcl.pbproj/project.pbxproj: bumped version to 8.4.1
- * generic/tcl.h: Added reminder comment to edit
- macosx/Tcl.pbproj/project.pbxproj when version number changes.
+ * generic/tclCmdIL (Tcl_LsortObjCmd): changed fix to [Bug 1675116] to
+ use the cheaper TclListObjCopy() instead of Tcl_DuplicateObj().
-2002-10-18 Jeff Hobbs <jeffh@ActiveState.com>
+2007-03-09 Andreas Kupries <andreask@activestate.com>
- * library/reg/pkgIndex.tcl:
- * win/configure:
- * win/configure.in:
- * win/Makefile.in:
- * win/makefile.vc:
- * win/makefile.bc: Updated to reg1.1
+ * library/platform/shell.tcl: Made more robust if an older platform
+ * library/platform/pkgIndex.tcl: package is present in the inspected
+ * unix/Makefile.in: shell. Package forget it to prevent errors. Bumped
+ * win/Makefile.in: package version to 1.1.3, and updated the Makefiles
+ installing it as Tcl Module.
- * doc/registry.n: Added support for broadcasting changes to the
- * tests/registry.test: registry Environment. Noted proper code in ths
- * win/tclWinReg.c: docs. [Patch 625453]
+2007-03-09 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * unix/Makefile.in (dist): add any mac/tcl*.sea.hqx files
+ * generic/tclCmdIL.c (Tcl_LsortObjCmd): Handle tricky case with loss
+ * tests/cmdIL.test (cmdIL-1.29): of list rep during sorting due
+ to shimmering. [Bug 1675116]
-2002-10-17 Don Porter <dgp@users.sourceforge.net>
+2007-03-09 Kevin B. Kenny <kennykb@acm.org>
- * generic/tclVar.c: Fixed code that check for proper # of args to
- * tests/var.test: [array names]. Added test. [Bug 624755]
+ * library/clock.tcl (ReadZoneinfoFile): Added Y2038 compliance to the
+ code for version-2 'zoneinfo' files.
+ * tests/clock.test (clock-56.3): Added a test case for Y2038 and
+ 'zoneinfo'. Modified test initialisation to use the
+ 'loadTestedCommands' function of tcltest to bring in the correct path
+ for the registry library.
-2002-10-16 Jeff Hobbs <jeffh@ActiveState.com>
+2007-03-08 Don Porter <dgp@users.sourceforge.net>
- * win/configure: add workaround for cygwin windres
- * win/tcl.m4 (SC_CONFIG_CFLAGS): problem. [Patch 624010] (howell)
+ * generic/tclListObj.c (TclLsetList): Rewrite so that the routine
+ itself does not do any direct intrep surgery. Better isolates those
+ things into the implementation of the "list" Tcl_ObjType.
-2002-10-15 Jeff Hobbs <jeffh@ActiveState.com>
+2007-03-08 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * README: added archives.tcl.tk note
+ * generic/tclListObj.c (TclLindexList, TclLindexFlat): Moved these
+ functions to tclListObj.c from tclCmdIL.c to mirror the way that the
+ equivalent functions for [lset]'s guts are arranged.
- * unix/configure:
- * unix/tcl.m4: Correct AIX-5 ppc build flags. Correct HP 11 64-bit gcc
- building. [Patch 601051] (martin)
+2007-03-08 Kevin B. Kenny <kennykb@acm.org>
-2002-10-15 Vince Darley <vincentdarley@users.sourceforge.net>
+ * library/clock.tcl: Further tweaks to the Windows time zone table
+ (restoring missing Mexican time zones). Added rudimentary handling of
+ version-2 'zoneinfo' files. Update US DST rules so that zones such as
+ 'EST5EDT' get the correct transition dates.
+ * tests/clock.test: Added rudimentary test cases for 'zoneinfo'
+ parsing. Adjusted several tests that depended on obsolete US DST
+ transition rules.
- * generic/tclCmdMZ.c:
- * tests/trace.test: applied patch from Hemang Levana to fix [Bug
- 615043] in execution traces with idle tasks firing.
+2007-03-07 Daniel Steffen <das@users.sourceforge.net>
-2002-10-14 Jeff Hobbs <jeffh@ActiveState.com>
+ * macosx/tclMacOSXNotify.c: add spinlock debugging and sanity checks.
- * generic/tclEnv.c (Tcl_PutEnv): correct possible mem leak.
- [Patch 623269] (brouwers)
+ * macosx/Tcl.xcodeproj/project.pbxproj: ensure gcc version used by
+ * macosx/Tcl.xcodeproj/default.pbxuser: Xcode and configure/make are
+ * macosx/Tcl-Common.xcconfig: consistent and independent of
+ gcc_select default and CC env var; fixes for Xcode 3.0.
-2002-10-11 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * unix/tcl.m4 (Darwin): s/CFLAGS/CPPFLAGS/ in macosx-version-min check
+ * unix/configure: autoconf-2.59
- * generic/tcl.h: Need a different strategy through the maze of
- #defines to let people building with Cygwin build correctly. Also
- made some comments less misleading...
+2007-03-07 Don Porter <dgp@users.sourceforge.net>
-2002-10-10 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclCmdIL.c (TclLindex*): Rewrites to make efficient
+ private copies of the list and indexlist arguments, so we can operate
+ on the list elements directly with no fear of shimmering effects.
+ Replaces defensive coding schemes that are otherwise required. End
+ result is that TclLindexList is entirely a wrapper around
+ TclLindexFlat, which is now the core engine of all [lindex]
+ operations.
- * README: fixed minor nits [Bug 607776] (virden)
+ * generic/tclObj.c (Tcl_AppendAllObjTypes): Converted to simpler
+ list validity test.
- * win/configure:
- * win/tcl.m4: enable USE_THREAD_ALLOC (new threaded allocator) by
- default in cygwin configure on Windows.
+2007-03-07 Donal K. Fellows <donal.k.fellows@man.ac.uk>
-2002-10-10 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclRegexp.c (TclRegAbout): Generate information about a
+ regexp as a Tcl_Obj instead of as a string, which is more efficient.
- * doc/Tcl.n: Clarified that namespace separators are legal in
- the variable names during $-subtitution. [Bug 615139]
+2007-03-07 Kevin B. Kenny <kennykb@acm.org>
- * doc/regexp.n: Typo correction. Thanks Ronnie Brunner. [Bug 606826]
+ * library/clock.tcl: Adjusted Windows time zone table to handle new US
+ DST rules by locale rather than as Posix time zone spec.
+ * tests/clock.test (clock-39.6, clock-49.2, testclock::registry):
+ Adjusted tests to simulate new US rules.
+ * library/tzdata/America/Indiana/Winamac:
+ * library/tzdata/Europe/Istanbul:
+ * library/tzdata/Pacific/Easter:
+ Olson's tzdata2007c.
-2002-10-10 Vince Darley <vincentdarley@users.sourceforge.net>
+2007-03-05 Andreas Kupries <andreask@activestate.com>
- * unix/tclLoadAout.c
- * unix/tclLoadDl.c
- * unix/tclLoadDld.c
- * unix/tclLoadDyld.c
- * unix/tclLoadNext.c
- * unix/tclLoadOSF.c
- * unix/tclLoadShl.c
- * win/tclWinLoad.c: allow either full paths or simply dll names to be
- specified when loading files (the latter will be looked up by the OS
- on your PATH/LD_LIBRARY_PATH as appropriate). Fixes [Bug 611108]
+ * library/platform/shell.tcl (::platform::shell::RUN): In the case of
+ * library/platform/pkgIndex.tcl: a failure put the captured stderr
+ * unix/Makefile.in: into the error message to aid in debugging. Bumped
+ * win/Makefile.in: package version to 1.1.2, and updated the makefiles
+ installing it as Tcl Module.
-2002-10-09 Jeff Hobbs <jeffh@ActiveState.com>
+2007-03-03 Donal K. Fellows <dkf@users.sf.net>
- * unix/README: doc'ed --enable-symbols options.
- * unix/Makefile.in: removed @MEM_DEBUG_FLAGS@ subst.
- * unix/configure: regen
- * unix/configure.in: removed SC_ENABLE_MEMDEBUG call
- * unix/tcl.m4: replaced SC_ENABLE_MEMDEBUG with a more intelligent
- SC_ENABLE_SYMBOLS that takes yes|no|mem|compile|all as options now.
+ * generic/tclLink.c (LinkedVar): Added macro to conceal at least some
+ of the pointer hackery.
-2002-10-09 Kevin B. Kenny <kennykb@acm.org>
+2007-03-02 Don Porter <dgp@users.sourceforge.net>
- * win/tclWinTime.c: Added code to set an exit handler that terminates
- the thread that calibrates the performance counter, so that the thread
- won't outlive unloading the Tcl DLL. [Bug 620735].
+ * generic/tclCmdIL.c (Tcl_LreverseObjCmd): Added missing
+ TclInvalidateStringRep() call when we directly manipulate the intrep
+ of an unshared "list" Tcl_Obj. [Bug 1672585]
-2002-10-09 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclCmdIL.c (Tcl_JoinObjCmd): Revised [join] implementation
+ to append Tcl_Obj's instead of strings. [RFE 1669420]
- * doc/binary.n: More clarification of [binary scan]'s behaviour.
+ * generic/tclCmdIL.c (Info*Cmd): Code simplifications and
+ optimizations.
-2002-10-09 Daniel Steffen <das@users.sourceforge.net>
+2007-03-02 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * generic/tclIntDecls.h: fixed botched regen.
+ * generic/tclCompile.c (TclPrintInstruction): Added a scheme to allow
+ * generic/tclCompile.h (AuxDataPrintProc): aux-data to be printed
+ * generic/tclCompCmds.c (Print*Info): out for debugging. For
+ this to work, immediate operands referring to aux-data must be
+ identified as such in the instruction descriptor table using
+ OPERAND_AUX4 (all are always 4 bytes).
-2002-10-09 Daniel Steffen <das@users.sourceforge.net>
+ * generic/tclExecute.c (TclExecuteByteCode): Rewrote the compiled
+ * generic/tclCompCmds.c (TclCompileDictCmd): [dict update] so that it
+ * generic/tclCompile.h (DictUpdateInfo): stores critical
+ * tests/dict.test (dict-21.{14,15}): non-varying data in an
+ aux-data value instead of a (shimmerable) literal. [Bug 1671001]
- * generic/tclInt.decls: made TclSetPreInitScript() declaration
- generic as it is used on mac & aqua as well.
- * generic/tclIntDecls.h:
- * generic/tclStubInit.c: regen.
- * generic/tclCompile.h: added prototype for TclCompileVariableCmd.
+2007-03-01 Don Porter <dgp@users.sourceforge.net>
- * mac/tclMacPort.h: removed incorrect <fcntl.h> definitions and
- obsolete <stat.h> definitions.
- * mac/tclMacChan.c: removed obsolete GetOpenMode() and replaced
- associated constants with the <fcntl.h> analogues (they existing defs
- were inconsistent with <fcntl.h> which was causing havoc when
- Tcl_GetOpenMode was used instead of private GetOpenMode).
+ * generic/tclCmdIL.c (Tcl_LinsertObjCmd): Code simplifications
+ and optimizations.
- * mac/tclMacFCmd.c: removed GenerateUniqueName(), use equivalent (and
- identically named) routine from MoreFiles instead.
+ * generic/tclCmdIL.c (Tcl_LreplaceObjCmd): Code simplifications
+ and optimizations.
- * mac/tclMacLoad.c: CONSTification, fixes to Vince's last changes.
+ * generic/tclCmdIL.c (Tcl_LrangeObjCmd): Rewrite in the same
+ spirit; avoid shimmer effects rather than react to them.
- * mac/tclMacFile.c:
- * mac/tclMacTest.c:
- * mac/tclMacUnix.c: CONSTification.
+ * generic/tclCmdAH.c (Tcl_ForeachObjCmd): Stop throwing away
+ * tests/foreach.test (foreach-1.14): useful error information when
+ loop variable sets fail.
- * mac/tclMacOSA.c: CONSTification, sprintf fixes, UH 3.4.x changes;
- fix for missing autoname token from TclOSACompileCmd. (bdesgraupes)
- * mac/AppleScript.html(AppleScript delete): doc fix. (bdesgraupes)
+ * generic/tclCmdIL.c (Tcl_LassignObjCmd): Rewrite to make an
+ efficient private copy of the list argument, so we can operate on the
+ list elements directly with no fear of shimmering effects. Replaces
+ defensive coding schemes that are otherwise required.
- * mac/tcltkMacBuildSupport.sea.hqx: updated MoreFiles to 1.5.3,
- updated build instructions for 8.4.
- * mac/tclMacProjects.sea.hqx: rebuilt archive.
+ * generic/tclCmdAH.c (Tcl_ForeachObjCmd): Rewrite to make
+ efficient private copies of the variable and value lists, so we can
+ operate on them without any special shimmer defense coding schemes.
-2002-10-09 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2007-03-01 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * doc/Alloc.3: Added a note to mention that attempting to allocate a
- zero-length block can return NULL. [Tk Bug 619544]
+ * generic/tclCompCmds.c (TclCompileForeachCmd): Prevent an unexpected
+ * tests/foreach.test (foreach-9.1): infinite loop when the
+ variable list is empty and the foreach is compiled. [Bug 1671138]
-2002-10-04 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2007-02-26 Andreas Kupries <andreask@activestate.com>
- * doc/binary.n: Doc improvements [Patch 616480]
+ * generic/tclIORChan.c (FreeReflectedChannel): Added the missing
+ refcount release between NewRC and FreeRC for the channel handle
+ object, spotted by Don Porter. [Bug 1667990]
- * tests/fCmd.test, tests/winFCmd.test:
- * tools/eolFix.tcl, tools/genStubs.tcl: [file exist] -> [file exists]
- Thanks to David Welton.
+2007-02-26 Don Porter <dgp@users.sourceforge.net>
-2002-10-03 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclCmdAH.c (Tcl_ForeachObjCmd): Removed surplus
+ copying of the objv array that used to be a workaround for [Bug
+ 404865]. That bug is long fixed.
- * doc/tcltest.n: fixed typo [Bug 618018]. Thanks to "JJM".
+2007-02-24 Don Porter <dgp@users.sourceforge.net>
-2002-10-03 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclBasic.c: Use new interface in Tcl_EvalObjEx so that the
+ recounting logic of the List internal rep need not be repeated there.
+ Better encapsulation of internal details.
- * tools/man2help2.tcl:
- * tests/http.test, tests/httpd, tests/httpold.test:
- * tests/env.test, tests/binary.test, tests/autoMkindex.test:
- * library/init.tcl, library/http/http.tcl: [info exist] should really
- be [info exists]. [Bug 602566]
+ * generic/tclInt.h: New internal routine TclListObjCopy() used
+ * generic/tclListObj.c: to efficiently do the equivalent of [lrange
+ $list 0 end]. After some experience with this, might be a good
+ candidate for exposure as a public interface. It's useful for callers
+ of Tcl_ListObjGetElements() who want to control the ongoing validity
+ of the returned objv pointer.
- * doc/lsearch.n: Better specification of what happens when -sorted is
- mixed with other options. [Bug 617816]
+2007-02-22 Andreas Kupries <andreask@activestate.com>
-2002-10-01 Jeff Hobbs <jeffh@ActiveState.com>
+ * tests/pkg.test: Added tests for the case of an alpha package
+ satisfying a require for the regular package, demonstrating a corner
+ case specified in TIP#280. More notes in the comments to the test.
- * generic/tclProc.c (TclCreateProc): mask out VAR_UNDEFINED for
- precompiled locals to support 8.3 precompiled code.
- (Tcl_ProcObjCmd): correct 2002-09-26 fix to look for tclProcBodyType.
+2007-02-20 Jan Nijtmans <nijtmans@users.sf.net>
-2002-10-01 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclInt.decls: Added "const" specifiers in TclSockGetPort
+ * generic/tclIntDecls.h: regenerated
+ * generic/*.c:
+ * unix/tclUnixChan.c
+ * unix/tclUnixPipe.c
+ * win/tclWinPipe.c
+ * win/tclWinSock.c: Added many "const" specifiers in implementation.
- * doc/socket.n: Mentioned that ports may be specified as serivce names
- as well as integers. [Bug 616843]
+2007-02-20 Don Porter <dgp@users.sourceforge.net>
-2002-09-30 Jeff Hobbs <jeffh@ActiveState.com>
+ * doc/tcltest.n: Typo fix. [Bug 1663539]
- * generic/tclCompCmds.c (TclCompileRegexpCmd): correct the checking
- for bad re's that didn't terminate the re string. Resultant compiles
- were correct, but much slower than necessary.
+2007-02-20 Pat Thoyts <patthoyts@users.sourceforge.net>
-2002-09-29 David Gravereaux <davygrvy@pobox.com>
+ * generic/tclFileName.c: Handle extended paths on Windows NT and
+ * generic/tclPathObj.c: above. These have a \\?\ prefix. [Bug
+ * win/tclWinFile.c: 1479814]
+ * tests/winFCmd.test: Tests for extended path handling.
- * win/tclAppInit.c: Added proper exiting conditions using Win32
- console signals. This handles the existing lack of a Ctrl+C exit to
- call exit handlers when built for thread support. Also, properly
- handles exits from other conditions such as CTRL_CLOSE_EVENT,
- CTRL_LOGOFF_EVENT, and CTRL_SHUTDOWN_EVENT signals. In all cases, exit
- handlers will be called. [Bug 219355]
+2007-02-19 Jeff Hobbs <jeffh@ActiveState.com>
- * win/makefile.vc: Added missing tclThreadAlloc.c to the build rules
- and defines USE_THREAD_ALLOC when TCL_THREADS is defined to get the
- new behavior by default.
+ * unix/tcl.m4: use SHLIB_SUFFIX=".so" on HP-UX ia64 arch.
+ * unix/configure: autoconf-2.59
-2002-09-27 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclIOUtil.c (Tcl_FSEvalFileEx): safe incr of objPtr ref.
- * README: Bumped to version 8.4.1 to avoid confusion
- * generic/tcl.h: of CVS snapshots with the actual 8.4.0
- * tools/tcl.wse.in: release.
- * unix/configure.in:
- * unix/tcl.spec:
- * win/configure.in:
+2007-02-18 Donal K. Fellows <dkf@users.sf.net>
- * unix/configure: autoconf
- * win/configure:
+ * doc/chan.n, doc/clock.n, doc/eval.n, doc/exit.n, doc/expr.n:
+ * doc/interp.n, doc/open.n, doc/platform_shell.n, doc/pwd.n:
+ * doc/refchan.n, doc/regsub.n, doc/scan.n, doc/tclvars.n, doc/tm.n:
+ * doc/unload.n: Apply [Bug 1610310] to fix typos. Thanks to Larry
+ Virden for spotting them.
-2002-09-26 Jeff Hobbs <jeffh@ActiveState.com>
+ * doc/interp.n: Partial fix of [Bug 1662436]; rest requires some
+ policy decisions on what should and shouldn't be safe commands from
+ the "new in 8.5" set.
- * unix/configure: regen.
- * unix/tcl.m4: improve AIX-4/5 64bit compilation support.
+2007-02-13 Kevin B. Kenny <kennykb@acm.org>
- * generic/tclProc.c (Tcl_ProcObjCmd): correct overeager optimization
- of noop proc to handle the precompiled case. (sofer)
+ * tools/fix_tommath_h.tcl: Further tweaking for the x86-64. The change
+ is to make 'mp_digit' be an 'unsigned int' on that platform; since
+ we're using only 32 bits of it, there's no reason to make it a 64-bit
+ 'unsigned long.'
+ * generic/tclTomMath.h: Regenerated.
- * unix/ldAix (nmopts): add -X32_64 to make it work for 32 or 64bit
- mode compilation.
+2007-02-13 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * library/encoding/koi8-u.enc: removed extraneous spaces that confused
- encoding reader. [Bug 615115]
+ * doc/re_syntax.n: Corrected description of 'print' class [Bug
+ 1614687] and enhanced description of 'graph' class.
- * unix/Makefile.in: generate source dists with -src designator and do
- not generate .Z anymore (just .gz and .zip).
+2007-02-12 Kevin B. Kenny <kennykb@acm.org>
-2002-09-18 Mumit Khan <khan@nanotech.wisc.edu>
+ * tools/fix_tommath_h.tcl: Added code to patch out a check for
+ __x86_64__ that caused Tommath to use __attributes(TI)__ for the
+ mp_word type. Tetra-int's simply fail on too many gcc-glibc-OS
+ combinations to be ready for shipment today, even if they work for
+ some of us. This change allows reversion of das's change of 2006-08-18
+ that accomplised the same thing on Darwin. [Bugs 1601380, 1603737,
+ 1609936, 1656265]
+ * generic/tclTomMath.h: Regenerated.
+ * library/tzdata/Africa/Asmara:
+ * library/tzdata/Africa/Asmera:
+ * library/tzdata/America/Nassau:
+ * library/tzdata/Atlantic/Faeroe:
+ * library/tzdata/Atlantic/Faroe:
+ * library/tzdata/Australia/Eucla:
+ * library/tzdata/Pacific/Easter: Rebuilt from Olson's tzdata2007b.
- Added basic Cygwin support.
+2007-02-09 Joe Mistachkin <joe@mistachkin.com>
- * win/tcl.m4 (SC_PATH_TCLCONFIG): Support one-tree build.
- (SC_PATH_TKCONFIG): Likewise.
- (SC_PROG_TCLSH): Likewise.
- (SC_CONFIG_CFLAGS): Assume real Cygwin port and remove -mno-cygwin
- flags. Add -mwin32 to extra_cflags and extra_ldflags. Remove ``-e
- _WinMain@16'' from LDFLAGS_WINDOW.
- * win/configure.in: Allow Cygwin build.
- (SEH test): Define to be 1 instead of empty value.
- (EXCEPTION_DISPOSITION): Add test.
- * win/configure: Regenerate.
+ * win/nmakehlp.c: Properly cleanup after nmakehlp, including the
+ * win/makefile.vc: vcX0.pch file.
- * generic/tcl.h: Don't explicitly define __WIN32__ for Cygwin, let the
- user decide whether to use Windows or POSIX personality.
- (TCL_WIDE_INT_TYPE, TCL_LL_MODIFIER, struct Tcl_StatBuf): Define for
- Cygwin.
- * generic/tclEnv.c (Tcl_CygwinPutenv): putenv replacement for Cygwin.
- * generic/tclFileName.c (Tcl_TranslateFileName): Convert POSIX to
- native format.
- (TclDoGlob): Likewise.
- * generic/tclPlatDecls.h (TCHAR): Define for Cygwin.
- * win/tclWinPort.h (putenv, TclpSysAlloc, TclpSysFree)
- (TclpSysRealloc): Define for Cygwin.
+2007-02-08 Jeff Hobbs <jeffh@ActiveState.com>
-2002-09-26 Daniel Steffen <das@users.sourceforge.net>
+ * unix/tclUnixInit.c (TclpCheckStackSpace): do stack size checks with
+ unsigned size_t to correctly validate stackSize in the 2^31+ range.
+ [Bug 1654104]
- * macosx/Makefile: preserve environment value of INSTALL_ROOT. When
- embedding only use deployment build. Force relink before embedded
- build to ensure new linker flags are picked up.
+2007-02-08 Don Porter <dgp@users.sourceforge.net>
- * macosx/Tcl.pbproj/project.pbxproj: add symbolic links to debug lib,
- stub libs and tclConfig.sh in framework toplevel. Configure target
- dependency fix. Fix to 'clean' action. Added private tcl headers to
- framework. Install tclsh symbolic link. Html doc build works when no
- installed tclsh available. Made html doc structure in framework more
- like in Apple frameworks.
+ * generic/tclNamesp.c: Corrected broken logic in Tcl_DeleteNamespace
+ * tests/namespace.test: introduced in Patch 1577278 that caused
+ [namespace delete ::] to be effective only at level #0. New test
+ namespace-7.7 should prevent similar error in the future [Bug 1655305]
-2002-09-24 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2007-02-06 Don Porter <dgp@users.sourceforge.net>
- * unix/tcl.m4 (SC_TCL_64BIT_FLAGS): Yet more robust 64-bit value
- detection to close [Bug 613117] on more systems.
+ * generic/tclNamesp.c: Corrected broken implementation of the
+ * tests/namespace.test: TclMatchIsTrivial optimization on [namespace
+ children $namespace $pattern].
- * generic/tclCompile.c (TclPrintSource): More CONSTifying.
- * generic/tclExecute.c (EvalStatsCmd): Object-ify to reduce warnings.
- Thanks to 'CoderX2' on the chat for bringing this to my attention...
+2007-02-04 Daniel Steffen <das@users.sourceforge.net>
- * unix/tcl.m4: Forgot to define TCL_WIDE_INT_IS_LONG at the
- appropriate moment. I believe this is the cause of [Bug 613117]
+ * unix/tcl.m4: use gcc4's __attribute__((__visibility__("hidden"))) if
+ available to define MODULE_SCOPE effective on all platforms.
+ * unix/configure.in: add caching to -pipe and zoneinfo checks.
+ * unix/configure: autoconf-2.59
+ * unix/tclConfig.h.in: autoheader-2.59
- * doc/lset.n: Changed 'list' to 'varName' for consistency with lappend
- documentation. Thanks to Glenn Jackman [Bug 611719]
+2007-02-03 Joe Mistachkin <joe@mistachkin.com>
-2002-09-22 Don Porter <dgp@users.sourceforge.net>
+ * win/rules.vc: Fix platform specific file copy macros for downlevel
+ Windows.
- * library/tcltest/tcltest.tcl: Corrected [puts -nonewline] within
- test bodies. Thanks to Harald Kirsch. [Bug 612786, Patch 612788] Also
- corrected reporting of body return code. Thanks to David Taback [Bug
- 611922]
- * library/tcltest/pkgIndex.tcl: Bump to version 2.2.1.
- * tests/tcltest.test: added tests for these bugs.
+2007-01-29 Don Porter <dgp@users.sourceforge.net>
-2002-09-15 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tclResult.c: Added optimization case to TclTransferResult to
+ cover common case where there's big savings over the fully general
+ path. Thanks to Peter MacDonald. [Bug 1626518]
- * unix/configure: Regen.
- * unix/tcl.m4 (SC_CONFIG_CFLAGS): Add PEEK_XCLOSEIM define under
- Linux. This is used by Tk to double check that an X input context is
- cleaned up before it is closed.
+ * generic/tclLink.c: Broken linked float logic corrected. Thanks to
+ Andy Goth. [Bug 1602538]
-2002-09-12 David Gravereaux <davygrvy@pobox.com>
+ * doc/fcopy.n: Typo fix. [Bug 1630627]
- * win/coffbase.txt: Added BLT to the virtual base address listings
- table should BLT's build tools decide to use it.
+2007-01-28 Daniel Steffen <das@users.sourceforge.net>
-2002-09-12 Daniel Steffen <das@users.sourceforge.net>
+ * macosx/Tcl.xcodeproj/project.pbxproj: extract build settings that
+ * macosx/Tcl.xcodeproj/default.pbxuser: were common to multiple
+ * macosx/Tcl-Common.xcconfig (new file): configurations into external
+ * macosx/Tcl-Debug.xcconfig (new file): xcconfig files; add extra
+ * macosx/Tcl-Release.xcconfig (new file): configurations for building
+ with SDKs and 64bit; convert legacy jam-based 'Tcl' target to native
+ target with single script phase; correct syntax of build setting
+ references to use $() throughout.
- * generic/tcl.h:
- * mac/tclMacApplication.r:
- * mac/tclMacLibrary.r:
- * mac/tclMacResource.r: unified use of the two equivalent resource
- compiler header inclusion defines RC_INVOKED and RESOURCE_INCLUDED,
- now use RC_INVOKED throughout.
+ * macosx/README: document new Tcl.xcodeproj configurations; other
+ minor updates/corrections.
-2002-09-10 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tcl.h: update location of version numbers in macosx files.
- * unix/README: Add note about building extensions with the same
- compiler Tcl was built with. [Tk Bug 592096]
+ * macosx/Tcl.xcode/project.pbxproj: restore 'tcltest' target to
+ * macosx/Tcl.xcode/default.pbxuser: working order by replicating
+ applicable changes to Tcl.xcodeproj since 2006-07-20.
-2002-09-10 Daniel Steffen <das@users.sourceforge.net>
+2007-01-25 Daniel Steffen <das@users.sourceforge.net>
- * macosx/Tcl.pbproj/project.pbxproj: disabled building html
- documentation during embedded build.
+ * unix/tcl.m4: integrate CPPFLAGS into CFLAGS as late as possible and
+ move (rather than duplicate) -isysroot flags from CFLAGS to CPPFLAGS
+ to avoid errors about multiple -isysroot flags from some older gcc
+ builds.
-2002-09-10 Daniel Steffen <das@users.sourceforge.net>
+ * unix/configure: autoconf-2.59
- * unix/Makefile.in: added DYLIB_INSTALL_DIR variable for macosx and
- set it to default value ${LIB_RUNTIME_DIR}
- * unix/tcl.m4 (Darwin): use DYLIB_INSTALL_DIR instead of
- LIB_RUNTIME_DIR in the -install_name argument to ld.
- * unix/configure: regen.
+2007-01-22 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * macosx/Tcl.pbproj/project.pbxproj:
- * macosx/Makefile: added support for building Tcl as an embedded
- framework, i.e. using an dyld install_name containing
- @executable_path/../Frameworks via the new DYLIB_INSTALL_DIR
- unix/Makefile variable.
+ * compat/memcmp.c (memcmp): Reworked so that arithmetic is never
+ performed upon void pointers, since that is illegal. [Bug 1631017]
-2002-09-10 Jeff Hobbs <jeffh@ActiveState.com>
+2007-01-19 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- *** 8.4.0 TAGGED FOR RELEASE ***
+ * generic/tclCompile.c (TclCompileScript): Reduce the frequency with
+ which we issue INST_START_CMD, making bytecode both more compact and
+ somewhat faster. The optimized case is where we would otherwise be
+ issuing a sequence of those instructions; in those cases, it is only
+ ever the first one encountered that could possibly trigger.
-2002-09-06 Don Porter <dgp@users.sourceforge.net>
+2007-01-19 Joe Mistachkin <joe@mistachkin.com>
- * doc/file.n: Format correction, and clarified [file normalize]
- returns an absolute path.
+ * tools/man2tcl.c: Include stdlib.h for exit() and improve comment
+ detection.
+ * win/nmakehlp.c: Update usage.
+ * win/makefile.vc: Properly build man2tcl.c for MSVC8.
- * doc/tcltest.n: Added examples section, as long promised.
+2007-01-19 Daniel Steffen <das@users.sourceforge.net>
-2002-09-06 Reinhard Max <max@suse.de>
+ * macosx/tclMacOSXFCmd.c (TclMacOSXSetFileAttribute): on some versions
+ of Mac OS X, truncate() fails on resource forks, in that case use
+ open() with O_TRUNC instead.
- * tests/tcltest.test: Added nonRoot flag to tests 8.3, 8.4, and 8.12.
+ * macosx/tclMacOSXNotify.c: accommodate changes to prototypes of
+ OSSpinLock(Un)Lock API.
-2002-09-05 Don Porter <dgp@users.sourceforge.net>
+ * macosx/Tcl.xcodeproj/project.pbxproj: ensure HOME and USER env vars
+ * macosx/Tcl.xcodeproj/default.pbxuser: are defined when running
+ testsuite from Xcode.
- * doc/tcltest.n: Clarified phrasing.
+ * tests/env.test: add extra system env vars that need to be preserved
+ on some Mac OS X versions for testsuite to work.
- * generic/tclBasic.c (TclRenameCommand,CallCommandTraces):
- * tests/trace.test (trace-27.1): Corrected memory leak when a rename
- trace deleted the command being traced. Test added. Thanks to Hemang
- Lavana for the fix. [Bug 604609]
+ * unix/Makefile.in: Move libtommath defines into configure.in to
+ * unix/configure.in: avoid replicating them across multiple
+ * macosx/Tcl.xcodeproj/project.pbxproj: buildsystems.
- * generic/tclVar.c (TclDeleteVars): Corrected logic for setting the
- TCL_INTERP_DESTROYED flag when calling variable traces. [Tk Bug 605121]
+ * unix/tcl.m4: ensure CPPFLAGS env var is used when set. [Bug 1586861]
+ (Darwin): add -isysroot and -mmacosx-version-min flags to CPPFLAGS
+ when present in CFLAGS to avoid discrepancies between what headers
+ configure sees during preprocessing tests and compiling tests.
-2002-09-04 Miguel Sofer <msofer@users.sourceforge.net>
+ * unix/configure: autoconf-2.59
+ * unix/tclConfig.h.in: autoheader-2.59
- * generic/tclVar.c (DeleteArray): leak plug [Bug 604239]. Thanks to
- dkf and dgp for the long and difficult discussion in the chat.
+2007-01-18 Donal K. Fellows <donal.k.fellows@man.ac.uk>
-2002-09-03 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclCompile.c (TclCompileScript): Make sure that when parsing
+ an expanded literal fails, a correct bytecode sequence is still
+ issued. [Bug 1638414]. Also make sure that the start of the expansion
+ bytecode sequence falls inside the span of bytecodes for a command.
+ * tests/compile.test (compile-16.24): Added test for [Bug 1638414]
- * generic/tclVar.c (Tcl_UpVar2): code cleanup to not use goto
+2007-01-17 Donal K. Fellows <dkf@users.sf.net>
- * unix/configure: remove -pthread from LIBS on FreeBSD in thread
- * unix/tcl.m4: enabled build. [Bug 602849]
+ * generic/tclIO.c: Added macros to make usage of ChannelBuffers
+ clearer.
-2002-09-03 Miguel Sofer <msofer@users.sourceforge.net>
+2007-01-11 Joe English <jenglish@users.sourceforge.net>
- * generic/tclInterp.c (AliasCreate): a Tcl_Obj was leaked on error
- return from TclPreventAliasLoop.
+ * win/tcl.m4(CFLAGS_WARNING): Remove "-Wconversion". This was removed
+ from unix/tcl.m4 2004-07-16 but not from here.
+ * win/configure: Regenerated.
-2002-09-03 Daniel Steffen <das@users.sourceforge.net>
+2007-01-11 Pat Thoyts <patthoyts@users.sourceforge.net>
- * macosx/Tcl.pbproj/project.pbxproj: Bumped version number to 8.4.0
- and updated copyright info.
+ * win/makefile.vc: Fixes to work better on Win98. Read version numbers
+ * win/nmakehlp.c: from package index file to avoid keeping numbers in
+ * win/rules.vc: the makefile where they may become de-synchronized.
-2002-09-03 Miguel Sofer <msofer@users.sourceforge.net>
+2007-01-10 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * generic/tclVar.c (Tcl_UpVar2): a Tcl_Obj was being leaked on error
- return from TclGetFrame.
+ * generic/regcomp.c (compile, freev): Define a strategy for
+ * generic/regexec.c (exec): managing the internal
+ * generic/regguts.h (AllocVars, FreeVars): vars of the RE engine to
+ * generic/regcustom.h (AllocVars, FreeVars): reduce C stack usage.
+ This will make Tcl as a whole much less likely to run out of stack
+ space...
-2002-09-03 Don Porter <dgp@users.sourceforge.net>
+2007-01-09 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * changes: Updated changes for 8.4.0 release.
+ * generic/tclCompCmds.c (TclCompileLindexCmd):
+ * tests/lindex.test (lindex-9.2): Fix silly bug that ended up
+ sometimes compiling list arguments in the wrong order. [Bug 1631364]
-2002-09-02 Jeff Hobbs <jeffh@ActiveState.com>
+2007-01-03 Kevin B. Kenny <kennykb@acm.org>
- * unix/tclUnixFile.c (TclpObjLink): removed unnecessary/unfreed
- extra native char*.
+ * generic/tclDate.c: Regenerated to recover a lost fix from patthoyts.
+ [Bug 1618523]
- * unix/tclUnixChan.c (Tcl_MakeTcpClientChannel): make sure to init
- flags field of TcpState ptr to 0.
+2006-12-26 Mo DeJong <mdejong@users.sourceforge.net>
- * unix/configure:
- * unix/tcl.m4: added 64-bit gcc compilation support on HP-11.
- [Patch 601051] (martin)
+ * generic/tclIO.c (Tcl_GetsObj): Avoid checking for for the LF in a
+ possible CRLF sequence when EOF has already been found.
- * README: Bumped version number to 8.4.0
- * generic/tcl.h:
- * tools/tcl.wse.in:
- * unix/configure:
- * unix/configure.in:
- * unix/tcl.spec:
- * win/README.binary:
- * win/configure:
- * win/configure.in:
+2006-12-26 Mo DeJong <mdejong@users.sourceforge.net>
- * generic/tclInterp.c (SlaveCreate): make sure that the memory and
- checkmem commands are initialized in non-safe slave interpreters when
- TCL_MEM_DEBUG is used. [Bug 583445]
+ * generic/tclEncoding.c (EscapeFromUtfProc): Clear the
+ TCL_ENCODING_END flag when end bytes are written. This fix keep this
+ method from writing escape bytes for an encoding like iso2022-jp
+ multiple times when the escape byte overlap with the end of the IO
+ buffer.
+ * tests/io.test: Add test for escape byte overlap issue.
- * win/tclWinConsole.c (ConsoleCloseProc): only wait on writable pipe
- if there was something to write. This may prevent infinite wait on
- exit.
+2006-12-19 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * tests/exec.test: marked exec-18.1 unixOnly until the Windows
- incompatability (in the test, not the core) can be resolved.
+ * unix/tclUnixThrd.c (Tcl_GetAllocMutex, TclpNewAllocMutex): Add
+ intermediate variables to shut up unwanted warnings. [Bug 1618838]
- * tests/http.test (http-3.11): added close $fp that was causing an
- error on Windows because the file was not closed before deleting.
+2006-12-19 Daniel Steffen <das@users.sourceforge.net>
- * unix/tclUnixInit.c (Tcl_MacOSXGetLibraryPath): made this static
- function only appear when HAVE_CFBUNDLE is defined.
+ * unix/tclUnixThrd.c (TclpInetNtoa): fix for 64 bit.
-2002-08-31 Daniel Steffen <das@users.sourceforge.net>
+ * unix/tcl.m4 (Darwin): --enable-64bit: verify linking with 64bit
+ -arch flag succeeds before enabling 64bit build.
+ * unix/configure: autoconf-2.59
- * unix/tcl.m4: added TK_SHLIB_LD_EXTRAS analogue of existing
- TCL_SHLIB_LD_EXTRAS for linker settings only used when linking Tk.
+2006-12-17 Daniel Steffen <das@users.sourceforge.net>
+
+ * tests/macOSXLoad.test (new file): add testing of .bundle loading and
+ * tests/load.test: unloading on Darwin (in addition
+ * tests/unload.test: to existing tests of .dylib
+ loading).
+ * macosx/Tcl.xcodeproj/project.pbxproj: add building of dltest
+ binaries so that testsuite run from Xcode can use them; fix testsuite
+ run script
+ * unix/configure.in: add support for building dltest binaries as
+ * unix/dltest/Makefile.in: .bundle (in addition to .dylib) on Darwin.
+ * unix/Makefile.in: add stub lib dependency to dltest target.
+ * unix/configure: autoconf-2.59
- * unix/configure: regen
+ * tests/append.test: fix cleanup failure when all tests are skipped.
-2002-08-31 Daniel Steffen <das@users.sourceforge.net>
+ * tests/chan.test (chan-16.9): cleanup chan event handler to avoid
+ causing error in event.test when running testsuite with -singleproc 1.
- *** macosx-8-4-branch merged into the mainline [Patch 602770] ***
+ * tests/info.test: add !singleTestInterp constraint to tests that fail
+ when running testsuite with -singleproc 1. [Bug 1605269]
- * generic/tcl.decls: added new macosx specific entry to stubs table.
+2006-12-14 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * tools/genStubs.tcl: added generation of platform guards for macosx.
- This is a little more complex than it seems, because MacOS X IS "unix"
- plus a little bit, for the purposes of Tcl. BUT unfortunately, Tk uses
- "unix" to mean X11. So added platform keys for macosx (the little
- added to "unix"), "aqua" and "x11" to distinguish these for Tk.
+ * doc/string.n: Fix example. [Bug 1615277]
- * generic/tcl.h: added a #ifnded RESOURCE_INCLUDED so that tcl.h can
- be passed to the resource compiler.
+2006-12-12 Don Porter <dgp@users.sourceforge.net>
- * generic/tcl.h:
- * generic/tclNotify.c: added a few Notifier procs, to be able to
- modify more bits of the Tcl notifier dynamically. Required to get Mac
- OS X Tk to live on top of the Tcl Unix threaded notifier. Changes the
- size of the Tcl_NotifierProcs structure, but doesn't move any elements
- around.
+ * generic/tclCompExpr.c: Now that the new internal structs are
+ in use to support operator commands, might as well make them the
+ default for [expr] as well and avoid passing every parsed expression
+ through the inefficient Tcl_Token array format. This addresses most
+ issues in [RFE 1517602]. Assuming no performance disasters result from
+ this, much dead code supporting the other implementation might now be
+ removed.
- * unix/tclUnixNotfy.c: moved the call to Tcl_ConditionNotify till
- AFTER we are done mucking with the pointer swap. Fixes cases where the
- thread waiting on the condition wakes & accesses the waitingListPtr
- before it gets reset, causing a hang.
+ * generic/tclBasic.c: Final step routing all direct evaluation forms
+ * generic/tclCompExpr.c: of the operator commands through TEBC,
+ * generic/tclCompile.h: dropping all the routines in tclMathOp.c.
+ * generic/tclMathOp.c: Still needs Engineering Manual attention.
- * library/auto.tcl (tcl_findLibrary): added checking the directories
- in the tcl_pkgPath for library files on macosx to enable support of
- the standard Mac OSX library locations
+2006-12-11 Don Porter <dgp@users.sourceforge.net>
- * unix/Makefile.in:
- * unix/configure.in:
- * unix/tcl.m4: added MAC_OSX_DIR. Added PLAT_OBJS to the OBJS: there
- are some MacOS X specific files now for Tcl, and when I get he
- resource & applescript stuff ported over, and restore support for
- FindFiles, etc, there will be a few more. Added LD_LIBRARY_PATH_VAR
- configure variable to avoid having to set all possible LD_LIBRARY_PATH
- analogues on all platforms. LD_LIBRARY_PATH_VAR is "LD_LIBRARY_PATH"
- by default, "LIBPATH" on AIX, "SHLIB_PATH" on HPUX and
- "DYLD_LIBRARY_PATH" on Mac OSX. Added configure option to package Tcl
- as a framework on Mac OSX.
+ * generic/tclBasic.c: Another step with all sorting operator
+ * generic/tclCompExpr.c: commands now routing through TEBC via
+ * generic/tclCompile.h: TclSortingOpCmd().
- * macosx/tclMacOSXBundle.c (new): support for finding Tcl extension
- packaged as 'bundles' in the standard Mac OSX library locations.
+2006-12-08 Don Porter <dgp@users.sourceforge.net>
- * unix/tclUnixInit.c: added support for findig the tcl script library
- inside Tcl packaged as a framework on Mac OSX.
+ * generic/tclBasic.c: Another step down the path of re-using
+ * generic/tclCompExpr.c: TclExecuteByteCode to implement the TIP 174
+ * generic/tclCompile.h: commands instead of using a mass of code
+ * generic/tclMathOp.c: duplication. Now all operator commands that
+ * tests/mathop.test: demand exactly one operation are implemented
+ via TclSingleOpCmd and a call to TEBC.
- * macosx/Tcl.pbproj/jingham.pbxuser (new):
- * macosx/Tcl.pbproj/project.pbxproj (new): project for Apple's
- ProjectBuilder IDE.
+ * generic/tclCompExpr.c: Revised implementation of TclInvertOpCmd to
+ * generic/tclMathOp.c: perform a bytecode compile / execute sequence.
+ This demonstrates a path toward avoiding mountains of code duplication
+ in tclMathOp.c and tclExecute.c.
- * macosx/Makefile (new): simple makefile for building the project from
- the command line via the ProjectBuilder tool 'pbxbuild'.
+ * generic/tclCompile.h: Change TclExecuteByteCode() from static to
+ * generic/tclExecute.c: MODULE_SCOPE so all files including
+ tclCompile.h may call it.
- * unix/configure:
- * generic/tclStubInit.c:
- * generic/tclPlatDecls.h: regen
+ * generic/tclMathOp.c: More revisions to make tests pass.
+ * tests/mathop.test:
-2002-08-29 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+2006-12-08 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * win/tclWinThrd.c (TclpFinalizeThreadData, TclWinFreeAllocCache):
- Applied patch for [Bug 599428] (sofer)
+ * generic/tclNamesp.c (TclTeardownNamespace): Ensure that dying
+ namespaces unstitch themselves from their referents. [Bug 1571056]
+ (NsEnsembleImplementationCmd): Silence GCC warning.
-2002-08-28 David Gravereaux <davygrvy@pobox.com>
+ * tests/mathop.test: Full tests for & | and ^ operators
- * generic/tclEnv.c:
- * unix/configure.in:
- * win/tclWinPort.h: putenv() on some systems copies the buffer rather
- than taking reference to it. This causes memory leaks and is know to
- effect mswindows (msvcrt) and NetBSD 1.5.2. This patch tests for this
- behavior and turns on -DHAVE_PUTENV_THAT_COPIES=1 when approriate.
- Thanks to David Welton for assistance. [Bug 414910]
+2006-12-08 Daniel Steffen <das@users.sourceforge.net>
- * unix/configure: regen'd
+ * library/tcltest/tcltest.tcl: use [info frame] for "-verbose line".
-2002-08-28 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2006-12-07 Don Porter <dgp@users.sourceforge.net>
- * doc/eval.n: Added mention of list command and corrected "SEE ALSO".
+ * generic/tclCompCmds.c: Additional commits correct most
+ * generic/tclExecute.c: failing tests illustrating bugs
+ * generic/tclMathOp.c: uncovered in [Patch 1578137].
- * unix/configure.in: Cache handling of ac_cv_type_socklen_t was wrong.
- [Bug 600931] reported by John Ellson. Fixed by putting the brackets
- where they belong.
+ * generic/tclBasic.c: Biggest source of TIP 174 failures was that
+ the commands were not [namespace export]ed from the ::tcl::mathop
+ namespace. More bits from [Patch 1578137] correct that.
-2002-08-26 Miguel Sofer <msofer@users.sourceforge.net>
+ * tests/mathop.test: Commmitted several new tests from Peter Spjuth
+ found in [Patch 1578137]. Many failures now demonstrate issues to fix
+ in the TIP 174 implementation.
- * generic/tclCompCmds.c: fix for [Bug 599788] (error in element name
- causing segfault), reported by Tom Wilkason. Fixed by copying the
- tokens instead of the source string.
+2006-12-07 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
-2002-08-26 Miguel Sofer <msofer@users.sourceforge.net>
+ * tests/mathop.test: Added tests for ! ~ eq operators.
+ * generic/tclMathOp.c (TclInvertOpCmd): Add in check for non-integral
+ numeric values.
+ * generic/tclCompCmds.c (CompileCompareOpCmd): Factor out the code
+ generation for the chained comparison operators.
- * generic/tclThreadAlloc.c: small optimisation, reducing the new
- allocator's overhead.
+2006-12-07 Pat Thoyts <patthoyts@users.sourceforge.net>
-2002-08-23 Miguel Sofer <msofer@users.sourceforge.net>
+ * tests/exec.test: Fixed line endings (caused win32 problems).
- * generic/tclObj.c (USE_THREAD_ALLOC): fixed leak [Bug 597936]. Thanks
- to Zoran Vasiljevic.
+2006-12-06 Don Porter <dgp@users.sourceforge.net>
-2002-08-23 Miguel Sofer <msofer@users.sourceforge.net>
+ * generic/tclCompCmds.c: Revised and consolidated into utility
+ * tests/mathop.test: routines some of routines that compile
+ the new TIP 174 commands. This corrects some known bugs. More to come.
- * generic/tclThreadAlloc.c (USE_THREAD_ALLOC): moving objects between
- caches as a block, instead of one-by-one.
+2006-12-06 Kevin B. Kenny <kennykb@acm.org>
-2002-08-22 Miguel Sofer <msofer@users.sourceforge.net>
+ * tests/expr.test (expr-47.12): Improved error reporting in hopes of
+ having more information to pursue [Bug 1609936].
- * generic/tclBasic.c:
- * generic/tclCmdMZ.c: fix for freed memory r/w in delete traces [Bug
- 589863], patch by Hemang Lavana.
+2006-12-05 Andreas Kupries <andreask@activestate.com>
-2002-08-20 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+ TIP#291 IMPLEMENTATION
- * win/Makefile.in (CFLAGS):
- * unix/Makefile.in (MEM_DEBUG_FLAGS): Added usage of @MEM_DEBUG_FLAGS@.
- * win/configure.in:
- * unix/configure.in: Added usage of SC_ENABLE_MEMDEBUG.
- * win/tcl.m4:
- * unix/tcl.m4: Added macro SC_ENABLE_MEMDEBUG. Allows a user of
- configure to (de)activate memory validation and debugging
- (TCL_MEM_DEBUG). No need to modify the makefile anymore.
+ * generic/tclBasic.c: Define tcl_platform element for pointerSize.
+ * doc/tclvars.n:
-2002-08-20 Don Porter <dgp@users.sourceforge.net>
+ * win/Makefile.in: Added installation instructions for the platform
+ * win/makefile.vc: package. Added the platform package.
+ * win/makefile.bc:
+ * unix/Makefile.in:
- * generic/tclCkalloc.c: CONSTified MemoryCmd and CheckmemCmd.
+ * tests/platform.test:
+ * tests/safe.test:
- * README: Bumped version number to 8.4b3 to distinguish
- * generic/tcl.h: HEAD from the 8.4b2 release.
- * tools/tcl.wse.in:
- * unix/configure.in:
- * unix/tcl.spec:
- * win/README.binary:
- * win/configure.in:
+ * library/platform/platform.tcl:
+ * library/platform/shell.tcl:
+ * library/platform/pkgIndex.tcl:
- * unix/configure: autoconf
- * win/configure:
+ * doc/platform.n:
+ * doc/platform_shell.n:
- * library/http/http.tcl: Corrected installation directory of
- * library/msgcat/msgcat.tcl: the package tcltest 2.2. Added
- * library/opt/optparse.tcl: comments in other packages to remind
- * library/tcltest/tcltest.tcl: that installation directories need
- * unix/Makefile.in: updates to match increasing version
- * win/Makefile.in: numbers. [Bug 597450]
- * win/makefile.bc:
- * win/makefile.vc:
+2006-12-05 Don Porter <dgp@users.sourceforge.net>
-2002-08-19 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+ * generic/tclPkg.c: When no requirements are supplied to a
+ * tests/pkg.test: [package require $pkg] and [package unknown]
+ is invoked to find a satisfying package, pass the requirement argument
+ "0-" (which means all versions are acceptable). This permits a
+ registered [package unknown] command to call [package vsatisfies
+ $testVersion {*}$args] without any special handling of the empty $args
+ case. This fixes/avoids a bug in [::tcl::tm::UnknownHandler] that was
+ causing old TM versions to be provided in preference to newer TM
+ versions. Thanks to Julian Noble for discovering the issue.
- * unix/tclUnixTest.c (TestfilehandlerCmd): Changed
- readable/writable to the more common readable|writable.
- Fixes [Bug 596034] (lvirden)
+2006-12-04 Donal K. Fellows <dkf@users.sf.net>
-2002-08-16 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ TIP#267 IMPLEMENTATION
- * tests/fCmd.test: Added test to make sure that the cause of the
- problem is detectable with an unpatched Tcl.
- * doc/ObjectType.3: Added note on the root cause of this problem to
- the documentation, since it is possible for user code to trigger this
- sort of behaviour too.
- * generic/tclIOUtil.c (SetFsPathFromAny): Objects should only have
- their old representation deleted when we know that we are about to
- install a new one. This stops a weird TclX bug under Linux with
- certain kinds of memory debugging enabled which essentally came down
- to a double-free of a string.
+ * generic/tclIOCmd.c (Tcl_ExecObjCmd): Added -ignorestderr option,
+ * tests/exec.test, doc/exec.n: loosely from [Patch 1476191]
-2002-08-14 Miguel Sofer <msofer@users.sourceforge.net>
+2006-12-04 Don Porter <dgp@users.sourceforge.net>
- * generic/tclInt.h:
- * generic/tclObj.c: (code cleanup) factored the parts in the macros
- TclNewObj() / TclDecrRefCount() into a common part for all memory
- allocators and two new macros TclAllocObjStorage() /
- TclFreeObjStorage() that are specific to each allocator and fully
- describe the differences. Removed allocator-specific code from
- tclObj.c by using the macros.
+ * generic/tclCompExpr.c: Added implementation for the
+ CompileExprTree() routine that can produce expression bytecode
+ directly from internal structures with no need to pass through the
+ Tcl_Token array representation. Still disabled by default. #undef
+ USE_EXPR_TOKENS to try it out.
-2002-08-12 Miguel Sofer <msofer@users.sourceforge.net>
+2006-12-03 Don Porter <dgp@users.sourceforge.net>
- * generic/tclCmdMZ.c: fixing UMR in delete traces, [Bug 589863].
+ * generic/tclCompExpr.c: Added expr parsing routines that
+ produce a different set of internal structures representing the parsed
+ expression, as well as routines that go on to convert those structures
+ into the traditional Tcl_Token array format. Use of these routines is
+ currently disabled. #undef PARSE_DIRECT_EXPR_TOKENS to enable them.
+ These routines will only become really useful when more routines that
+ compile directly from the new internal structures are completed.
-2002-08-08 David Gravereaux <davygrvy@pobox.com>
+2006-12-02 Donal K. Fellows <dkf@users.sf.net>
- * tools/man2help.tcl: Fixed $argv handling bug where if -bitmap wasn't
- specified $argc was off by one.
+ * doc/file.n: Clarification of [file pathtype] docs. [Bug 1606454]
-2002-08-08 Miguel Sofer <msofer@users.sourceforge.net>
+2006-12-01 Kevin B. Kenny <kennykb@acm.org>
- * tests/uplevel.test: added 6.1 to test [uplevel] with shadowed
- commands [Bug 524383]
+ * libtommath/bn_mp_add.c: Corrected the effects of a
+ * libtommath/bn_mp_div.c: bollixed 'cvs merge' operation
+ * libtommath/bncore.c: that inadvertently committed some
+ * libtommath/tommath_class.h: half-developed code.
- * tests/subst.test: added 5.8-10 as further tests for [Bug 495207]
+ TIP#299 IMPLEMENTATION
-2002-08-08 Don Porter <dgp@users.sourceforge.net>
+ * doc/mathfunc.n: Added isqrt() function to docs
+ * generic/tclBasic.c: Added isqrt() math function (ExprIsqrtFunc)
+ * tests/expr.test (expr-47.*): Added tests for isqrt()
+ * tests/info.test (info-20.2): Added isqrt() to expected math funcs.
- * tests/README: Noted removal of defs.tcl.
+2006-12-01 Don Porter <dgp@users.sourceforge.net>
-2002-08-08 Jeff Hobbs <jeffh@ActiveState.com>
+ * tests/chan.test: Correct timing sensitivity in new test. [Bug
+ 1606860]
- * doc/lsearch.n: corrected lsearch docs to use -inline in examples.
+ TIP#287 IMPLEMENTATION
- *** 8.4b2 TAGGED FOR RELEASE ***
+ * doc/chan.n: New subcommand [chan pending].
+ * generic/tclBasic.c: Thanks to Michael Cleverly for proposal
+ * generic/tclInt.h: and implementation.
+ * generic/tclIOCmd.c:
+ * library/init.tcl:
+ * tests/chan.test:
+ * tests/ioCmd.test:
- * tests/fCmd.test:
- * tests/unixFCmd.test: updated tests for new link copy behavior.
- * generic/tclFCmd.c (CopyRenameOneFile): changed the behavior to
- follow links to endpoints and copy that file/directory instead of just
- copying the surface link. This means that trying to copy a link that
- has no endpoint (danling link) is an error. [Patch 591647] (darley)
- (CopyRenameOneFile): this is currently disabled by default until
- further issues with such behavior (like relative links) can be handled
- correctly.
+ TIP#298 IMPLEMENTATION
- * tests/README: slight wording improvements
+ * generic/tcl.decls: Tcl_GetBignumAndClearObj -> Tcl_TakeBignumFromObj
+ * generic/tclObj.c:
-2002-08-07 Miguel Sofer <msofer@users.sourceforge.net>
+ * generic/tclDecls.h: make genstubs
+ * generic/tclStubInit.c:
- * docs/BoolObj.3: added description of valid string reps for a boolean
- object [Bug 584794]
- * generic/tclObj.c: optimised Tcl_GetBooleanFromObj and
- SetBooleanFromAny to avoid parsing the string rep when it can be
- avoided [Bugs 584650, 472576]
+ * generic/tclExecute.c: Update callers.
+ * generic/tclMathOp.c:
-2002-08-07 Miguel Sofer <msofer@users.sourceforge.net>
+2006-11-30 Kevin B. Kenny <kennykb@acm.org>
- * generic/tclCompile.h:
- * generic/tclObj.c: making tclCmdNameType static [Bug 584567] (dgp)
+ * library/tzdata: Olson's tzdata2006p.
+ * libtommath/bn_mp_sqrt.c: Fixed a bug where the initial approximation
+ to the square root could be on the wrong side, causing failure of
+ convergence.
-2002-08-07 Miguel Sofer <msofer@users.sourceforge.net>
+2006-11-29 Don Porter <dgp@users.sourceforge.net>
- * generic/tclObj.c (Tcl_NewObj): added conditional code for
- USE_THREAD_ALLOC; objects allocated through Tcl_NewObj() were
- otherwise being leaked. [Bug 587488] reported by Sven Sass.
+ * generic/tclBasic.c (Tcl_AppendObjToErrorInfo): Added
+ Tcl_DecrRefCount() on the objPtr argument to plug memory leaks. This
+ makes the routine a consumer, which makes it easiest to use.
-2002-08-06 Daniel Steffen <das@users.sourceforge.net>
+2006-11-28 Andreas Kupries <andreask@activestate.com>
- * generic/tclInt.decls:
- * unix/tclUnixThrd.c: Added stubs and implementations for non-threaded
- build for the tclUnixThrd.c procs TclpReaddir, TclpLocaltime,
- TclpGmtime and TclpInetNtoa. Fixes link errors in stubbed & threaded
- extensions that include tclUnixPort.h and use any of the procs
- readdir, localtime, gmtime or inet_ntoa (e.g. TclX 8.4) [Bug 589526]
- * generic/tclIntPlatDecls.h:
- * generic/tclStubInit.c: Regen.
-
-2002-08-05 Don Porter <dgp@users.sourceforge.net>
-
- * library/tcltest/tcltest.tcl: The setup and cleanup scripts are now
- * library/tcltest/pkgIndex.tcl: skipped when a test is skipped, fixing
- * tests/tcltest.test: [Bug 589859]. Test for bug added, and
- corrected tcltest package bumped to version 2.2.
-
- * generic/tcl.decls: Restored Tcl_Concat to return (char *). Like
- * generic/tclDecls.h: Tcl_Merge, it transfers ownership of a dynamic
- * generic/tclUtil.c: allocated string to the caller.
-
-2002-08-04 Don Porter <dgp@users.sourceforge.net>
-
- * doc/CmdCmplt.3: Applied Patch 585105 to fully CONST-ify
- * doc/Concat.3: all remaining public interfaces of Tcl.
- * doc/CrtCommand.3: Notably, the parser no longer writes on
- * doc/CrtSlave.3: the string it is parsing, so it is no
- * doc/CrtTrace.3: longer necessary for Tcl_Eval() to be
- * doc/Eval.3: given a writable string. Also, the
- * doc/ExprLong.3: refactoring of the Tcl_*Var* routines
- * doc/LinkVar.3: by Miguel Sofer is included, so that the
- * doc/ParseCmd.3: "part1" argument for them no longer needs
- * doc/SetVar.3: to be writable either.
- * doc/TraceVar.3:
- * doc/UpVar.3: Compatibility support has been enhanced so
- * generic/tcl.decls: that a #define of USE_NON_CONST will remove
- * generic/tcl.h: all possible source incompatibilities with
- * generic/tclBasic.c: the 8.3 version of the header file(s).
- * generic/tclCmdMZ.c: The new #define of USE_COMPAT_CONST now does
- * generic/tclCompCmds.c:what USE_NON_CONST used to do -- disable
- * generic/tclCompExpr.c:only those new CONST's that introduce
- * generic/tclCompile.c: irreconcilable incompatibilities.
+ * generic/tclBasic.c: TIP #280 implementation.
+ * generic/tclCmdAH.c:
+ * generic/tclCmdIL.c:
+ * generic/tclCmdMZ.c:
+ * generic/tclCompCmds.c:
+ * generic/tclCompExpr.c:
+ * generic/tclCompile.c:
* generic/tclCompile.h:
- * generic/tclDecls.h: Several bugs are also fixed by this patch.
- * generic/tclEnv.c: [Bugs 584051,580433] [Patches 585105,582429]
- * generic/tclEvent.c:
- * generic/tclInt.decls:
+ * generic/tclExecute.c:
+ * generic/tclIOUtil.c:
* generic/tclInt.h:
- * generic/tclIntDecls.h:
* generic/tclInterp.c:
- * generic/tclLink.c:
+ * generic/tclNamesp.c:
* generic/tclObj.c:
- * generic/tclParse.c:
- * generic/tclParseExpr.c:
* generic/tclProc.c:
- * generic/tclTest.c:
- * generic/tclUtf.c:
- * generic/tclUtil.c:
- * generic/tclVar.c:
- * mac/tclMacTest.c:
- * tests/expr-old.test:
- * tests/parseExpr.test:
- * unix/tclUnixTest.c:
- * unix/tclXtTest.c:
- * win/tclWinTest.c:
-
-2002-08-01 Miguel Sofer <msofer@users.sourceforge.net>
-
- * generic/tclExecute.c: bugfix (reading freed memory). Testsuite
- passed on linux/i386, compile-13.1 hung on linux/alpha.
-
-2002-08-01 Miguel Sofer <msofer@users.sourceforge.net>
-
- * generic/tclExecute.c: added a reference count for the complete
- execution stack, instead of Tcl_Preserve/Tcl_Release.
+ * tests/compile.test:
+ * tests/info.test:
+ * tests/platform.test:
+ * tests/safe.test:
-2002-08-01 Mo DeJong <mdejong@users.sourceforge.net>
+2006-11-27 Kevin B. Kenny <kennykb@acm.org>
- * generic/tclCkalloc.c (TclFinalizeMemorySubsystem): Don't lock the
- ckalloc mutex before invoking the Tcl_DumpActiveMemory function since
- it also locks the same mutex. This code is only executed when "memory
- onexit filename" has been executed and Tcl is compiled with
- -DTCL_MEM_DEBUG.
+ * unix/tclUnixChan.c (TclUnixWaitForFile):
+ * tests/event.test (event-14.*): Corrected a bug where
+ TclUnixWaitForFile would present select() with the wrong mask on an
+ LP64 machine if a fd number exceeds 32. Thanks to Jean-Luc Fontaine
+ for reporting and diagnosing [Bug 1602208].
-2002-08-01 Reinhard Max <max@suse.de>
+2006-11-27 Don Porter <dgp@users.sourceforge.net>
- * win/tclWinPort.h: The windows headers don't provide socklen_t, so we
- have to do it.
+ * generic/tclExecute.c (TclIncrObj): Correct failure to detect
+ floating-point increment values. Thanks to William Coleda [Bug
+ 1602991]
-2002-07-31 Miguel Sofer <msofer@users.sourceforge.net>
+2006-11-26 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclInt.h (USE_THREAD_ALLOC): for unshared objects,
- TclDecrRefCount now frees the internal rep before the string rep -
- just like the non-macro Tcl_DecrRefCount/TclFreeObj [Bug 524802]. For
- the other allocators the fix was done on 2002-03-06.
+ * tests/mathop.test, doc/mathop.n: More bits and pieces of the TIP#174
+ implementation. Note that the test suite is not yet complete.
-2002-07-31 Miguel Sofer <msofer@users.sourceforge.net>
+2006-11-26 Daniel Steffen <das@users.sourceforge.net>
- * generic/tclInterp.c: signed/unsigned comparison warning fixed
- (Vince Darley).
+ * unix/tcl.m4 (Linux): --enable-64bit support. [Patch 1597389]
+ * unix/configure: autoconf-2.59 [Bug 1230558]
-2002-07-31 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2006-11-25 Donal K. Fellows <dkf@users.sf.net>
- * unix/tcl.m4 (SC_BUGGY_STRTOD): Enabled caching of test results.
+ TIP#174 IMPLEMENTATION
- * unix/tcl.m4 (SC_BUGGY_STRTOD): Solaris 2.8 still has a buggy
- strtod() implementation; make sure we detect it.
+ * generic/tclMathOp.c (new file): Completed the implementation of the
+ interpreted versions of all the tcl::mathop commands. Moved to a new
+ file to make tclCompCmds.c more focused in purpose.
- * tests/expr.test (expr-22.*): Marked as non-portable because it seems
- that these tests have an annoying tendency to fail in unexpected ways.
- [Bugs 584825, 584950, 585986]
+2006-11-23 Donal K. Fellows <dkf@users.sf.net>
-2002-07-30 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+ * generic/tclCompCmds.c (Tcl*OpCmd, TclCompile*OpCmd):
+ * generic/tclBasic.c (Tcl_CreateInterp): Partial implementation of
+ TIP#174; the commands are compiled, but (mostly) not interpreted yet.
- * tests/io.test:
- * generic/tclIO.c (WriteChars): Added flag to break out of loop if
- nothing of the input is consumed at all, to prevent infinite looping
- of called with a non-UTF-8 string. Fixes [Bug 584603] partially.
- Added new test "io-60.1". Might need additional changes to Tcl_Main so
- that unprintable results are printed as binary data.
+2006-11-22 Donal K. Fellows <dkf@users.sf.net>
-2002-07-29 Mo DeJong <mdejong@users.sourceforge.net>
+ TIP#269 IMPLEMENTATION
- * unix/Makefile.in: Use CC_SEARCH_FLAGS instead of LD_SEARCH_FLAGS
- when linking with ${CC}.
- * unix/configure: Regen.
- * unix/configure.in: Don't subst CC_SEARCH_FLAGS or LD_SEARCH_FLAGS
- since this is now done in tcl.m4.
- * unix/tcl.m4 (SC_CONFIG_CFLAGS): Document and set CC_SEARCH_FLAGS
- whenever LD_SEARCH_FLAGS is set. [Patch 588290]
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd): Implementation of the [string
+ * tests/string.test (string-25.*): is list] command, based on
+ * doc/string.n: work by Joe Mistachkin, with
+ enhancements by Donal Fellows for better failindex behaviour.
-2002-07-29 Reinhard Max <max@suse.de>
+2006-11-22 Don Porter <dgp@users.sourceforge.net>
- * unix/tcl.m4 (SC_SERIAL_PORT): Fixed detection for cases when
- configure's stdin is not a tty.
+ * tools/genWinImage.tcl (removed): Removed two files used in
+ * win/README.binary (removed): production of binary distributions
+ for Windows, a task we no longer perform. [Bug 1476980]
+ * generic/tcl.h: Remove mention of win/README.binary in comment
- * unix/tclUnixPort.h:
- * generic/tclIOSock.c: Changed size_t to socklen_t in
- socket-related function calls.
+ * generic/tcl.h: Moved TCL_REG_BOSONLY #define from tcl.h to
+ * generic/tclInt.h: tclInt.h. Only know user is Expect, which
+ already #include's tclInt.h. No need to continue greater exposure.
+ [Bug 926500]
- * unix/configure.in: Added test and fallback definition
- for socklen_t.
+2006-11-20 Donal K. Fellows <dkf@users.sf.net>
- * unix/configure: generated.
+ * generic/tclBasic.c (Tcl_CreateInterp, TclHideUnsafeCommands):
+ * library/init.tcl: Refactored the [chan] command's guts so that it
+ does not use aliases to global commands, making the code more robust.
-2002-07-29 Miguel Sofer <msofer@users.sourceforge.net>
+2006-11-17 Don Porter <dgp@users.sourceforge.net>
- * generic/tclObj.c: fixed a comment
+ * generic/tclExecute.c (INST_EXPON): Corrected crash on
+ [expr 2**(1<<63)]. Was operating on cleared bignum Tcl_Obj.
- * generic/tcl.h:
- * generic/tclBasic.c:
- * generic/tclInterp.c: added the new flag TCL_EVAL_INVOKE to the
- interface of the Tcl_Eval* functions, removing the
- TCL_EVAL_NO_TRACEBACK added yesterday: alias invocations not only
- require no tracebacks, but also look up the command name in the global
- scope - see new test interp-9.4
- * tests/interp.test: added 9.3 to test for safety of aliases to hidden
- commands, 9.4 to test for correct command lookup scope.
-
-2002-07-29 Donal K. Fellows <fellowsd@cs.man.ac.uk>
-
- * generic/regc_locale.c (cclass): [[:xdigit:]] is only a defined
- concept on western characters, so should not allow any unicode digit,
- and hence number of ranges in [[:xdigit:]] is fixed.
- * tests/reg.test: Added test to detect the bug.
- * generic/regc_cvec.c (newcvec): Corrected initial size value in
- character vector structure. [Bug 578363] Many thanks to
- pvgoran@users.sf.net for tracking this down.
-
-2002-07-28 Miguel Sofer <msofer@users.sourceforge.net>
+2006-11-16 Donal K. Fellows <dkf@users.sf.net>
- * generic/tcl.h:
- * generic/tclBasic.c: added the new flag TCL_EVAL_NO_TRACEBACK to the
- interface of the Tcl_Eval* functions. Modified the error message for
- too many nested evaluations.
- * generic/tclInterp.h: changed the Alias struct to be of variable
- length and store the prefix arguments directly (instead of a pointer
- to a Tcl_Obj list). Made AliasObjCmd call Tcl_EvalObjv instead of
- TclObjInvoke - thus making aliases trigger execution traces. [Bug
- 582522]
- * tests/interp.test:
- * tests/stack.test: adapted to the new error message.
- * tests/trace.test: added tests for aliases firing the exec traces.
+ * doc/apply.n, doc/chan.n: Added examples.
-2002-07-27 Mo DeJong <mdejong@users.sourceforge.net>
+2006-11-15 Don Porter <dgp@users.sourceforge.net>
- * unix/Makefile.in: Revert fix for Tcl bug 529801 since it was
- incorrect and broke the build on other systems. Fix [Bug 587299]. Add
- MAJOR_VERSION, MINOR_VERSION, PATCH_LEVEL, SHLIB_LD_FLAGS,
- SHLIB_LD_LIBS, CC_SEARCH_FLAGS, LD_SEARCH_FLAGS, and LIB_FILE
- variables to support more generic library build/install rules.
- * unix/configure: Regen.
- * unix/configure.in: Move AC_PROG_RANLIB into tcl.m4. Move shared
- build test and setting of MAKE_LIB and MAKE_STUB_LIB into tcl.m4. Move
- subst of a number of variables into tcl.m4 where they are defined.
- * unix/tcl.m4 (SC_ENABLE_SYMBOLS, SC_CONFIG_CFLAGS):
- Subst vars where they are defined. Add MAKE_LIB, MAKE_STUB_LIB,
- INSTALL_LIB, and INSTALL_STUB_LIB rules to deal with the ugly details
- of running ranlib on static libs at build and install time. Replace
- TCL_SHLIB_LD_EXTRAS with SHLIB_LD_FLAGS and use it when building a
- shared library.
- * unix/tclConfig.sh.in: Add TCL_CC_SEARCH_FLAGS.
+ TIP#270 IMPLEMENTATION
-2002-07-26 Miguel Sofer <msofer@users.sourceforge.net>
+ * generic/tcl.decls: New public routines Tcl_ObjPrintf,
+ * generic/tclStringObj.c: Tcl_AppendObjToErrorInfo, Tcl_Format,
+ * generic/tclInt.h: Tcl_AppendLimitedToObj,
+ Tcl_AppendFormatToObj and Tcl_AppendPrintfToObj. Former internal
+ versions removed.
- * generic/tclExecute.c: fixed Tcl_Obj leak in code corresponding to
- the macro NEXT_INST_V(x, 0, 1). [Bug 587495]
+ * generic/tclDecls.h: make genstubs
+ * generic/tclStubInit.c:
-2002-07-26 Miguel Sofer <msofer@users.sourceforge.net>
+ * generic/tclBasic.c: Updated callers.
+ * generic/tclCkalloc.c:
+ * generic/tclCmdAH.c:
+ * generic/tclCmdIL.c:
+ * generic/tclCmdMZ.c:
+ * generic/tclCompExpr.c:
+ * generic/tclCompile.c:
+ * generic/tclDictObj.c:
+ * generic/tclExecute.c:
+ * generic/tclIORChan.c:
+ * generic/tclIOUtil.c:
+ * generic/tclMain.c:
+ * generic/tclNamesp.c:
+ * generic/tclObj.c:
+ * generic/tclPkg.c:
+ * generic/tclProc.c:
+ * generic/tclStrToD.c:
+ * generic/tclTimer.c:
+ * generic/tclUtil.c:
+ * unix/tclUnixFCmd.c:
- * generic/tclVar.c (TclObjLookupVar): leak fix and improved comments.
+ * tools/genStubs.tcl: Updated script to no longer produce the
+ _ANSI_ARGS_ wrapper in generated declarations. Also revised to accept
+ variadic prototypes with more than one fixed argument. (This is
+ possible since TCL_VARARGS and its limitations are no longer in use).
+ * generic/tcl.h: Some reordering so that macro definitions do
+ not interfere with the now _ANSI_ARGS_-less stub declarations.
-2002-07-26 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclDecls.h: make genstubs
+ * generic/tclIntDecls.h:
+ * generic/tclIntPlatDecls.h:
+ * generic/tclPlatDecls.h:
+ * generic/tclTomMathDecls.h:
- * generic/tclVar.c (TclLookupVar): removed early returns that
- prevented the parens from being restored. also removed goto label as
- it was not necessary.
+2006-11-15 Donal K. Fellows <dkf@users.sf.net>
-2002-07-24 Miguel Sofer <msofer@users.sourceforge.net>
+ * doc/ChnlStack.3, doc/CrtObjCmd.3, doc/GetIndex.3, doc/OpenTcp.3:
+ * doc/chan.n, doc/fconfigure.n, doc/fcopy.n, doc/foreach.n:
+ * doc/history.n, doc/http.n, doc/library.n, doc/lindex.n:
+ * doc/lrepeat.n, doc/lreverse.n, doc/pkgMkIndex.n, doc/re_syntax.n:
+ Convert \fP to \fR so that man-page scrapers have an easier time.
- * generic/tclExecute.c:
- * tests/expr-old.test: fix for erroneous error messages in [expr],
- [Bug 587140] reported by Martin Lemburg.
+2006-11-14 Don Porter <dgp@users.sourceforge.net>
-2002-07-25 Joe English <jenglish@users.sourceforge.net>
+ TIP#261 IMPLEMENTATION
- * generic/tclProc.c: fix for [Tk Bug 219218] "error handling with
- bgerror in Tk"
+ * generic/tclNamesp.c: [namespace import] with 0 arguments
+ introspects the list of imported commands.
-2002-07-24 Miguel Sofer <msofer@users.sourceforge.net>
+2006-11-13 Kevin B. Kenny <kennykb@users.sourceforge.net>
- * generic/tclExecute.c: restoring full TCL_COMPILE_DEBUG
- functionality.
+ * generic/tclThreadStorage.c (Tcl_InitThreadStorage):
+ (Tcl_FinalizeThreadStorage): Silence a compiler warning about
+ presenting a volatile pointer to 'memset'.
-2002-07-24 Don Porter <dgp@users.sourceforge.net>
+2006-11-13 Don Porter <dgp@users.sourceforge.net>
- * tests/unixInit.test: relaxed unixInit-3.1 to accept iso8859-15 as a
- valid C encoding. [Bug 575336]
+ * generic/tclIO.c: When [gets] on a binary channel needs to use
+ the "iso8859-1" encoding, save a copy of that encoding per-thread to
+ avoid repeated freeing and re-loading of it from the file system. This
+ replaces the cached copy of this encoding that the platform
+ initialization code used to keep in pre-8.5 releases.
-2002-07-24 Miguel Sofer <msofer@users.sourceforge.net>
+2006-11-13 Daniel Steffen <das@users.sourceforge.net>
- * generic/tclExecute.c: restoring the tcl_traceCompile functionality
- while I repair tcl_traceExec. The core now compiles and runs also
- under TCL_COMPILE_DEBUG, but execution in the bytecode engine can
- still not be traced.
+ * generic/tclCompExpr.c: Fix gcc warnings about 'cast to/from
+ * generic/tclEncoding.c: pointer from/to integer of different
+ * generic/tclEvent.c: size' on 64-bit platforms by casting
+ * generic/tclExecute.c: to intermediate types
+ * generic/tclHash.c: intptr_t/uintptr_t via new PTR2INT(),
+ * generic/tclIO.c: INT2PTR(), PTR2UINT() and UINT2PTR()
+ * generic/tclInt.h: macros. [Patch 1592791]
+ * generic/tclProc.c:
+ * generic/tclTest.c:
+ * generic/tclThreadStorage.c:
+ * generic/tclTimer.c:
+ * generic/tclUtil.c:
+ * unix/configure.in:
+ * unix/tclUnixChan.c:
+ * unix/tclUnixPipe.c:
+ * unix/tclUnixPort.h:
+ * unix/tclUnixTest.c:
+ * unix/tclUnixThrd.c:
-2002-07-24 Daniel Steffen <das@users.sourceforge.net>
+ * unix/configure: autoconf-2.59
+ * unix/tclConfig.h.in: autoheader-2.59
- * unix/Makefile.in:
- * unix/configure.in: corrected fix for [Bug 529801]: ranlib only
- needed for static builds on Mac OS X.
- * unix/configure: Regen.
- * unix/tclLoadDyld.c: fixed small bugs introduced by Vince,
- implemented library unloading correctly (needs OS X 10.2).
+2006-11-12 Donal K. Fellows <dkf@users.sf.net>
-2002-07-23 Joe English <jenglish@users.sourceforge.net>
+ * generic/tclInt.h, generic/tclInt.decls: Transfer TclPtrMakeUpvar and
+ TclObjLookupVar to the internal stubs table.
- * doc/OpenFileChnl.3: (Updates from Larry Virden)
- * doc/open.n:
- * doc/tclsh.1: Fix section numbers in Unix man page references.
- * doc/lset.n: In EXAMPLES section, include command to set the initial
- value used in subsequent examples.
- * doc/http.n: Package version updated to 2.4.
+2006-11-10 Daniel Steffen <das@users.sourceforge.net>
-2002-07-23 Mo DeJong <mdejong@users.sourceforge.net>
+ * tests/fCmd.test (fCmd-6.26): fix failure when env(HOME) path
+ contains symlinks.
- * unix/configure: Regen.
- * unix/tcl.m4 (SC_CONFIG_CFLAGS): Enable 64 bit compilation when using
- the native compiler on a 64 bit version of IRIX. [Bug 219220]
+ * macosx/Tcl.xcodeproj/project.pbxproj: remove tclParseExpr.c; when
+ running testsuite from inside Xcdoe, skip stack-3.1 (it only fails
+ under those circumstances).
-2002-07-23 Mo DeJong <mdejong@users.sourceforge.net>
+ * unix/tcl.m4 (Darwin): suppress linker arch warnings when building
+ universal for both 32 & 64 bit and no 64bit CoreFoundation is
+ available; sync with tk tcl.m4 change.
+ * unix/configure.in: whitespace.
+ * unix/configure: autoconf-2.59
- * unix/Makefile.in: Combine ranlib tests and avoid printing unless
- ranlib is actually run.
+2006-11-09 Don Porter <dgp@users.sourceforge.net>
-2002-07-23 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tclParseExpr.c (removed): Moved all the code of
+ * generic/tclCompExpr.c: tclParseExpr.c into tclCompExpr.c.
+ * unix/Makefile.in: This sets the stage for expr compiling to work
+ * win/Makefile.in: directly with the full parse tree structures,
+ * win/makefile.bc: and not have to pass through the information
+ * win/makefile.vc: lossy format of an array of Tcl_Tokens.
+ * win/tcl.dsp:
- * unix/tcl.m4 (SC_PATH_X): Set XINCLUDES to "" instead of "# no
- special path needed" or "# no include files found" when x headers
- cannot be located.
+2006-11-09 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
-2002-07-22 Vince Darley <vincentdarley@users.sourceforge.net>
+ TIP#272 IMPLEMENTATION
- * generic/tclIOUtil.c: made tclNativeFilesystem static (since 07-19
- changes removed its usage elsewhere), and added comments about its
- usage.
- * generic/tclLoad.c:
- * generic/tcl.h:
- * generic/tcl.decls:
- * doc/FileSystem.3: converted last load-related ClientData parameter
- to Tcl_LoadHandle opaque structure, removing a couple of casts in the
- process.
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd): Implementation of the
+ * tests/string.test, tests/stringComp.test: [string reverse] command
+ * doc/string.n: from TIP#272.
- * generic/tclInt.h: removed tclNativeFilesystem declaration since it
- is now static again.
+ * generic/tclCmdIL.c (Tcl_LreverseObjCmd): Implementation of the
+ * generic/tclBasic.c, generic/tclInt.h: [lreverse] command from
+ * tests/cmdIL.test (cmdIL-7.*): TIP#272.
+ * doc/lreverse.n:
-2002-07-22 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2006-11-08 Donal K. Fellows <dkf@users.sf.net>
- * tests/expr.test (expr-22.*): Added tests to help detect the
- corrected handling.
- * generic/tclExecute.c (IllegalExprOperandType): Improved error
- message generated when attempting to manipulate Inf and NaN values.
- * generic/tclParseExpr.c (GetLexeme): Allowed parser to recognise
- 'Inf' as a floating-point number. [Bug 218000]
+ * generic/tclIO.c, generic/tclPkg.c: Style & clarity rewrites.
-2002-07-21 Don Porter <dgp@users.sourceforge.net>
+2006-11-07 Andreas Kupries <andreask@activestate.com>
- * tclIOUtil.c: Silence compiler warning. [Bug 584408].
+ * unix/tclUnixFCmd.c (CopyFile): Added code to fall back to a
+ hardwired default block size should the filesystem report a bogus
+ value. [Bug 1586470]
-2002-07-19 Vince Darley <vincentdarley@users.sourceforge.net>
+2006-11-04 Don Porter <dgp@users.sourceforge.net>
- * generic/tclIOUtil.c: fix to GetFilesystemRecord
- * win/tclWinFile.c:
- * unix/tclUnixFile.c: fix to subtle problem with links shown up by
- latest tclkit builds.
+ * generic/tclStringObj.c: Changed Tcl_ObjPrintf() response to an
+ invalid format specifier string. No longer panics; now produces an
+ error message as output.
-2002-07-19 Mo DeJong <mdejong@users.sourceforge.net>
+ TIP#274 IMPLEMENTATION
- * unix/configure:
- * unix/configure.in:
- * win/configure:
- * win/configure.in: Add AC_PREREQ(2.13) in an attempt to make it more
- clear that the configure scripts must be generated with autoconf
- version 2.13. [Bug 583573]
+ * generic/tclParseExpr.c: Exponentiation operator is now right
+ * tests/expr.test: associative. [Patch 1556802]
-2002-07-19 Vince Darley <vincentdarley@users.sourceforge.net>
+2006-11-03 Miguel Sofer <msofer@users.sf.net>
- * unix/Makefile.in: fix to build on MacOS X [Bug 529801], bug report
- and fix from jcw.
+ * generic/tclBasic.c (TEOVI): fix por possible leak of a Command in
+ the presence of execution traces that delete it.
-2002-07-19 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclBasic.c (TEOVI):
+ * tests/trace.test (trace-21.11): fix for [Bug 1590232], execution
+ traces may cause a second command resolution in the wrong namespace.
+
+2006-11-03 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * tests/event.test (event-11.5): Rewrote tests to stop Tcl from
+ * tests/io.test (multiple tests): opening sockets that are
+ * tests/ioCmd.test (iocmd-15.1,16,17): reachable from outside hosts
+ * tests/iogt.test (__echo_srv__.tcl): where not necessary. This is
+ * tests/socket.test (multiple tests): noticably annoying on some
+ * tests/unixInit.test (unixInit-1.2): systems (e.g., Windows).
+
+2006-11-02 Daniel Steffen <das@users.sourceforge.net>
+
+ * macosx/Tcl.xcodeproj/project.pbxproj: check autoconf/autoheader exit
+ status and stop build if they fail.
+
+2006-11-02 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * doc/ParseCmd.3, doc/Tcl.n, doc/eval.n, doc/exec.n:
+ * doc/fconfigure.n, doc/interp.n, doc/unknown.n:
+ * library/auto.tcl, library/init.tcl, library/package.tcl:
+ * library/safe.tcl, library/tm.tcl, library/msgcat/msgcat.tcl:
+ * tests/all.tcl, tests/basic.test, tests/cmdInfo.test:
+ * tests/compile.test, tests/encoding.test, tests/execute.test:
+ * tests/fCmd.test, tests/http.test, tests/init.test:
+ * tests/interp.test, tests/io.test, tests/ioUtil.test:
+ * tests/iogt.test, tests/namespace-old.test, tests/namespace.test:
+ * tests/parse.test, tests/pkg.test, tests/pkgMkIndex.test:
+ * tests/proc.test, tests/reg.test, tests/trace.test:
+ * tests/upvar.test, tests/winConsole.test, tests/winFCmd.test:
+ * tools/tclZIC.tcl:
+ * generic/tclParse.c (Tcl_ParseCommand): Replace {expand} with {*}
+ officially (TIP #293). Leave -DALLOW_EXPAND=0|1 option to keep
+ {expand} syntax for transition users. [Bug 1589629]
+
+2006-11-02 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * generic/tclBasic.c, generic/tclInterp.c, generic/tclProc.c: Silence
+ warnings from gcc over signed/unsigned and TclStackAlloc().
+ * generic/tclCmdMZ.c: Update to more compact and clearer coding style.
+
+2006-11-02 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCmdAH.c: Further revisions to produce the routines
+ * generic/tclInt.h: TclFormat() and TclAppendFormatToObj() that
+ * generic/tclNamesp.c: accept (objc, objv) arguments rather than
+ * generic/tclStringObj.c: any varargs stuff.
+
+ * generic/tclBasic.c: Further revised TclAppendPrintToObj() and
+ * generic/tclCkalloc.c: TclObjPrintf() routines to panic when unable
+ * generic/tclCmdAH.c: to complete their formatting operations,
+ * generic/tclCmdIL.c: rather than report an error message. This
+ * generic/tclCmdMZ.c: means an interp argument for error message
+ * generic/tclDictObj.c: recording is no longer needed, further
+ * generic/tclExecute.c: simplifying the interface for callers.
+ * generic/tclIORChan.c:
+ * generic/tclIOUtil.c:
+ * generic/tclInt.h:
+ * generic/tclMain.c:
+ * generic/tclNamesp.c:
+ * generic/tclParseExpr.c:
+ * generic/tclPkg.c:
+ * generic/tclProc.c:
+ * generic/tclStringObj.c:
+ * generic/tclTimer.c:
+ * generic/tclUtil.c:
+ * unix/tclUnixFCmd.c:
- * win/tclWinSerial.c (no_timeout): Made this variable static.
+2006-11-02 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * generic/tclExecute.c, generic/tclCompile.c, generic/tclBasic.c:
- * generic/tclCompile.h (builtinFuncTable, instructionTable): Added
- prefix to these symbols because they are visible outside the Tcl
- library.
+ * tests/winPipe.test (winpipe-4.[2345]): Made robust when run in
+ directory with spaces in its name.
- * generic/tclCompExpr.c (operatorTable):
- * unix/tclUnixTime.c (tmKey):
- * generic/tclIOUtil.c (theFilesystemEpoch, filesystemWantToModify,
- (filesystemIteratorsInProgress, filesystemOkToModify): Made these
- variables static.
+ * generic/tclCmdAH.c: Clean up uses of cast NULLs.
- * unix/tclUnixFile.c: Renamed nativeFilesystem to
- * win/tclWinFile.c: tclNativeFilesystem and declared
- * generic/tclIOUtil.c: it properly in tclInt.h
- * generic/tclInt.h:
+ * generic/tclInterp.c (AliasObjCmd): Added more explanatory comments.
- * generic/tclUtf.c (totalBytes): Made this array static and const.
+ * generic/tclBasic.c (TclEvalObjvInternal): Rewrote so that comments
+ are relevant and informative once more. Also made the unknown handler
+ processing use the Tcl execution stack for working space, and not the
+ general heap.
- * generic/tclParse.c (typeTable): Made this array static and const.
- (Tcl_ParseBraces): Simplified error handling case so that scans are
- only performed when needed, and flags are simpler too.
+2006-11-01 Daniel Steffen <das@users.sourceforge.net>
- * license.terms: Added AS to list of copyright holders; it's only fair
- for the current gatekeepers to be listed here!
+ * unix/tclUnixPort.h: ensure MODULE_SCOPE is defined before use, so
+ that tclPort.h can once again be included without tclInt.h.
- * tests/cmdMZ.test: Renamed constraint for clarity. [Bug 583427]
- Added tests for the [time] command, which was previously only
- indirectly tested!
+ * generic/tclEnv.c (Darwin): mark _environ symbol as unexported even
+ when MODULE_SCOPE != __private_extern__.
-2002-07-18 Vince Darley <vincentdarley@users.sourceforge.net>
+2006-10-31 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclBasic.c: Refactored and renamed the routines
+ * generic/tclCkalloc.c: TclObjPrintf, TclFormatObj, and
+ * generic/tclCmdAH.c: TclFormatToErrorInfo to a new set of routines
+ * generic/tclCmdIL.c: TclAppendPrintfToObj, TclAppendFormatToObj,
+ * generic/tclCmdMZ.c: TclObjPrintf, and TclObjFormat, with the
+ * generic/tclDictObj.c: intent of making the latter list, plus
+ * generic/tclExecute.c: TclAppendLimitedToObj and
+ * generic/tclIORChan.c: TclAppendObjToErrorInfo, public via a revised
+ * generic/tclIOUtil.c: TIP 270.
* generic/tclInt.h:
- * generic/tcl.h:
- * */*Load*.c: added comments on changes of 07/17 and replaced
- clientData with Tcl_LoadHandle in all locations.
+ * generic/tclMain.c:
+ * generic/tclNamesp.c:
+ * generic/tclParseExpr.c:
+ * generic/tclPkg.c:
+ * generic/tclProc.c:
+ * generic/tclStringObj.c:
+ * generic/tclTimer.c:
+ * generic/tclUtil.c:
+ * unix/tclUnixFCmd.c:
- * generic/tclFCmd.c:
- * tests/fileSystem.test: fixed a 'knownBug' with 'file
- attributes ""'
- * tests/winFCmd.test:
- * tests/winPipe.test:
- * tests/fCmd.test:
- * tessts/winFile.test: added 'pcOnly' constraint to some tests to make
- for more useful 'tests skipped' log from running all tests on
- non-Windows platforms.
+2006-10-31 Miguel Sofer <msofer@users.sf.net>
-2002-07-17 Miguel Sofer <msofer@users.sourceforge.net>
+ * generic/tclBasic.c, generic/tcl.h, generic/tclInterp.c:
+ * generic/tclNamesp.c: removing the flag bit TCL_EVAL_NOREWRITE, the
+ last remnant of the callObjc/v fiasco. It is not needed, as it is now
+ always set and checked or'ed with TCL_EVAL_INVOKE.
- * generic/tclBasic.c (CallCommandTraces): delete traces now receive
- the FQ old name of the command. [Bug 582532] (Don Porter)
+2006-10-31 Pat Thoyts <patthoyts@users.sourceforge.net>
-2002-07-18 Vince Darley <vincentdarley@users.sourceforge.net>
+ * win/rules.vc: Fix for [Bug 1582769] - options conflict with VC2003.
- * tests/ioUtil.test: added constraints to 1.4,2.4 so they don't run
- outside of tcltest. [Bugs 583276,583277]
+2006-10-31 Donal K. Fellows <dkf@users.sf.net>
-2002-07-17 Miguel Sofer <msofer@users.sourceforge.net>
+ * generic/tclBasic.c, generic/tclNamesp.c, generic/tclProc.c:
+ * generic/tclInt.h: Removed the callObjc and callObjv fields from the
+ Interp structure. They did not function correctly and made other parts
+ of the core amazingly complex, resulting in a substantive change to
+ [info level] behaviour. [Bug 1587618]
+ * library/clock.tcl: Removed use of [info level 0] for calculating the
+ command name as used by the user and replace with a literal. What's
+ there now is sucky, but at least appears to be right to most users.
+ * tests/namespace.test (namespace-42.7,namespace-47.1): Reverted
+ changes to these tests.
+ * tests/info.test (info-9.11,info-9.12): Added knownBug constraint
+ since these tests require a different behaviour of [info level] than
+ is possible because of other dependencies.
- * generic/tclVar.c (DupParsedVarName): nasty bug fixed, reported by
- Vince Darley.
+2006-10-30 Jeff Hobbs <jeffh@ActiveState.com>
-2002-07-17 Miguel Sofer <msofer@users.sourceforge.net>
+ * tools/tcltk-man2html.tcl (option-toc): handle any kind of options
+ defined toc section (needed for ttk docs)
- * generic/tclVar.c (TclPtrIncrVar): missing CONST in declarations,
- inconsistent with tclInt.h. Thanks to Vince Darley for reporting, boo
- to gcc for not complaining.
+2006-10-30 Miguel Sofer <msofer@users.sf.net>
-2002-07-17 Vince Darley <vincentdarley@users.sourceforge.net>
+ * generic/tclBasic.c (TEOVI): insured that the interp's callObjc/v
+ fields are restored after traces run, as they be spoiled. This was
+ causing a segfault in tcllib's profiler tests.
- * generic/tclInt.h:
- * generic/tclIOUtil.c:
- * generic/tclLoadNone.c:
- * unix/tclLoadAout.c:
- * unix/tclLoadDl.c:
- * unix/tclLoadDld.c:
- * unix/tclLoadDyld.c:
- * unix/tclLoadNext.c:
- * unix/tclLoadOSF.c:
- * unix/tclLoadShl.c:
- * mac/tclMacLoad.c:
- * win/tclWinLoad.c: modified to move more functionality to the generic
- code and avoid duplication. Partial replacement of internal uses of
- clientData with opaque Tcl_LoadHandle. A little further work still
- needed, but significant changes are done.
-
-2002-07-17 D. Richard Hipp <drh@hwaci.com>
-
- * library/msgcat/msgcat.tcl: fix a comment that was causing problems
- for programs (ex: mktclapp) that embed the initialization scripts in
- strings.
-
-2002-07-17 Miguel Sofer <msofer@users.sourceforge.net>
+2006-10-30 Don Porter <dgp@users.sourceforge.net>
- * generic/tclInt.decls:
- * generic/tclIntDecls.h:
- * generic/tclStubInit.c:
- * generic/tclVar.c: removing the now redundant functions to access
- indexed variables: Tcl(Get|Set|Incr)IndexedScalar() and
- Tcl(Get|Set|Incr)ElementOfIndexedArray().
-
-2002-07-17 Donal K. Fellows <fellowsd@cs.man.ac.uk>
-
- * generic/tclExecute.c (TclExecuteByteCode): Minor fixes to make this
- file compile with SunPro CC...
-
-2002-07-17 Miguel Sofer <msofer@users.sourceforge.net>
+ * generic/tclExecute.c (INST_MOD): Corrected improper testing of the
+ * tests/expr.test: sign of bignums when applying Tcl's
+ division rules. Thanks to Peter Spjuth. [Bug 1585704]
- * generic/tclExecute.c: modified to do variable lookup explicitly, and
- then either inlining the variable access or else calling the new
- TclPtr(Set|Get|Incr)Var functions in tclVar.c
- * generic/tclInt.h: declare some functions previously local to
- tclVar.c for usage by TEBC.
- * generic/tclVar.c: removed local declarations; moved all special
- accessor functions for indexed variables to the end of the file - they
- are unused and ready for removal, but left there for the time being as
- they are in the internal stubs table.
+2006-10-29 Miguel Sofer <msofer@users.sf.net>
- ** WARNING FOR BYTECODE MAINTAINERS **
- TCL_COMPILE_DEBUG is currently not functional; will be fixed ASAP.
+ * generic/tclNamesp.c (EnsembleImplementationCmd):
+ * tests/namespace.test (47.7-8): reverted a wrong "optimisation" that
+ completely broke snit; added two tests.
-2002-07-16 Mo DeJong <mdejong@users.sourceforge.net>
+2006-10-28 Donal K. Fellows <dkf@users.sf.net>
- * unix/Makefile.in:
- * win/Makefile.in: Add a more descriptive warning in the event `make
- genstubs` needs to be rerun.
+ * generic/tclProc.c (ObjInterpProcEx, TclObjInterpProcCore): Split the
+ core of procedures to make it easier to build procedure-like code
+ without going through horrible contortions. This is the last critical
+ component to make advanced OO systems workable as simple loadable
+ extensions. TOIPC is now in the internal stub table.
+ (MakeProcError, MakeLambdaError): Refactored ProcessProcResultCode to
+ be simpler, some of which goes to TclObjInterpProcCore, and the rest
+ of which is now in these far simpler routines which just do errorInfo
+ stack generation for different types of procedure-like entity.
+ * tests/apply.test (apply-5.1): Updated to expect the more informative
+ form of message.
-2002-07-16 Mo DeJong <mdejong@users.sourceforge.net>
+2006-10-27 Donal K. Fellows <dkf@users.sf.net>
- * unix/Makefile.in: Use dltest.marker file to keep track of when the
- dltest package is up to date. This fixes [Bug 575768] since tcltest is
- no longer linked every time.
- * unix/dltest/Makefile.in: Create ../dltest.marker after a successful
- `make all` run in dltest.
+ * generic/tclVar.c (HasLocalVars): New macro to make various bits and
+ pieces cleaner.
-2002-07-16 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tclNamesp.c (TclSetNsPath): Expose SetNsPath() through
+ internal stubs table with semi-external name.
- * unix/configure: Regen.
- * unix/configure.in: Remove useless subst of TCL_BIN_DIR.
+ * generic/tclInt.h (CallFrame): Add a field for handling context data
+ for extensions (like object systems) that should be tied to a call
+ frame (and not a command or interpreter).
-2002-07-15 Miguel Sofer <msofer@users.sourceforge.net>
+ * generic/tclBasic.c (TclRenameCommand): Change to take CONST args;
+ they were only ever used in a constant way anyway, so this appears to
+ be a spot that was missed during TIP#27 work.
- * generic/tclVar.c: inaccurate comment fixed
+2006-10-26 Miguel Sofer <msofer@users.sf.net>
-2002-07-15 Miguel Sofer <msofer@users.sourceforge.net>
+ * generic/tclProc.c (SetLambdaFromAny): minor change, eliminate
+ redundant call to Tcl_GetString (thanks aku).
- * generic/tclBasic.c (Tcl_AddObjErrorInfo):
- * generic/tclExecute.c (TclUpdateReturnInfo):
- * generic/tclInt.h:
- * generic/tclProc.c:
- Added two Tcl_Obj to the ExecEnv structure to hold the fully qualified
- names "::errorInfo" and "::errorCode" to cache the addresses of the
- corresponding variables. The two most frequent setters of these
- variables now profit from the new variable name caching.
+ * generic/tclInterp.c (ApplyObjCmd):
+ * generic/tclNamesp.c (EnsembleImplementationCmd): replaced ckalloc
+ (heap) with TclStackAlloc (execution stack).
-2002-07-15 Miguel Sofer <msofer@users.sourceforge.net>
+2006-10-24 Miguel Sofer <msofer@users.sf.net>
- * generic/tclVar.c: refactorisation to reuse already looked-up Var
- pointers; definition of three new Tcl_Obj types to cache variable name
- parsing and lookup for later reuse; modification of internal functions
- to profit from the caching.
+ * tests/info.test (info-9.11-12): tests for [Bug 1577492]
+ * tests/apply.test (apply-4.3-5): tests for [Bug 1574835]
- * generic/tclInt.decls:
- * generic/tclInt.h:
- * generic/tclIntDecls.h:
- * generic/tclNamesp.c: adding CONST qualifiers to variable names
- passed to Tcl_FindNamespaceVar and to variable resolvers; adding CONST
- qualifier to the 'msg' argument to TclLookupVar. Needed to avoid code
- duplication in the new tclVar.c code.
+ * generic/tclProc.c (ObjInterpProcEx): disable itcl hacks for calls
+ from ApplyObjCmd (islambda==1), as they mess apply's error messages
+ [Bug 1583266]
- * tests/set-old.test:
- * tests/var.test: slight modification of error messages due to the
- modifications in the tclVar.c code.
+2006-10-23 Miguel Sofer <msofer@users.sf.net>
-2002-07-15 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclProc.c (ApplyObjCmd): fix wrong#args for apply by using
+ the ensemble rewrite engine. [Bug 1574835]
+ * generic/tclInterp.c (AliasObjCmd): previous commit missed usage of
+ TCL_EVAL_NOREWRITE for aliases.
- * tests/unixInit.test: Improved constraints to protect /tmp. [Bug
- 581403]
+ * generic/tclBasic.c (TclEvalObjvInternal): removed redundant check
+ for ensembles. [Bug 1577628]
-2002-07-15 Vince Darley <vincentdarley@users.sourceforge.net>
+ * library/clock.tcl (format, scan): corrected wrong # args messages to
+ * tests/clock.test (3.1, 34.1): make use of the new rewrite
+ capabilities of [info level]
- * tests/winFCmd.test: renamed 'win2000' and 'notWin2000' to more
- appropriate constraint names.
- * win/tclWinFile.c: updated comments to reflect 07-11 changes.
- * win/tclWinFCmd.c: made ConvertFileNameFormat static again, since no
- longer used in tclWinFile.c
- * mac/tclMacFile.c: completed TclpObjLink implementation which was
- previously lacking.
- * generic/tclIOUtil.c: comment cleanup and code speedup.
+ * generic/tcl.h: Lets TEOV update the iPtr->callObj[cv] new
+ * generic/tclBasic.c: fields, except when the flag bit
+ * generic/tclInt.h: TCL_EVAL_NOREWRITE is present. These values
+ * generic/tclNamesp.c: are used by Tcl_PushCallFrame to initialise
+ * generic/tclProc.c: the frame's obj[cv] fields, and allows
+ * tests/namespace.test: [info level] to know and use ensemble
+ rewrites. [Bug 1577492]
-2002-07-14 Don Porter <dgp@users.sourceforge.net>
+ ***POTENTIAL INCOMPATIBILITY***
+ The return value from [info level 0] on interp alias calls is changed:
+ previously returned the target command (including curried values), now
+ returns the source - what was actually called.
+
+2006-10-23 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tcl.h: Modified the Tcl call stack so there is
+ * generic/tclBasic.c: always a valid CallFrame, even at level 0
+ * generic/tclCmdIL.c: [Patch 1577278]. Most of the changes
+ * generic/tclInt.h: involve removing tests for a NULL
+ * generic/tclNamesp.c: iPtr->(var)framePtr. There is now a
+ * generic/tclObj.c: CallFrame pushed at interp creation with a
+ * generic/tclProc.c: pointer to it stored in iPtr->rootFramePtr.
+ * generic/tclTrace.c: A second unused field in Interp is
+ * generic/tclVar.c: hijacked to enable further functionality,
+ currently unused (but with several FRQs depending on it).
- * generic/tclInt.h: Removed declarations that duplicated entries
- in the (internal) stub table.
+ ***POTENTIAL INCOMPATIBILITY***
+ Any user that includes tclInt.h and needs to determine if it is
+ running at level 0 should change (iPtr->varFramePtr == NULL) to
+ (iPtr->varFramePtr == iPtr->rootFramePtr).
- * library/tcltest/tcltest.tcl: Corrected errors in handling of
- configuration options -constraints and -limitconstraints.
+2006-10-23 Don Porter <dgp@users.sourceforge.net>
- * README: Bumped HEAD to version 8.4b2 so we can
- * generic/tcl.h: distinguish it from the 8.4b1 release.
+ * README: Bump version number to 8.5a6
+ * generic/tcl.h:
* tools/tcl.wse.in:
- * unix/configure*:
+ * unix/configure.in:
* unix/tcl.spec:
* win/README.binary:
- * win/configure*:
-
-2002-07-11 Vince Darley <vincentdarley@users.sourceforge.net>
-
- * doc/file.n:
- * win/tclWinFile.c: on Win 95/98/ME the long form of the path is used
- as a normalized form. This is required because short forms are not a
- robust representation. The file normalization function has been sped
- up, but more performance gains might be possible, if speed is still an
- issue on these platforms.
-
-2002-07-11 Don Porter <dgp@users.sourceforge.net>
-
- * library/tcltest/tcltest.tcl: Corrected reaction to existing but
- false ::tcl_interactive.
-
- * doc/Hash.3: Overlooked CONST documentation update.
-
-2002-07-11 Donal K. Fellows <fellowsd@cs.man.ac.uk>
-
- * generic/tclCkalloc.c: ckalloc() and friends take the block size as
- an unsigned, so we should use %ud when reporting it in fprintf() and
- panic().
-
-2002-07-11 Miguel Sofer <msofer@users.sourceforge.net>
-
- * generic/tclCompile.c: now setting local vars undefined at compile
- time, instead of waiting until the proc is initialized.
- * generic/tclProc.c: use macro TclSetVarUndefined instead of directly
- setting the flag.
-
-2002-07-11 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * win/configure.in:
- * tests/cmdAH.test: [file attr -perm] is Unix-only, so add [catch]
- when not inside a suitably-protected test.
+ * unix/configure: autoconf-2.59
+ * win/configure:
-2002-07-10 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2006-10-21 Miguel Sofer <msofer@users.sf.net>
- * tests/unixFCmd.test, tests/fileName.test:
- * tests/fCmd.test: Removed [exec] of Unix utilities that have
- equivalents in standard Tcl. [Bug 579268] Also simplified some of
- unixFCmd.test while I was at it.
+ * generic/tcl.h, generic/tclHash.c: Tcl_FindHashEntry now calls
+ Tcl_CreateHashEntry with a newPtr set to NULL: this would have caused
+ a segfault previously and eliminates duplicated code. A macro has been
+ added to tcl.h (only used when TCL_PRESERVE_BINARY_COMPATABALITY is
+ not set - i.e., not by default).
-2002-07-10 Don Porter <dgp@users.sourceforge.net>
+2006-10-20 Reinhard Max <max@tclers.tk>
- * tests/tcltest.test: Greatly reduced the number of [exec]s, using
- slave interps instead.
- * library/tcltest/tcltest.tcl: Fixed bug uncovered in the conversion
- where a message was written to stdout instead of [outputChannel].
+ * unix/configure.in: Added autodetection for OS-supplied timezone
+ * unix/Makefile.in: files and configure switches to override the
+ * unix/configure: detected default.
- * tests/basic.test: Cleaned up, constrained, and reduced the
- * tests/compile.test: amount of [exec] usage in the test suite.
- * tests/encoding.test:
- * tests/env.test:
- * tests/event.test:
- * tests/exec.test:
- * tests/io.test:
- * tests/ioCmd.test:
- * tests/regexp.test:
- * tests/regexpComp.test:
- * tests/socket.test:
- * tests/tcltest.test:
- * tests/unixInit.test:
- * tests/winDde.test:
- * tests/winPipe.test:
+2006-10-20 Daniel Steffen <das@users.sourceforge.net>
-2002-07-10 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ *** 8.5a5 TAGGED FOR RELEASE ***
- * tests/cmdAH.test: Removed [exec] of Unix utilities. [Bug 579211]
+ * tools/tcltk-man2html.tcl: add support for alpha & beta versions to
+ useversion glob pattern. [Bug 1579941]
- * tests/expr.test: Added tests to make sure that this works.
- * generic/tclExecute.c (ExprCallMathFunc): Functions should also be
- able to return wide-ints. [Bug 579284]
+2006-10-18 Don Porter <dgp@users.sourceforge.net>
-2002-07-08 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+ * changes: 8.5a5 release date set
- * tests/socket.test: Fixed [Bug 578164]. The original reason for the
- was a DNS outage while running the testsuite. Changed [info hostname]
- to 127.0.0.1 to bypass DNS, knowing that we operate on the local
- host.
+ * doc/Encoding.3: Missing doc updates (mostly Table of
+ * doc/Ensemble.3: Contents) exposed by `make checkdoc`
+ * doc/FileSystem.3:
+ * doc/GetTime.3:
+ * doc/PkgRequire.3:
-2002-07-08 Don Porter <dgp@users.sourceforge.net>
+2006-10-17 Miguel Sofer <msofer@users.sf.net>
- * doc/tcltest.n: Fixed incompatibility in [viewFile].
- * library/tcltest/tcltest.tcl: Corrected docs. Bumped to 2.2.1.
- * library/tcltest/pkgIndex.tcl: [Bug 578163]
+ * generic/tclInterp.c (ApplyObjCmd): fixed bad error in 2006-10-12
+ commit: interp released too early. Spotted by mistachkin.
-2002-07-08 Vince Darley <vincentdarley@users.sourceforge.net>
+2006-10-16 Miguel Sofer <msofer@users.sf.net>
- * tests/cmdAH.test:
- * tests/fCmd.test:
- * tests/fileName.test: tests which rely on 'file link' need a
- constraint so they don't run on older Windows OS. [Bug 578158]
- * generic/tclIOUtil.c:
- * generic/tcl.h:
- * generic/tclInt.h:
- * generic/tclTest.c:
- * mac/tclMacChan.c:
- * unix/tclUnixChan.c:
- * win/tclWinChan.c:
- * doc/FileSystem.3: cleaned up internal handling of
- Tcl_FSOpenFileChannel to remove duplicate code, and make writing
- external vfs's clearer and easier. No functionality change. Also
- clarify that objects with refCount zero should not be passed in to the
- Tcl_FS API, and prevent segfaults from occuring on such user errors.
- [Bug 578617]
-
-2002-07-06 Don Porter <dgp@users.sourceforge.net>
-
- * tests/pkgMkIndex.test: Constrained tests of [load] package indexing
- to those platforms where the testing shared libraries have been built.
- [Bug 578166].
-
-2002-07-05 Don Porter <dgp@users.sourceforge.net>
-
- * changes: added recent changes
-
-2002-07-05 Reinhard Max <max@suse.de>
-
- * generic/tclClock.c (FormatClock): Convert the format string to
- UTF8 before calling TclpStrftime, so that non-ASCII characters don't
- get mangled when the result string is being converted back.
- * tests/clock.test: Added a test for that.
-
-2002-07-05 Donal K. Fellows <fellowsd@cs.man.ac.uk>
-
- * unix/Makefile.in (ro-test,ddd,GDB,DDD): Created new targets to allow
- running the test suite with a read-only current directory, running
- under ddd instead of gdb, and factored out some executable names for
- broken sites (like mine) where gdb and ddd are installed with
- non-standard names...
-
- * tests/httpold.test: Altered test names to httpold-* to avoid clashes
- with http.test, and stopped tests from failing when the current
- directory is not writable...
-
- * tests/event.test: Stop these tests from failing
- * tests/ioUtil.test: when the current directory is
- * tests/regexp.test: not writable...
- * tests/regexpComp.test:
- * tests/source.test:
- * tests/unixFile.test:
- * tests/unixNotfy.test:
-
- * tests/unixFCmd.test: Trying to make these test-files
- * tests/macFCmd.test: not bomb out with an error when
- * tests/http.test: the current directory is not
- * tests/fileName.test: writable...
- * tests/env.test:
+ * tclProc.c (SetLambdaFromAny):
+ * tests/apply.test (9.1-9.2): plugged intrep leak [Bug 1578454],
+ found by mjanssen.
-2002-07-05 Jeff Hobbs <jeffh@ActiveState.com>
+2006-10-16 Andreas Kupries <andreask@activestate.com>
- *** 8.4b1 TAGGED FOR RELEASE ***
+ * generic/tclBasic.c: Moved TIP#219 cleanup to DeleteInterpProc.
-2002-07-04 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2006-10-16 Daniel Steffen <das@users.sourceforge.net>
- * tests/cmdMZ.test (cmdMZ-1.4):
- * tests/cmdAH.test: More fixing of writable-current-dir assumption.
- [Bug 575824]
+ * changes: updates for 8.5a5 release.
-2002-07-04 Miguel Sofer <msofer@users.sourceforge.net>
+ * unix/tclUnixThrd.c (TclpThreadGetStackSize): Darwin: fix for main
+ thread, where pthread_get_stacksize_np() returns incorrect info.
- * tests/basic.test: Same issue as below; fixed [Bug 575817]
+ * macosx/GNUmakefile: don't redo prebinding of non-prebound binaires.
-2002-07-04 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+2006-10-16 Don Porter <dgp@users.sourceforge.net>
- * tests/socket.test:
- * tests/winPipe.test:
- * tests/pid.test: Fixed [Bug 575848]. See below for a description the
- general problem.
+ * generic/tclPkg.c (ExactRequirement): Plugged memory leak. Also
+ changed Tcl_Alloc()/Tcl_Free() calls to ckalloc()/ckfree() for easier
+ memory debugging in the future. [Bug 1568373]
- All the bugs below are instances of the same problem: The testsuite
- assumes [pwd] = [temporaryDirectory] and writable.
+ * library/tcltest/tcltest.tcl: Revise tcltest bump to 2.3a1.
+ * library/tcltest/pkgIndex.tcl: This permits more features to be
+ * unix/Makefile.in: added to tcltest before we reach version 2.3.0
+ * win/Makefile.in: best timed to match the release of Tcl 8.5.0.
+ * win/makefile.vc: This also serves as a demo of TIP 268 features
- * tests/iogt.test: Fixed [Bug 575860]
- * tests/io.test: Fixed [Bug 575862]
- * tests/exec.test:
- * tests/ioCmd.test: Fixed [Bug 575836]
+2006-10-13 Colin McCormack <coldstore@users.sf.net>
-2002-07-03 Don Porter <dgp@users.sourceforge.net>
+ * win/tclWinFile.c: corrected erroneous attempt to protect against
+ NULL return from Tcl_FSGetNormalizedPath per [Bug 1548263] causing
+ [Bug 1575837].
+ * win/tclWinFile.c: alfredd supplied patch to fix [Bug 1575837]
- * tests/pkg1/direct1.tcl: removed
- * tests/pkg1/pkgIndex.tcl: removed
- * tests/pkgMkIndex.test: Imported auxilliary files from tests/pkg1
- into the test file pkgMkIndex.test itself. Formatting fixes.
+2006-10-13 Daniel Steffen <das@users.sourceforge.net>
- * unix/Makefile.in: removed tests/pkg/* from `make dist`
+ * unix/tclUnixThrd.c (TclpThreadGetStackSize): on Darwin, use
+ * unix/tcl.m4: pthread_get_stacksize_np() API to get thread stack size
+ * unix/configure: autoconf-2.59
+ * unix/tclConfig.h.in: autoheader-2.59
- * tests/pkg/circ1.tcl: removed
- * tests/pkg/circ2.tcl: removed
- * tests/pkg/circ3.tcl: removed
- * tests/pkg/global.tcl: removed
- * tests/pkg/import.tcl: removed
- * tests/pkg/pkg1.tcl: removed
- * tests/pkg/pkg2_a.tcl: removed
- * tests/pkg/pkg2_b.tcl: removed
- * tests/pkg/pkg3.tcl: removed
- * tests/pkg/pkg4.tcl: removed
- * tests/pkg/pkg5.tcl: removed
- * tests/pkg/pkga.tcl: removed
- * tests/pkg/samename.tcl: removed
- * tests/pkg/simple.tcl: removed
- * tests/pkg/spacename.tcl: removed
- * tests/pkg/std.tcl: removed
- * tests/pkgMkIndex.test: Fixed [Bug 575857] where this test file
- expected to be able to write to [file join [testsDirectory] pkg]. Part
- of the fix was to import several auxilliary files into the test file
- itself.
+2006-10-12 Miguel Sofer <msofer@users.sf.net>
- * tests/main.test: Cheap fix for [Bugs 575851, 575858]. Avoid
- * tests/tcltest.test: non-writable . by [cd [temporaryDirectory]].
+ * generic/tclInterp.c (ApplyObjCmd):
+ * tests/interp.test (interp-14.5-10): made [interp alias] use the
+ ensemble rewrite machinery to produce better error messages [Bug
+ 1576006]
- * library/auto.tcl: Fix [tcl_findLibrary] to be sure it sets $varName
- only if a successful library script is found. [Bug 577033]
+2006-10-12 David Gravereaux <davygrvy@pobox.com>
-2002-07-03 Miguel Sofer <msofer@users.sourceforge.net>
+ * win/nmakehlp.c: Replaced all wnsprintf() calls with snprintf().
+ wnsprintf was not in my shwlapi header file (VC++6)
- * generic/tclCompCmds.c (TclCompileCatchCmd): return
- TCL_OUT_LINE_COMPILE instead of TCL_ERROR: let the failure happen at
- runtime so that it can be caught [Bug 577015].
+2006-10-11 Don Porter <dgp@users.sourceforge.net>
-2002-07-02 Joe English <jenglish@users.sourceforge.net>
+ * generic/tclPkg.c (Tcl_PackageRequireEx): Corrected crash when
+ argument version=NULL passed in.
- * doc/tcltest.n: Markup fixes, spellcheck.
+2006-10-10 Don Porter <dgp@users.sourceforge.net>
-2002-07-02 Don Porter <dgp@users.sourceforge.net>
+ * changes: Updates for 8.5a5 release.
- * doc/tcltest.n: more refinements of the documentation.
+ * generic/tclNamespace.c (TclTeardownNamespace): After the
+ commandPathSourceList of a namespace is cleared, set the
+ commandPathSourceList to NULL so we don't try to walk the list a
+ second time, possibly after it is freed. [Bug 1566526]
+ * tests/namespace.test (namespace-51.16): Added test.
- * library/tcltest/tcltest.tcl: Added trace to be sure the stdio
- constraint is updated whenever the [interpreter] changes.
+2006-10-09 Miguel Sofer <msofer@users.sf.net>
- * doc/tcltest.n: Reverted [makeFile] and [viewFile] to
- * library/tcltest/tcltest.tcl: their former behavior, and documented
- * tests/cmdAH.test: it. Corrected misspelling of hook
- * tests/event.test: procedure. Restored tests.
- * tests/http.test:
- * tests/io.test:
+ * doc/UpVar.3: brough the docs in accordance to the code. Ever since
+ 8.0, Tcl_UpVar(2)? accepts TCL_NAMESPACE_ONLY as a flag value, and
+ var-3.4 tests for proper behaviour. The docs only allowed 0 and
+ TCL_GLOBAL_ONLY. [Bug 1574099]
- * library/tcltest/tcltest.tcl: Simplified logic of [GetMatchingFiles]
- and [GetMatchingDirectories], removing special case processing.
+2006-10-09 Miguel Sofer <msofer@users.sf.net>
- * doc/tcltest.n: More documentation updates. Reference sections are
- complete. Only examples need adding.
+ * tests/*.test: updated all tests to refer explicitly to the global
+ variables ::errorInfo, ::errorCode, ::env and ::tcl_platform: many
+ were relying on the alternative lookup in the global namespace, that
+ feature is tested specifically in namespace and variable tests.
-2002-07-02 Vince Darley <vincentdarley@users.sourceforge.net>
+ The modified testfiles are: apply.test, basic.test, case.test,
+ cmdIL.test, cmdMZ.test, compExpr-old.test, error.test, eval.test,
+ event.test, expr.test, fileSystem.test, for.test, http.test, if.test,
+ incr-old.test, incr.test, interp.test, io.test, ioCmd.test, load.test,
+ misc.test, namespace.test, parse.test, parseOld.test, pkg.test,
+ proc-old.test, set.test, switch.test, tcltest.test, thread.test,
+ var.test, while-old.test, while.test.
- * tests/fCmd.test:
- * generic/tclCmdAH.c: clearer error msgs for 'file link', as per the
- man page.
+2006-10-06 Pat Thoyts <patthoyts@users.sourceforge.net>
-2002-07-01 Joe English <jenglish@users.sourceforge.net>
+ * win/rules.vc: [Bug 1571954] avoid /RTCc flag with MSVC8
- * doc/Access.3:
- * doc/AddErrInfo.3:
- * doc/Alloc.3:
- * doc/Backslash.3:
- * doc/CrtChannel.3:
- * doc/CrtSlave.3:
- * doc/Encoding.3:
- * doc/Eval.3:
- * doc/FileSystem.3:
- * doc/Notifier.3:
- * doc/OpenFileChnl.3:
- * doc/ParseCmd.3:
- * doc/RegExp.3:
- * doc/Tcl_Main.3:
- * doc/Thread.3:
- * doc/TraceCmd.3:
- * doc/Utf.3:
- * doc/WrongNumArgs.3:
- * doc/binary.n:
- * doc/clock.n:
- * doc/expr.n:
- * doc/fconfigure.n:
- * doc/glob.n:
- * doc/http.n:
- * doc/interp.n:
- * doc/lsearch.n:
- * doc/lset.n:
- * doc/msgcat.n:
- * doc/packagens.n:
- * doc/pkgMkIndex.n:
- * doc/registry.n:
- * doc/resource.n:
- * doc/safe.n:
- * doc/scan.n:
- * doc/tclvars.n: Spell-check, fixed typos (Updates from Larry Virden)
+2006-10-06 Pat Thoyts <patthoyts@users.sourceforge.net>
-2002-07-01 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * doc/binary.n: TIP #275: Support unsigned values in binary
+ * generic/tclBinary.c: command. Tests and documentation updated.
+ * tests/binary.test:
- * unix/tcl.m4 (SC_CONFIG_CFLAGS): Made Solaris use gcc for linking
- when building with gcc to resolve problems with undefined symbols
- being present when tcl library used with non-gcc linker at later
- stage. Symbols were compiler-generated, so it is the compiler's
- business to define them. [Bug 541181]
+2006-10-05 Andreas Kupries <andreask@activestate.com>
-2002-07-01 Don Porter <dgp@users.sourceforge.net>
+ * library/tm.tcl: Fixed bug in TIP #189 implementation, now allowing
+ '_' in module names.
- * doc/tcltest.n: more work in progress updating tcltest docs.
+2006-10-05 Jeff Hobbs <jeffh@ActiveState.com>
- * library/tcltest/tcltest.tcl: Change [configure -match] to stop
- treating an empty list as a list of the single pattern "*". Changed
- the default value to [list *] so default operation remains the same.
+ * library/http/http.tcl (http::geturl): only do geturl url rfc 3986
+ validity checking if $::http::strict is true (default true for 8.5).
+ [Bug 1560506]
- * tests/pkg/samename.tcl: restored. Needed by pkgMkIndex.test.
+ * generic/tcl.h: note limitation on changing Tcl_UniChar size
+ * generic/tclEncoding.c (UtfToUnicodeProc, UnicodeToUtfProc):
+ * tests/encoding.test (encoding-16.1): fix alignment issues in
+ unicode <> utf conversion procs. [Bug 1122671]
- * library/tcltest/tcltest.tcl: restored writeability testing of
- -tmpdir, augmented by a special exception for the deafault value.
+2006-10-05 Miguel Sofer <msofer@users.sf.net>
-2002-07-01 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclVar.c (Tcl_LappendObjCmd):
+ * tests/append.test(4.21-22): fix for longstanding [Bug 1570718],
+ lappending nothing to non-list. Reported by lvirden
- * doc/concat.n: Documented the *real* behaviour of [concat]!
+2006-10-04 Kevin B. Kenny <kennykb@acm.org>
-2002-06-30 Don Porter <dgp@users.sourceforge.net>
+ * tzdata/: Olson's tzdata2006m.
- * doc/tcltest.n: more work in progress updating tcltest docs.
+2006-10-01 Kevin B. Kenny <kennykb@acm.org>
- * tests/README: Updated the instructions on running and
- * tests/cmdMZ.test: adding to the test suite. Also updated
- * tests/encoding.test: several tests, mostly to correctly create
- * tests/fCmd.test: and destroy any temporary files in the
- * tests/info.test: [temporaryDirectory] of tcltest.
- * tests/interp.test:
+ * tests/clock.test (clock-49.2): Removed a locale dependency that
+ caused a spurious failure in the German locale. [Bug 1567956]
- * library/tcltest/tcltest.tcl: Stopped checking for writeability of
- -tmpdir value because no default directory can be guaranteed to be
- writeable.
+2006-10-01 Miguel Sofer <msofer@users.sf.net>
- * tests/autoMkindex.tcl: removed.
- * tests/pkg/samename.tcl: removed.
- * tests/pkg/magicchar.tcl: removed.
- * tests/pkg/magicchar2.tcl: removed.
- * tests/autoMkindex.test: Updated auto_mkIndex tests to use [makeFile]
- and [removeFile] so tests are done in [temporaryDirecotry] where write
- access is guaranteed.
+ * doc/Eval.3 (TclEvalObjv): added note on refCount management for the
+ elements of objv. [Bug 730244]
- * library/tcltest/tcltest.tcl: Fixed [makeFile] and [viewFile] to
- * tests/cmdAH.test: accurately reflect a file's contents.
- * tests/event.test: Updated tests that depended on buggy
- * tests/http.test: behavior. Also added warning messages
- * tests/io.test: to "-debug 1" operations to debug test
- * tests/iogt.test: calls to (make|remove)(File|Directory).
+2006-10-01 Pat Thoyts <patthoyts@users.sourceforge.net>
- * unix/mkLinks: `make mklinks` on 6-27 commits.
+ * win/tclWinFile.c: Handle possible missing define.
-2002-06-28 Miguel Sofer <msofer@users.sourceforge.net>
+ * win/tclWinFile.c (TclpUtime): [Bug 1420432] file mtime fails for
+ * tests/cmdAH.test: directories on windows
- * generic/tclCompile.h: modified the macro TclEmitPush to not call its
- first argument repeatedly or pass it to other macros, [Bug 575194]
- reported by Peter Spjuth.
+ * tests/winFile.test: Handle Msys environment a little differently in
+ getuser function. [Bug 1567956]
-2002-06-28 Don Porter <dgp@users.sourceforge.net>
+2006-09-30 Miguel Sofer <msofer@users.sf.net>
- * docs/tcltest.n: Doc revisions in progress.
- * library/tcltest/tcltest.tcl: Corrected -testdir default value. Was
- not reliable, and disagreed with docs! Thanks to Hemang Lavana. [Bug
- 575150]
+ * generic/tclUtil.c (Tcl_SplitList): optimisation, [Patch 1344747] by
+ dgp.
-2002-06-28 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclInt.decls:
+ * generic/tclInt.h:
+ * generic/tclIntDecls.h:
+ * generic/tclObj.c:
+ * generic/tclStubInit.c: added an internal function TclObjBeingDeleted
+ to provide info as to the reason for the loss of an internal rep. [FR
+ 1512138]
- * unix/tclUnixThrd.c: Renamed the Tcl_Platform* #defines to
- * unix/tclUnixPipe.c: TclOS* because they are only used
- * unix/tclUnixFile.c: internally. Also stopped double-#def
- * unix/tclUnixFCmd.c: of TclOSlstat [Bug 566099, post-rename]
- * unix/tclUnixChan.c:
- * unix/tclUnixPort.h:
+ * generic/tclCompile.c:
+ * generic/tclHistory.c:
+ * generic/tclInt.h:
+ * generic/tclProc.c: made Tcl_RecordAndEvalObj not call "history" if
+ it has been redefined to an empty proc, in order to reduce the noise
+ when debugging [FR 1190441]. Moved TclCompileNoOp from tclProc.c to
+ tclCompile.c
- * doc/string.n: Improved documentation for [string last] along lines
- described in [Bug 574799] so it indicates that the supplied index
- marks the end of the search space.
+2006-09-28 Andreas Kupries <andreask@activestate.com>
-2002-06-27 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclPkg.c (CompareVersions): Bugfix. Check string lengths
+ * tests/pkg.test: before comparison. The shorter string is the smaller
+ number. Added testcases as well. Interestingly all existing test cases
+ for vcompare compared numbers of the same length with each other. [Bug
+ 1563836]
- * doc/dde.n: Work in progress updating the documentation
- * doc/http.n: of the packages that come bundled with
- * doc/msgcat.n: the Tcl source distribution, notably tcltest.
- * doc/registry.n:
- * doc/tcltest.n:
+2006-09-28 Miguel Sofer <msofer@users.sf.net>
- * library/tcltest/tcltest.tcl: Made sure that the TCLTEST_OPTIONS
- environment variablle configures tcltest at package load time.
+ * generic/tclIO.c (Tcl_GetsObj): added two test'n'panic guards for
+ possible NULL derefs, [Bug 1566382] and coverity #33.
-2002-06-26 Vince Darley <vincentdarley@users.sourceforge.net>
+2006-09-27 Don Porter <dgp@users.sourceforge.net>
- * tests/fileSystem.test:
- * generic/tclIOUtil.c: fix to handling of empty paths "" which are not
- claimed by any filesystem [Bug 573758]. Ensure good error messages are
- given in all cases.
- * tests/cmdAH.test:
- * unix/tclUnixFCmd.c: fix to bug reported as part of [Patch 566669].
- Thanks to Taguchi, Takeshi for the report.
+ * generic/tclExecute.c: Corrected error in INST_LSHIFT in the
+ * tests/expr.test: calculation done to determine whether a shift
+ in the (long int) type is possible. The calculation had literal value
+ "1" where it needed a value "1L" to compute the correct result. Error
+ detected via testing with the math::bigfloat package [Bug 1567222]
-2002-06-26 Reinhard Max <max@suse.de>
+ * generic/tclPkg.c (CompareVersion): Flatten strcmp() results to
+ {-1, 0, 1} to match expectations of CompareVersion() callers.
- * unix/tclUnixTime.c: Make [clock format] respect locale settings.
- * tests/clock.test: [Bug 565880]. ***POTENTIAL INCOMPATIBILITY***
+2006-09-27 Miguel Sofer <msofer@users.sf.net>
-2002-06-26 Miguel Sofer <msofer@users.sourceforge.net>
+ * generic/regc_color.c (singleton):
+ * generic/regc_cvec.c (addmcce):
+ * generic/regcomp.c (compile, dovec): the static function addmcce does
+ nothing when called with two NULL pointers; the only call is by
+ compile with two NULL pointers (regcomp.c #includes regc_cvec.c).
+ Large parts (all?) the code for mcce (multi character collating
+ element) that we do not use is ifdef'ed out with the macro
+ REGEXP_MCCE_ENABLE.
+ This silences coverity bugs 7, 16, 80
- * doc/CrtInterp.3:
- * doc/StringObj.3: clarifications by Don Porter, [Bugs 493995, 500930]
+ * generic/regc_color.c (uncolorchain):
+ * generic/regc_nfa.c (freearc): changed tests and asserts to
+ equivalent formulation, designed to avoid an explicit comparison to
+ NULL and satisfy coverity that 6 and 9 are not bugs.
-2002-06-24 Don Porter <dgp@users.sourceforge.net>
+2006-09-27 Andreas Kupries <andreask@activestate.com>
- * library/tcltest/tcltest.tcl: Corrected suppression of -verbose skip
- * tests/tcltest.test: and start by [test -output]. Also
- corrected test suite errors exposed by corrected code. [Bug 564656]
+ * tests/pkg.test: Added test for version comparison at the 32bit
+ boundary. [Bug 1563836]
-2002-06-25 Reinhard Max <max@suse.de>
+ * generic/tclPkg.c: Rewrote CompareVersion to perform string
+ comparison instead of numeric. This breaks through the 32bit limit on
+ version numbers. See code for details (handling of leading zeros,
+ signs, etc.). un-CONSTed some arguments of CompareVersions,
+ RequirementSatisfied, and AllRequirementsSatisfied. The new compare
+ modifies the string (temporary string terminators). All callers use
+ heap-allocated ver-intreps, so we are good with that. [Bug 1563836]
- * unix/tcl.m4: New macro SC_CONFIG_MANPAGES.
- * unix/configure.in: Added support for symlinks and compression
- * unix/Makefile.in: when installing the manpages. [Patch 518052]
- * unix/mkLinks.tcl: Default is still hardlinks and no compression.
+2006-09-27 Miguel Sofer <msofer@users.sf.net>
- * unix/mkLinks: generated
- * unix/configure:
+ * generic/tclFileName.c (TclGlob): added a panic for a call with
+ TCL_GLOBMODE_TAILS and pathPrefix==NULL. This would cause a segfault,
+ as found by coverity #26.
- * unix/README: Added documentation for the new features.
+2006-09-26 Kevin B. Kenny <kennykb@acm.org>
- * unix/tcl.m4 (SC_PATH_TCLCONFIG): Replaced ${exec_prefix}/lib by
- ${libdir}.
+ * doc/Encoding.3: Added covariant 'const' qualifier for the
+ * generic/tcl.decls: Tcl_EncodingType argument to
+ * generic/tclEncoding.c: Tcl_CreateEncoding. [Further TIP#27 work.]
+ * generic/tclDecls.h: Reran 'make genstubs'.
-2002-06-25 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2006-09-26 Pat Thoyts <patthoyts@users.sourceforge.net>
- * generic/tclUtil.c (TclGetIntForIndex): Fix of critical [Bug 533364]
- generated when the index is bad and the result is a shared object. The
- T_ASTO(T_GOR, ...) idiom likely exists elsewhere though. Also removed
- some cruft that just complicated things to no advantage.
- (SetEndOffsetFromAny): Same fix, though this wasn't on the path
- excited by the bug.
+ * win/makefile.vc: Additional compiler flags and amd64 support.
+ * win/nmakehlp.c:
+ * win/rules.vc:
-2002-06-24 Don Porter <dgp@users.sourceforge.net>
+2006-09-26 Don Porter <dgp@users.sourceforge.net>
- * library/tcltest/tcltest.tcl: Implementation of TIP 101. Adds
- * tests/parseOld.test: and exports a [configure] command
- * tests/tcltest.test: from tcltest.
+ * generic/tcl.h: As 2006-09-22 commit from Donal K. Fellows
+ demonstrates, "#define NULL 0" is just wrong, and as a quotable chat
+ figure observed, "If NULL isn't defined, we're not using a C compiler"
+ Improper fallback definition of NULL removed.
-2002-06-22 Don Porter <dgp@users.sourceforge.net>
+2006-09-25 Pat Thoyts <patthoyts@users.sourceforge.net>
- * changes: updated changes file for 8.4b1 release.
+ * generic/tcl.h: More fixing which struct stat to refer to.
+ * generic/tclGetDate.y: Some casts from time_t to int required.
+ * generic/tclTimer.c: Tcl_Time structure members are longs.
+ * win/makefile.vc: Support for varying compiler options
+ * win/rules.vc: and build to platform-specific subdirs.
- * library/tcltest/tcltest.tcl: Corrections to tcltest and the
- * tests/basic.test: Tcl test suite so that a test
- * tests/cmdInfo.test: with options -constraints knownBug
- * tests/compile.test: -limitConstraints 1 only tests the
- * tests/encoding.test: knownBug tests. Mostly involves
- * tests/env.test: replacing direct access to the
- * tests/event.test: testConstraints array with calls
- * tests/exec.test: to the testConstraint command
- * tests/execute.test: (which requires tcltest version 2)
- * tests/fCmd.test:
- * tests/format.test:
- * tests/http.test:
- * tests/httpold.test:
- * tests/ioUtil.test:
- * tests/link.test:
- * tests/load.test:
- * tests/namespace.test:
- * tests/pkgMkIndex.test:
- * tests/reg.test:
- * tests/result.test:
- * tests/scan.test:
- * tests/stack.test:
+2006-09-25 Andreas Kupries <andreask@activestate.com>
-2002-06-22 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclIO.c (Tcl_StackChannel): Fixed [Bug 1564642], aka
+ coverity #51. Extended loop condition, added checking for NULL to
+ prevent seg.fault.
- * tools/tcl.wse.in (Disk Label), unix/tcl.spec (version):
- * win/README.binary, README, win/configure.in, unix/configure.in:
- * generic/tcl.h (TCL_RELEASE_*, TCL_PATCH_LEVEL): Bump to beta1.
+2006-09-25 Andreas Kupries <andreask@activestate.com>
-2002-06-21 Joe English <jenglish@users.sourceforge.net>
+ * doc/package.n: Fixed nits reported by Daniel Steffen in the TIP#268
+ changes.
- * generic/tclCompExpr.c:
- * generic/tclParseExpr.c: LogSyntaxError() should reset the
- interpreter result [Bug 550142 "Tcl_ExprObj -> abort"]
+2006-09-25 Kevin B. Kenny <kennykb@acm.org>
-2002-06-21 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclNotify.c (Tcl_DeleteEvents): Simplified the code in hopes
+ of making the invariants clearer and proving to Coverity that the
+ event queue memory is managed correctly.
- * unix/Makefile.in: Updated all package install directories to
- * win/Makefile.in: match current Major.minor versions of the
- * win/makefile.bc: packages. Added tcltest package to
- * win/makefile.vc: installation on Windows.
+2006-09-25 Donal K. Fellows <dkf@users.sf.net>
- * library/init.tcl: Corrected comments and namespace style issues.
- Thanks to Bruce Stephens. [Bug 572025]
+ * generic/tclNotify.c (Tcl_DeleteEvents): Make it clear what happens
+ when the event queue is mismanaged. [Bug 1564677], coverity bug #10.
-2002-06-21 Vince Darley <vincentdarley@users.sourceforge.net>
+2006-09-24 Miguel Sofer <msofer@users.sf.net>
- * tests/cmdAH.test: Added TIP#99 implementation of 'file
- * tests/fCmd.test: link'. Supports creation of symbolic and
- * tests/fileName.test: hard links in the native filesystems and
- * tests/fileSystem.test: in vfs's, when the individual filesystem
- * generic/tclTest.c: supports the concept.
- * generic/tclCmdAH.c:
- * generic/tclIOUtil.c:
- * generic/tcl.h:
- * generic/tcl.decls:
- * doc/FileSystem.3:
- * doc/file.n:
- * mac/tclMacFile.c:
- * unix/tclUnixFile.c:
- * win/tclWinFile.c: Also enhanced speed of 'file normalize' on Windows
+ * generic/tclParse.c (Tcl_ParseCommand): also return an error if
+ start==NULL and numBytes<0. This is coverity's bug #20
-2002-06-20 Miguel Sofer <msofer@users.sourceforge.net>
+ * generic/tclStringObj.c (STRING_SIZE): fix allocation for 0-length
+ strings. This is coverity's bugs #54-5
- * generic/tclBasic.c (TclEvalObjvInternal): fix for [Bug 571385] in
- the implementation of TIP#62 (command tracing). Vince Darley, Hemang
- Lavana & Don Porter: thanks.
+2006-09-22 Andreas Kupries <andreask@activestate.com>
-2002-06-20 Miguel Sofer <msofer@users.sourceforge.net>
+ * generic/tclInt.h: Moved TIP#268's field 'packagePrefer' to the end
+ of the structure, for better backward compatibility.
- * generic/tclExecute.c (TclCompEvalObj): clarified and simplified the
- logic for compilation/recompilation.
+2006-09-22 Andreas Kupries <andreask@activestate.com>
-2002-06-19 Joe English <jenglish@users.sourceforge.net>
+ TIP#268 IMPLEMENTATION
- * doc/file.n: Fixed indentation. No substantive changes.
+ * generic/tclDecls.h: Regenerated from tcl.decls.
+ * generic/tclStubInit.c:
-2002-06-19 Jeff Hobbs <jeffh@ActiveState.com>
+ * doc/PkgRequire.3: Documentation of extended API, extended testsuite.
+ * doc/package.n:
+ * tests/pkg.test:
- * generic/tclCmdMZ.c (Tcl_RegexpObjCmd): get the resultPtr again as
- the Tcl_ObjSetVar2 may cause the result to change.
- [Patch 558324] (watson)
+ * generic/tcl.decls: Implementation.
+ * generic/tclBasic.c:
+ * generic/tclConfig.c:
+ * generic/tclInt.h:
+ * generic/tclPkg.c:
+ * generic/tclTest.c:
+ * generic/tclTomMathInterface.c:
+ * library/init.tcl:
+ * library/package.tcl:
+ * library/tm.tcl:
-2002-06-19 Miguel Sofer <msofer@users.sourceforge.net>
+2006-09-22 Donal K. Fellows <donal.k.fellows@man.ac.uk>
- * generic/tclExecute.c (TEBC): removing unused "for(;;)" loop;
- improved comments; re-indentation.
+ * generic/tclThreadTest.c (TclCreateThread): Use NULL instead of 0 as
+ end-of-strings marker to Tcl_AppendResult; the difference matters on
+ 64-bit machines. [Bug 1562528]
-2002-06-18 Miguel Sofer <msofer@users.sourceforge.net>
+2006-09-21 Don Porter <dgp@users.sourceforge.net>
- * generic/tclExecute.c (TEBC):
- - elimination of duplicated code in the non-immediate INST_INCR
- instructions.
- - elimination of 103 (!) TclDecrRefCount macros. The different
- instructions now jump back to a common "DecrRefCount zone" at the
- top of the loop. The macro "ADJUST_PC" was replaced by two macros
- "NEXT_INST_F" and "NEXT_INST_V" that take three params
- (pcAdjustment, # of stack objects to discard, resultObjPtr handling
- flag). The only instructions that retain a TclDecrRefCount are
- INST_POP (for speed), the common code for the non-immediate
- INST_INCR, INST_FOREACH_STEP and the two INST_LSET.
+ * generic/tclUtil.c: Dropped ParseInteger() routine. TclParseNumber
+ covers the task just fine.
- The object size of tclExecute.o was reduced by approx 20% since the
- start of the consolidation drive, while making room for some peep-hole
- optimisation at runtime.
+2006-09-19 Donal K. Fellows <dkf@users.sf.net>
-2002-06-18 Miguel Sofer <msofer@users.sourceforge.net>
+ * generic/tclEvent.c (Tcl_VwaitObjCmd): Rewrite so that an exceeded
+ limit trapped in a vwait cannot cause a dangerous dangling trace.
- * generic/tclExecute.c (TEBC, INST_DONE): small bug in the panic code
- for tcl-stack corruption.
+2006-09-19 Don Porter <dgp@users.sourceforge.net>
-2002-06-17 David Gravereaux <davygrvy@pobox.com>
+ * generic/tclExecute.c (INST_EXPON): Native type overflow detection
+ * tests/expr.test: was completely broken. Falling back on use of
+ bignums for all non-trivial ** calculations until
+ native-type-constrained special cases can be done carefully and
+ correctly. [Bug 1561260]
- Trims to support the removal of RESOURCE_INCLUDED from rc scripts from
- [FRQ 565088].
+2006-09-15 Jeff Hobbs <jeffh@ActiveState.com>
- * generic/tcl.h: moved the #ifndef RC_INVOKED start block up in the
- file. rc scripts don't need to know thread mutexes.
+ * library/http/http.tcl: Change " " -> "+" url encoding mapping
+ * library/http/pkgIndex.tcl: to " " -> "%20" as per RFC 3986.
+ * tests/http.test (http-5.1): bump http to 2.5.3
+ * unix/Makefile.in:
+ * win/Makefile.in:
- * win/tcl.rc:
- * win/tclsh.rc: removed the #define RESOURCE_INCLUDED to let the
- built-in -DRC_INVOKED to the work.
+2006-09-12 Andreas Kupries <andreask@activestate.com>
-2002-06-17 Jeff Hobbs <jeffh@ActiveState.com>
+ * unix/configure.in (HAVE_MTSAFE_GETHOST*): Modified to recognize
+ HP-UX 11.00 and beyond as having mt-safe implementations of the
+ gethost functions.
+ * unix/configure: Regenerated, using autoconf 2.59
- * doc/CrtTrace.3: Added TIP#62 implementation of command
- * doc/trace.n: execution tracing [FRQ 462580] (lavana).
- * generic/tcl.h: This includes enter/leave tracing as well
- * generic/tclBasic.c: as inter-procedure stepping.
- * generic/tclCmdMZ.c:
- * generic/tclCompile.c:
- * generic/tclExecute.c:
- * generic/tclInt.decls:
- * generic/tclInt.h:
- * generic/tclIntDecls.h:
- * generic/tclStubInit.c:
- * generic/tclVar.c:
- * tests/trace.test:
+ * unix/tclUnixCompat.c (PadBuffer): Fixed bug in calculation of the
+ increment needed to align the pointer, and added documentation
+ explaining why the macro is implemented as it is.
-2002-06-17 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+2006-09-11 Pat Thoyts <patthoyts@users.sourceforge.net>
- * win/tclWinPipe.c (BuildCommandLine): Fixed [bug 554068] ([exec] on
- windows did not treat { in filenames well.). Bug reported by Vince
- Darley <vincentdarley@users.sourceforge.net>, patch provided by Vince
- too.
+ * win/rules.vc: Updated to install http, tcltest and msgcat as
+ * win/makefile.vc: Tcl Modules (as per Makefile.in).
+ * win/makefile.vc: Added tommath_(super)class headers.
-2002-06-17 Joe English <jenglish@users.sourceforge.net>
+2006-09-11 Andreas Kupries <andreask@activestate.com>
- * generic/tcl.h: #ifdef logic for K&R C backwards compatibility
- changed to assume modern C by default. See [FRQ 565088] for full
- details.
+ * unix/Makefile.in (install-libraries): Fixed typo tcltest 2.3.9 ->
+ 2.3.0.
-2002-06-17 Don Porter <dgp@users.sourceforge.net>
+2006-09-11 Daniel Steffen <das@users.sourceforge.net>
- * doc/msgcat.n: Corrected en_UK references to en_GB. UK is not a
- country designation recognized in ISO 3166.
+ * unix/tclUnixCompat.c: make compatLock static and only declare it
+ when it will actually be used; #ifdef parts of TSD that are not always
+ needed; adjust #ifdefs to cover all possible cases; fix whitespace.
- * library/msgcat/msgcat.tcl: More Windows Registry locale codes from
- Bruno Haible.
+2006-09-11 Andreas Kupries <andreask@activestate.com>
+ * tests/msgcat.test: Bumped version in auxiliary files as well.
* doc/msgcat.n:
- * library/msgcat/msgcat.tcl:
- * library/msgcat/pkgIndex.tcl:
- * tests/msgcat.test: Revised locale initialization to interpret
- environment variable locale values according to XPG4, and to recognize
- the LC_ALL and LC_MESSAGES values over that of LANG. Also added many
- Windows Registry locale values to those recognized by msgcat. Revised
- tests and docs. Bumped to version 1.3. Thanks to Bruno Haible for the
- report and assistance crafting the solution. [Bug 525522, 525525]
-
-2002-06-16 Miguel Sofer <msofer@users.sourceforge.net>
-
- * generic/tclCompile.c (TclCompileTokens): a better algorithm for the
- previous bug fix.
-2002-06-16 Miguel Sofer <msofer@users.sourceforge.net>
+2006-09-11 Kevin B. Kenny <kennykb@acm.org>
- * generic/tclCompile.c (TclCompileTokens):
- * tests/compile.test: [Bug 569438] in the processing of dollar
- variables; report by Georgios Petasis.
+ * unix/Makefile.in: Bumped msgcat version to 1.4.2 to be
+ * win/Makefile.in: consistent with dgp's commits of 2006-09-10.
-2002-06-16 Miguel Sofer <msofer@users.sourceforge.net>
+2006-09-11 Don Porter <dgp@users.sourceforge.net>
- * generic/tclExecute.c: bug in the consolidation of the INCR_..._STK
- instructions; the bug could not be exercised as the (faulty)
- instruction INST_INCR_ARRAY_STK was never compiled-in (related to [Bug
- 569438]).
+ * library/msgcat/msgcat.tcl: Removed some unneeded [uplevel]s.
-2002-06-14 Miguel Sofer <msofer@users.sourceforge.net>
+2006-09-10 Don Porter <dgp@users.sourceforge.net>
- * generic/tclExecute.c (TclExecuteByteCode): runtime peep-hole
- optimisation of variables (INST_STORE, INST_INCR) and commands
- (INST_INVOKE); faster check for the existence of a catch.
- (TclExecuteByteCode): runtime peep-hole optimisation of comparisons.
- (TclExecuteByteCode): runtime peep-hole optimisation of INST_FOREACH -
- relies on peculiarities of the code produced by the bytecode compiler.
+ * generic/tclExecute.c: Corrected INST_EXPON flaw that treated
+ * tests/expr.test: $x**1 as $x**3. [Bug 1555371]
-2002-06-14 David Gravereaux <davygrvy@pobox.com>
-
- * win/rules.vc: The test for compiler optimizations was in error.
- Thanks goes to Roy Terry <royterry@earthlink.net> for his assistance
- with this.
-
-2002-06-14 Donal K. Fellows <fellowsd@cs.man.ac.uk>
-
- * doc/trace.n, tests/trace.test:
- * generic/tclCmdMZ.c (Tcl_TraceObjCmd,TclTraceCommandObjCmd)
- (TclTraceVariableObjCmd): Changed references to "trace list" to "trace
- info" as mandated by TIP#102.
-
-2002-06-13 Miguel Sofer <msofer@users.sourceforge.net>
-
- * generic/tclExecute.c (TclExecuteByteCode): consolidated code for the
- conditional branch instructions.
-
-2002-06-13 Miguel Sofer <msofer@users.sourceforge.net>
-
- * generic/tclExecute.c (TclExecuteByteCode): fixed the previous
- patch - wouldn't compile with TCL_COMPILE_DEBUG set.
-
-2002-06-13 Miguel Sofer <msofer@users.sourceforge.net>
-
- * generic/tclExecute.c (TclExecuteByteCode): consolidated the handling
- of exception returns to INST_INVOKE and INST_EVAL, as well as most of
- the code for INST_CONTINUE and INST_BREAK, in the new jump target
- "processExceptionReturn".
+ * doc/tcltest.n: Bump to version tcltest 2.3.0 to
+ * library/tcltest/pkgIndex.tcl: account for new "-verbose line"
+ * library/tcltest/tcltest.tcl: feature.
+ * unix/Makefile.in:
+ * win/Makefile.in:
+ * win/makefile.bc:
+ * win/makefile.vc:
-2002-06-13 Miguel Sofer <msofer@users.sourceforge.net>
+ * library/msgcat/msgcat.tcl: Bump to version msgcat 1.4.2 to
+ * library/msgcat/pkgIndex.tcl: account for modifications.
- * generic/tclExecute.c (TclExecuteByteCode): consolidated variable
- handling opcodes, replaced redundant code with some 'goto'. All
- store/append/lappend opcodes on the same data type now share the main
- code; same with incr opcodes.
- * generic/tclVar.c: added the bit TCL_TRACE_READS to the possible
- flags to Tcl_SetVar2Ex - it causes read traces to be fired prior to
- setting the variable. This is used in the core for [lappend].
+2006-09-10 Daniel Steffen <das@users.sourceforge.net>
- ***NOTE*** the usage of TCL_TRACE_READS in Tcl_(Obj)?GetVar.* is not
- documented; there, it causes the call to create the variable if it
- does not exist. The new usage in Tcl_(Obj)?SetVar.* remains
- undocumented too ...
+ * library/msgcat/msgcat.tcl (msgcat::Init): on Darwin, add fallback of
+ * tests/msgcat.test: default msgcat locale to
+ * unix/tclUnixInit.c (TclpSetVariables): current CFLocale
+ identifier if available (via private ::tcl::mac::locale global, set at
+ interp init when on Mac OS X 10.3 or later with CoreFoundation).
-2002-06-13 Vince Darley <vincentdarley@users.sourceforge.net>
+ * library/tcltest/tcltest.tcl: add 'line' verbose level: prints source
+ * doc/tcltest.n: file line information of failing tests.
- * tests/fCmd.test:
- * tests/winFile.test:
- * tests/fileSystem.test:
- * generic/tclTest.c:
- * generic/tclCmdAH.c:
- * generic/tclIOUtil.c:
- * doc/FileSystem.3:
- * mac/tclMacFile.c:
- * unix/tclUnixFile.c:
- * win/tclWinFile.c: fixed up further so both compiles and actually
- works with VC++ 5 or 6.
- * win/tclWinInt.h:
- * win/tclWin32Dll.c: cleaned up code and vfs tests and added tests for
- the internal changes of 2002-06-12, to see whether WinTcl on NTFS can
- coexist peacefully with links in the filesystem. Added new test
- command 'testfilelink' to enable the newer code to be tested.
- * tests/fCmd.test: (made certain tests of 'testfilelink' not run on
- unix).
+ * macosx/Tcl.xcodeproj/project.pbxproj: add new tclUnixCompat.c file;
+ revise tests target to use new tcltest 'line' verbose level.
-2002-06-12 Miguel Sofer <msofer@users.sourceforge.net>
+ * unix/configure.in: add descriptions to new AC_DEFINEs for MT-safe.
+ * unix/tcl.m4: add caching to new SC_TCL_* macros for MT-safe wrappers
+ * unix/configure: autoconf-2.59
+ * unix/tclConfig.h.in: autoheader-2.59
- * tclBasic.c (Tcl_DeleteTrace): fixed [Bug 568123] (thanks to
- Hemang Lavana)
+2006-09-08 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
-2002-06-12 Jeff Hobbs <jeffh@ActiveState.com>
+ * unix/tclUnixCompat.c: Added fallback to gethostbyname() and
+ gethostbyaddr() if the implementation is known to be MT-safe
+ (currently for Darwin 6 or later only).
- * win/tclWinFile.c: corrected the symbolic link handling code to
- allow it to compile. Added real definition of REPARSE_DATA_BUFFER
- (found in winnt.h). Most of the added definitions appear to have
- correct, cross-Win-version equivalents in winnt.h and should be
- removed, but just making things "work" for now.
+ * unix/configure.in: Assume gethostbyname() and gethostbyaddr() are
+ MT-safe starting with Darwin 6 (Mac OSX 10.2).
-2002-06-12 Vince Darley <vincentdarley@users.sourceforge.net>
+ * unix/configure: Regenerated with autoconf V2.59
- * generic/tclIOUtil.c:
- * generic/tcl.decls:
- * generic/tclDecls.h: made code for Tcl_FSNewNativePath agree with man
- pages.
+2006-09-08 Andreas Kupries <andreask@activestate.com>
- * doc/FileSystem.3: clarified the circumstances under which certain
- functions are called in the presence of symlinks.
+ * unix/tclUnixCompat.c: Fixed conditions for CopyArray/CopyString, and
+ CopyHostent. Also fixed bad var names in TclpGetHostByName.
- * win/tclWinFile.c:
- * win/tclWinPort.h:
- * win/tclWinInt.h:
- * win/tclWinFCmd.c: Fix for Windows to allow 'file lstat', 'file
- type', 'glob -type l', 'file copy', 'file delete', 'file normalize',
- and all VFS code to work correctly in the presence of symlinks
- (previously Tcl's behaviour was not very well defined). This also
- fixes possible serious problems in all versions of WinTcl where 'file
- delete' on a NTFS symlink could delete the original, not the symlink.
- Note: symlinks cannot yet be created in pure Tcl.
+2006-09-07 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
-2002-06-11 Miguel Sofer <msofer@users.sourceforge.net>
+ * unix/tclUnixCompat.c: Added fallback to MT-unsafe library calls if
+ TCL_THREADS is not defined.
+ Fixed alignment of arrays copied by CopyArray() to be on the
+ sizeof(char *) boundary.
- * generic/tclBasic.c:
- * generic/tclCompCmds.c:
- * generic/tclInt.h: reverted the new compilation functions; replaced
- by a more general approach described below.
+2006-09-07 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
- * generic/tclCompCmds.c:
- * generic/tclCompile.c: made *all* compiled variable access attempts
- create an indexed variable - even get or incr without previous set.
- This allows indexed access to local variables that are created and set
- at runtime, for example by [global], [upvar], [variable], [regexp],
- [regsub].
+ * unix/tclUnixChan.c: Rewritten MT-safe wrappers to return ptrs to
+ * unix/tclUnixCompat.c: TSD storage making them all look like their
+ * unix/tclUnixFCmd.c: MT-unsafe pendants API-wise.
+ * unix/tclUnixPort.h:
+ * unix/tclUnixSock.c:
-2002-06-11 Miguel Sofer <msofer@users.sourceforge.net>
+2006-09-06 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
- * doc/global.n:
- * doc/info.n:
- * test/info.test:
- * generic/tclCmdIL.c: fix for [Bug 567386], [info locals] was
- reporting some linked variables.
+ * unix/tclUnixChan.c: Added TCL_THREADS ifdef'ed usage of MT-safe
+ * unix/tclUnixFCmd.c: calls like: getpwuid, getpwnam, getgrgid,
+ * unix/tclUnixSock.c: getgrnam, gethostbyname and gethostbyaddr.
+ * unix/tclUnixPort.h: See [Bug 999544]
+ * unix/Makefile.in:
+ * unix/configure.in:
+ * unix/tcl.m4:
+ * unix/configure: Regenerated.
- * generic/tclBasic.c:
- * generic/tclCompCmds.c:
- * generic/tclInt.h: added compile functions for [global], [variable]
- and [upvar]. They just declare the new local variables, the commands
- themselves are not compiled-in. This gives a notably faster read
- access to these linked variables.
+ * unix/tclUnixCompat.c: New file containing MT-safe implementation of
+ some library calls.
-2002-06-11 Miguel Sofer <msofer@users.sourceforge.net>
+2006-09-04 Don Porter <dgp@users.sourceforge.net>
- * generic/tclExecute.c: optimised algorithm for exception range
- lookup; part of [Patch 453709].
+ * generic/tclCompExpr.c: Removed much complexity that is no
+ longer needed.
-2002-06-10 Vince Darley <vincentdarley@users.sourceforge.net>
+ * tests/main.text (Tcl_Main-4.4): Test corrected to not be
+ timing sensitive to the Bug 1481986 fix. [Bug 1550858]
- * unix/tclUnixFCmd.c: fixed [Bug 566669]
- * generic/tclIOUtil.c: improved and sped up handling of native paths
- (duplication and conversion to normalized paths), particularly on
- Windows.
- * modified part of above commit, due to problems on Linux. Will
- re-examine bug report and evaluate more closely.
+2006-09-04 Jeff Hobbs <jeffh@ActiveState.com>
-2002-06-07 Don Porter <dgp@users.sourceforge.net>
+ * doc/package.n: correct package example
- * tests/tcltest.test: More corrections to test suite so that tests of
- failing [test]s don't show up themselves as failing tests.
+2006-08-31 Don Porter <dgp@users.sourceforge.net>
-2002-06-07 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclCompExpr.c: Corrected flawed logic for disabling
+ the INST_TRY_CVT_TO_NUMERIC instruction at the end of an expression
+ when function arguments contain operators. [Bug 1541274]
- * generic/tclExecute.c: Tidied up headers in relation to float.h to
- cut the cruft and ensure DBL_MAX is defined since doubles seem to be
- the same size everywhere; if the assumption isn't true, the variant
- platforms had better have run configure...
+ * tests/expr-old.test: The remaining failing tests reported in
+ * tests/expr.test: [Bug 1381715] are all new in Tcl 8.5, so
+ there's really no issue of compatibility with Tcl 8.4 result to deal
+ with. Fixed by updating tests to expect 8.5 results.
- * unix/tclUnixPort.h (EOVERFLOW): Added code to define it if it wasn't
- previously defined. Also some other general tidying and adding of
- comments. [Bugs 563122, 564595]
- * compat/tclErrno.h: Added definition for EOVERFLOW copied from
- Solaris headers; I've been unable to find any uses of EFTYPE, which
- was the error code previously occupying the slot, in Tcl, or any
- definition of it in the Solaris headers.
+2006-08-29 Don Porter <dgp@users.sourceforge.net>
-2002-06-06 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tclParseExpr.c: Dropped the old expr parser.
- * unix/dltest/Makefile.in: Remove hard coded CFLAGS=-g and add
- CFLAGS_DEBUG, CFLAGS_OPTIMIZE, and CFLAGS_DEFAULT varaibles. [Bug
- 565488]
+2006-08-30 Jeff Hobbs <jeffh@ActiveState.com>
-2002-06-06 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclBasic.c (Tcl_CreateInterp): init iPtr->threadId
- * tests/tcltest.test: Corrections to test suite so that tests of
- failing [test]s don't show up themselves as failing tests.
+ * win/tclWinChan.c [Bug 819667] Improve logic for identifying COM
+ ports.
- * tests/io.test: Fixed up namespace variable resolution issues
- revealed by running test suite with "-singleproc 1".
+ * generic/tclIOGT.c (ExecuteCallback):
+ * generic/tclPkg.c (Tcl_PkgRequireEx): replace Tcl_GlobalEval(Obj)
+ with more efficient Tcl_Eval(Obj)Ex
- * doc/tcltest.n:
- * library/tcltest/tcltest.tcl:
- * tests/tcltest.test: Several updates to tcltest.
- 1) changed to lazy initialization of test constraints
- 2) deprecated [initConstraintsHook]
- 3) repaired badly broken [limitConstraints].
- 4) deprecated [threadReap] and [mainThread]
- [Patch 512214, Bug 558742, Bug 461000, Bug 534903]
+ * unix/Makefile.in (valgrindshell): add valgrindshell target and
+ update default VALGRINDARGS. User can override, or add to it with
+ VALGRIND_OPTS env var.
-2002-06-06 Daniel Steffen <das@users.sourceforge.net>
+ * generic/tclFileName.c (DoGlob): match incrs with decrs.
- * unix/tclUnixThrd.c (TclpReaddir, TclpLocaltime, TclpGmtime):
- added mutex wrapped calls to readdir, localtime & gmtime in case their
- thread-safe *_r counterparts are not available.
- * unix/tcl.m4: added configure check for readdir_r
- * unix/tcl.m4 (Darwin): set TCL_DEFAULT_ENCODING to utf-8 on MacOSX
- (where posix file apis expect utf-8, not iso8859-1).
- * unix/configure: regen
- * unix/Makefile.in: set DYLD_LIBRARY_PATH in parallel to
- LD_LIBRARY_PATH for MacOSX dynamic linker.
- * generic/tclEnv.c (TclSetEnv): fix env var setting on MacOSX. Adapted
- from [Patch 524352] (jkbonfield).
+2006-08-29 Don Porter <dgp@users.sourceforge.net>
-2002-06-05 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclParseExpr.c: Use the "parent" field of orphan
+ ExprNodes to store the closure of left pointers. This lets us avoid
+ repeated re-scanning leftward for the left boundary of subexpressions,
+ which in worst case led to near O(N^2) runtime.
- * doc/Tcl_Main.3: Documented $tcl_rcFileName and added more
- clarifications about the intended use of Tcl_Main(). [Bug 505651]
+2006-08-29 Joe Mistachkin <joe@mistachkin.com>
-2002-06-05 Daniel Steffen <das@users.sourceforge.net>
+ * unix/tclUnixInit.c: Fixed the issue (typo) that was causing
+ * unix/tclUnixThrd.c (TclpThreadGetStackSize): stack.test to fail on
+ FreeBSD (and possibly other Unix platforms).
- * generic/tclFileName.c (TclGlob): mac specific fix to recent changes
- in 'glob -tails' handling.
- * mac/tclMacPort.h:
- * mac/tclMacChan.c: fixed TIP#91 bustage.
- * mac/tclMacResource.c (Tcl_MacConvertTextResource): added utf
- conversion of text resource contents.
- * tests/macFCmd.test (macFCmd-1.2): allow CWIE creator.
+2006-08-29 Colin McCormack <coldstore@users.sourceforge.net>
-2002-06-04 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclIOUtil.c: Added test for NULL return from
+ * generic/tclPathObj.c: Tcl_FSGetNormalizedPath which was causing
+ * unix/tclUnixFile.c: segv's per [Bug 1548263]
+ * win/tclWinFCmd.c:
+ * win/tclWinFile.c:
- * library/tcltest/tcltest.tcl:
- * tests/init.test:
- * tests/tcltest.test: Added more TIP 85 tests from Arjen Markus.
- Converted tcltest.test to use a private namespace. Fixed bugs in
- [tcltest::Eval] revealed by calling [tcltest::test] from a non-global
- namespace, and namespace errors in init.test.
+2006-08-28 Kevin B. Kenny <kennykb@acm.org>
-2002-06-04 Mo DeJong <mdejong@users.sourceforge.net>
+ * library/tzdata/America/Havana: Regenerated from Olson's
+ * library/tzdata/America/Tegucigalpa: tzdata2006k.
+ * library/tzdata/Asia/Gaza:
- * win/README: Update msys+mingw URL.
+2006-08-28 Don Porter <dgp@users.sourceforge.net>
-2002-06-03 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclStringObj.c: Revised ObjPrintfVA to take care to
+ * generic/tclParseExpr.c: copy only whole characters when doing
+ %s formatting. This relieves callers of TclObjPrintf() and
+ TclFormatToErrorInfo() from needing to fix arguments to character
+ boundaries. Tcl_ParseExpr() simplified by taking advantage. [Bug
+ 1547786]
- * doc/tcltest.n:
- * library/tcltest/tcltest.tcl:
- * library/tcltest/pkgIndex.tcl:
- * tests/tcltest.test: Implementation of TIP 85. Allows tcltest users
- to add new legal values of the -match option to [test], associating
- each with a Tcl command that does the matching of expected results
- with actual results of tests. Thanks to Arjen Markus. => tcltest 2.1
- [Patch 521362]
+ * generic/tclStringObj.c: Corrected TclFormatObj's failure to
+ count up the number of arguments required by examining the format
+ string. [Bug 1547681]
-2002-06-03 Miguel Sofer <msofer@users.sourceforge.net>
+2006-08-27 Joe Mistachkin <joe@mistachkin.com>
- * doc/namespace.n: added description of [namepace forget] behaviour
- for unqualified patterns [Bug 559268]
+ * generic/tclClock.c (ClockClicksObjCmd): Fix nested macro breakage
+ with TCL_MEM_DEBUG enabled. [Bug 1547662]
-2002-06-03 Miguel Sofer <msofer@users.sourceforge.net>
+2006-08-26 Miguel Sofer <msofer@users.sf.net>
- * generic/tclExecute.c: reverting an accidental modification in the
- last commit.
+ * doc/namespace.n:
+ * generic/tclNamesp.c:
+ * tests/upvar.test: bugfix, docs clarification and new tests for
+ [namespace upvar] as follow up to [Bug 1546833], reported by Will
+ Duquette.
-2002-06-03 Miguel Sofer <msofer@users.sourceforge.net>
+2006-08-24 Kevin B. Kenny <kennykb@acm.org>
- * doc/Tcl.n: clarify the empty variable name issue ([Bug 549285]
- reported by Tom Krehbiel, patch by Don Porter).
+ * library/tzdata: Regenerated, including several new files, from
+ Olson's tzdata2006j.
+ * library/clock.tcl:
+ * tests/clock.test: Removed an early testing hack that allowed loading
+ 'registry' from the build tree rather than an installed one. This is a
+ workaround for [Bug 15232730], which remains open because it's a
+ symptom of a deeper underlying problem.
-2002-05-31 Don Porter <dgp@users.sourceforge.net>
+2006-08-23 Don Porter <dgp@users.sourceforge.net>
- * library/package.tcl: Fixed leak of slave interp in [pkg_mkIndex].
- Thanks to Helmut for report. [Bug 550534]
+ * generic/tclParseExpr.c: Minimal collection of new tests
+ * tests/parseExpr.test: testing the error messages of the new
+ expr parser. Several bug fixes and code simplifications that appeared
+ during that effort.
- * tests/io.test:
- * tests/main.test: Use the "stdio" constraint to control whether an
- [open "|[interpreter]"] is attempted.
-
- * generic/tclExecute.c (TclMathInProgress,TclExecuteByteCode
- (ExprCallMathFunc):
- * generic/tclInt.h (TclMathInProgress):
- * unix/Makefile.in (tclMtherr.*):
- * unix/configure.in (NEED_MATHERR):
- * unix/tclAppInit.c (matherr):
- * unix/tclMtherr.c (removed file):
- * win/tclWinMtherr.c (_matherr): Removed internal routine
- TclMathInProgress and Unix implementation of matherr(). These are now
- obsolete, dealing with very old versions of the C math library.
- Windows version is retained in case Borland compilers require it, but
- it is inactive. Thanks to Joe English. [Bug 474335, Patch 555635]
- * unix/configure: regen
-
-2002-05-30 Miguel Sofer <msofer@users.sourceforge.net>
+2006-08-21 Don Porter <dgp@users.sourceforge.net>
- * generic/tclCompExpr.c:
- * generic/tclCompile.c:
- * generic/tclCompile.h: removed exprIsJustVarRef and
- exprIsComparison from the ExprInfo and CompileEnv structs. These were
- set, but not used since dec 1999 [Bug 562383].
+ * generic/tclIOUtil.c: Revisions to complete the thread finalization
+ of the cwdPathPtr. [Bug 1536142]
-2002-05-30 Vince Darley <vincentdarley@users.sourceforge.net>
+ * generic/tclParseExpr.c: Revised mistaken call to
+ TclCheckBadOctal(), so both [expr 08] and [expr 08z] have same
+ additional info in error message.
- * generic/tclFileName.c (TclGlob): fix to longstanding 'knownBug' in
- fileName tests 15.2-15.4, and fix to a new Tcl 8.4 bug in certain uses
- of 'glob -tails'.
- * tests/fileName.test: removed 'knownBug' flag from some tests, added
- some new tests for above bugs.
+ * tests/compExpr-old.test: Update existing tests to not fail with
+ * tests/compExpr.test: the new expr parser.
+ * tests/compile.test:
+ * tests/expr-old.test:
+ * tests/expr.test:
+ * tests/for.test:
+ * tests/if.test:
+ * tests/parseExpr.test:
+ * tests/while.test:
-2002-05-29 Jeff Hobbs <jeffh@ActiveState.com>
+2006-08-21 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * unix/configure: regen'ed
- * unix/configure.in: replaced bigendian check with autoconf standard
- AC_C_BIG_ENDIAN, which defined WORDS_BIGENDIAN on bigendian systems.
- * generic/tclUtf.c (Tcl_UniCharNcmp):
- * generic/tclInt.h (TclUniCharNcmp): use WORDS_BIGENDIAN instead of
- TCL_OPTIMIZE_UNICODE_COMPARE to enable memcmp alternative.
+ * win/Makefile.in (gdb): Make this target work so that debugging an
+ msys build is possible.
- * generic/tclExecute.c (TclExecuteByteCode INST_STR_CMP):
- * generic/tclCmdMZ.c (Tcl_StringObjCmd): changed the case for choosing
- the Tcl_UniCharNcmp compare to when both objs are of StringType, as
- benchmarks show that is the optimal check (both bigendian and
- littleendian systems).
+2006-08-21 Daniel Steffen <das@users.sourceforge.net>
-2002-05-29 Don Porter <dgp@users.sourceforge.net>
+ * macosx/tclMacOSXNotify.c (Tcl_WaitForEvent): if the run loop is
+ already running (e.g. if Tcl_WaitForEvent was called recursively),
+ re-run it in a custom run loop mode containing only the source for the
+ notifier thread, otherwise wakeups from other sources added to the
+ common run loop modes might get lost.
- * generic/tclMain.c: Removed "dummy" reference to Tcl_LinkVar. It is
- no longer needed since Tcl_Main() now actually calls Tcl_LinkVar().
- Thanks to Joe English for pointing that out.
+ * unix/tclUnixNotfy.c (Tcl_WaitForEvent): on 64-bit Darwin,
+ pthread_cond_timedwait() appears to have a bug that causes it to wait
+ forever when passed an absolute time which has already been exceeded
+ by the system time; as a workaround, when given a very brief timeout,
+ just do a poll on that platform. [Bug 1457797]
-2002-05-29 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclClock.c (ClockClicksObjCmd): add support for Darwin
+ * generic/tclCmdMZ.c (Tcl_TimeObjCmd): nanosecond resolution timer
+ * generic/tclInt.h: to [clock clicks] and [time]
+ * unix/configure.in (Darwin): when TCL_WIDE_CLICKS defined
+ * unix/tclUnixTime.c (TclpGetWideClicks, TclpWideClicksToNanoseconds):
+ * unix/configure: autoconf-2.59
+ * unix/tclConfig.h.in: autoheader-2.59
- * generic/tclExecute.c (TclExecuteByteCode):
- * generic/tclCmdMZ.c (Tcl_StringObjCmd): Use the macro version.
- * generic/tclInt.h (TclUniCharNcmp): Optimised still further with a
- macro for use in sensitive places like tclExecute.c
+ * unix/tclUnixPort.h (Darwin): override potentially faulty configure
+ detection of termios availability in all cases, since termios is known
+ to be present on all Mac OS X releases since 10.0. [Bug 497147]
- * generic/tclUtf.c (Tcl_UniCharNcmp): Use new flag to figure out when
- we can use an optimal comparison scheme, and default to the old scheme
- in other cases which is at least safe.
- * unix/configure.in (TCL_OPTIMIZE_UNICODE_COMPARE): New optional flag
- that indicates when we can use memcmp() to compare Unicode strings
- (i.e. when the high-byte of a Tcl_UniChar precedes the low-byte.)
+2006-08-18 Daniel Steffen <das@users.sourceforge.net>
-2002-05-29 Jeff Hobbs <jeffh@ActiveState.com>
+ * unix/tcl.m4 (Darwin): add support for --enable-64bit on x86_64, for
+ universal builds including x86_64, for 64-bit CoreFoundation on
+ Leopard and for use of -mmacosx-version-min instead of
+ MACOSX_DEPLOYMENT_TARGET
+ * unix/configure: autoconf-2.59
+ * unix/tclConfig.h.in: autoheader-2.59
- * generic/tclInt.decls:
- * generic/tclIntDecls.h:
- * generic/tclStubInit.c:
- * generic/tclUtf.c: added TclpUtfNcmp2 private command that mirrors
- Tcl_UtfNcmp, but takes n in bytes, not utf-8 chars. This provides a
- faster alternative for comparing utf strings internally.
- (Tcl_UniCharNcmp, Tcl_UniCharNcasecmp): removed the explicit end of
- string check as it wasn't correct for the function (by doc and logic).
-
- * generic/tclCmdMZ.c (Tcl_StringObjCmd): reworked the string equal
- comparison code to use TclpUtfNcmp2 as well as short-circuit for equal
- objects or unequal length strings in the equal case. Removed the use
- of goto and streamlined the other parts.
-
- * generic/tclExecute.c (TclExecuteByteCode): added check for object
- equality in the comparison instructions. Added short-circuit for !=
- length strings in INST_EQ, INST_NEQ and INST_STR_CMP. Reworked
- INST_STR_CMP to use TclpUtfNcmp2 where appropriate, and only use
- Tcl_UniCharNcmp when at least one of the objects is a Unicode obj with
- no utf bytes.
-
- * generic/tclCompCmds.c (TclCompileStringCmd): removed error creation
- in code that no longer throws an error.
+ * generic/tcl.h: add fixes for building on Leopard and
+ * unix/tclUnixPort.h: support for 64-bit CoreFoundation on Leopard
+ * macosx/tclMacOSXFCmd.c:
- * tests/string.test:
- * tests/stringComp.test: added more string comparison checks.
+ * unix/tclUnixPort.h: on Darwin x86_64, disable use of vfork as it
+ causes execve to fail intermittently. (rdar://4685553)
- * tests/clock.test: better qualified 9.1 constraint check for %s.
+ * generic/tclTomMath.h: on Darwin 64-bit, for now disable use of
+ 128-bit arithmetic through __attribute__ ((mode(TI))), as it leads to
+ link errors due to missing fallbacks. (rdar://4685527)
-2002-05-28 Jeff Hobbs <jeffh@ActiveState.com>
+ * macosx/Tcl.xcodeproj/project.pbxproj: add x86_64 to universal build,
+ switch native release targets to use DWARF with dSYM, Xcode 3.0
+ changes
+ * macosx/README: updates for x86_64 and Xcode 2.4.
- * generic/tclThreadAlloc.c (TclpRealloc, TclpFree): protect against
- the case when NULL is based.
+ * macosx/Tcl.xcodeproj/default.pbxuser: add test suite target that
+ * macosx/Tcl.xcodeproj/project.pbxproj: runs the tcl test suite at
+ build time and shows clickable test suite errors in the GUI build
+ window.
- * tests/clock.test: added clock-9.1
- * compat/strftime.c:
- * generic/tclClock.c:
- * generic/tclInt.decls:
- * generic/tclIntDecls.h:
- * unix/tclUnixTime.c: fix for Windows msvcrt mem leak caused by using
- an env(TZ) setting trick for in clock format -gmt 1. This also makes
- %s seem to work correctly with -gmt 1 as well as making it a lot
- faster by avoid the env(TZ) hack. TclpStrftime now takes useGMT as an
- arg. [Bug 559376]
-
-2002-05-28 Vince Darley <vincentdarley@users.sourceforge.net>
-
- * generic/tclIOUtil.c: fixes to Tcl_FSLoadFile when called on a file
- inside a vfs. This should avoid leaving temporary files sitting around
- on exit. [Bug 545579]
-
-2002-05-27 Donal K. Fellows <fellowsd@cs.man.ac.uk>
-
- * win/tclWinError.c: Added comment on conversion of
- ERROR_NEGATIVE_SEEK because that is a mapping that really belongs, and
- not a catch-all case.
- * win/tclWinPort.h (EOVERFLOW): Should be either EFBIG or EINVAL
- * generic/tclPosixStr.c (Tcl_ErrnoId, Tcl_ErrnoMsg): EOVERFLOW can
- potentially be a synonym for EINVAL.
-
-2002-05-24 Donal K. Fellows <fellowsd@cs.man.ac.uk>
-
- === Changes due to TIP#91 ===
-
- * win/tclWinPort.h: Added declaration of EOVERFLOW.
- * doc/CrtChannel.3: Added documentation of wideSeekProc.
- * generic/tclIOGT.c (TransformSeekProc, TransformWideSeekProc):
- Adapted to use the new channel mechanism.
- * unix/tclUnixChan.c (FileSeekProc, FileWideSeekProc): Renamed
- FileSeekProc to FileWideSeekProc and created new FileSeekProc which
- has the old-style interface and which errors out with EOVERFLOW when
- the returned file position can't fit into the return type (int for
- historical reasons.)
- * win/tclWinChan.c (FileSeekProc, FileWideSeekProc): Renamed
- FileSeekProc to FileWideSeekProc and created new FileSeekProc which
- has the old-style interface and which errors out with EOVERFLOW when
- the returned file position can't fit into the return type (int for
- historical reasons.)
- * mac/tclMacChan.c (FileSeek): Reverted to old interface; Macs lack
- large-file support because I can't see how to add it.
- * generic/tclIO.c (Tcl_Seek, Tcl_Tell): Given these functions
- knowledge of the new arrangement of channel types.
- (Tcl_ChannelVersion): Added recognition of new version code.
- (HaveVersion): New function to do version checking.
- (Tcl_ChannelBlockModeProc, Tcl_ChannelFlushProc)
- (Tcl_ChannelHandlerProc): Made these functions use HaveVersion for
- ease of future maintainability.
- (Tcl_ChannelBlockModeProc): Obvious lookup function.
- * generic/tcl.h (Tcl_ChannelType): New wideSeekProc field, and
- seekProc type restored to old interpretation.
- (TCL_CHANNEL_VERSION_3): New channel version.
-
-2002-05-24 Andreas Kupries <andreas_kupries@users.sourceforge.net>
-
- * tests/winPipe.test: Applied patch for [Bug 549617]. Patch and bug
- report by Kevin Kenny <kennykb@users.sourceforge.net>.
-
- * win/tclWinSock.c (TcpWatchProc): Fixed [Bug 557878]. We are not
- allowed to mess with the watch mask if the socket is a server socket.
- I believe that the original reporter is George Peter Staplin.
-
-2002-05-21 Mo DeJong <mdejong@users.sourceforge.net>
-
- * unix/configure: Regen.
- * unix/configure.in: Invoke SC_ENABLE_SHARED before calling
- SC_CONFIG_CFLAGS so that the SHARED_BUILD variable can be checked
- inside SC_CONFIG_CFLAGS.
- * unix/tcl.m4 (SC_CONFIG_CFLAGS): Pass -non_shared instead of -shared
- to ld when configured with --disable-shared under OSF. [Bug 540390]
-
-2002-05-20 Daniel Steffen <das@users.sourceforge.net>
-
- * generic/tclInt.h: added prototype for TclpFilesystemPathType().
- * mac/tclMacChan.c: use MSL provided creator type if available instead
- of the default 'MPW '.
-
-2002-05-16 Joe English <jenglish@users.sf.net>
-
- * doc/CrtObjCmd.3: Added Tcl_GetCommandFromObj, Tcl_GetCommandFullName
- [Bugs 547987, 414921]
-
-2002-05-14 Donal K. Fellows <fellowsd@cs.man.ac.uk>
-
- * unix/tclUnixChan.c (TtyOutputProc): #if/#endif-ed this function out
- to stop compiler warnings. Also much general tidying of comments in
- this file and removal of whitespace from blank lines.
-
-2002-05-13 Donal K. Fellows <fellowsd@cs.man.ac.uk>
-
- * unix/tclUnixChan.c (SETBREAK): Solaris thinks ioctl() takes a signed
- second argument, and Linux thinks ioctl() takes an unsigned second
- argument. So need a longer definition of this macro to get neither to
- spew warnings...
-
-2002-05-13 Vince Darley <vincentdarley@users.sourceforge.net>
-
- * generic/tclEvent.c:
- * generic/tclIOUtil.c:
- * generic/tclInt.h: clean up all memory allocated by the filesystem,
- via introduction of 'TclFinalizeFilesystem'. Move TclFinalizeLoad into
- TclFinalizeFilesystem so we can be sure it is called at just the right
- time. Fix bad comment also. [Bug 555078 and 'fs' part of 543549]
- * win/tclWinChan.c: fix comment referring to wrong function.
+ * tests/macOSXFCmd.test: fix use of deprecated resource fork paths.
-2002-05-10 Don Porter <dgp@users.sourceforge.net>
+ * unix/tclUnixInit.c (TclpInitLibraryPath): move code that is only
+ needed when TCL_LIBRARY is defined to run only in that case.
- * tests/load.test:
- * tests/safe.test:
- * tests/tcltest.test: Corrected some list-quoting issues and other
- matters that cause tests to fail when the patch includes special
- characters. Report from Vince Darley. [Bug 554068].
+ * generic/tclLink.c (LinkTraceProc): fix 64-bit signed-with-unsigned
+ comparison warning from gcc4 -Wextra.
-2002-05-08 David Gravereaux <davygrvy@pobox.com>
+ * unix/tclUnixChan.c (TclUnixWaitForFile): with timeout < 0, if
+ select() returns early (e.g. due to a signal), call it again instead
+ of returning a timeout result. Fixes intermittent event-13.8 failures.
- * doc/file.n:
- * tools/man2tcl.c:
- * tools/man2help2.tcl: Thanks to Peter Spjuth <peter.spjuth@space.se>,
- again. My prior fix for single-quote macro mis-understanding was
- wrong. Reverted to reimpliment the 'macro2' proc which handles
- single-quote macros and restored file.n text arrangement to avoid
- single-quotes on the first line. Sorry for all the confusion.
+2006-08-17 Don Porter <dgp@users.sourceforge.net>
-2002-05-08 David Gravereaux <davygrvy@pobox.com>
+ * generic/tclCompile.c: Revised the new set of expression
+ * generic/tclParseExpr.c: parse error messages.
- * tools/man2tcl.c:
- * tools/man2help2.tcl: Proper source of macro error mis-understanding
- single-quote as the leading macro command found and repaired.
+2006-08-16 Don Porter <dgp@users.sourceforge.net>
- * doc/file.n: Reverted to prior state before I messed with it.
+ * generic/tclParseExpr.c: Replace PrecedenceOf() function with
+ prec[] static array.
-2002-05-08 Don Porter <dgp@users.sourceforge.net>
+2006-08-14 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * library/tcltest/tcltest.tcl: Corrected [uplevel] quoting when
- [source]-ing test script in subdirectories.
- * tests/fileName.test:
- * tests/load.test:
- * tests/main.test:
- * tests/tcltest.test:
- * tests/unixInit.test: Fixes to test suite when there's a space in the
- working path. Thanks to Kevin Kenny.
-
-2002-05-07 David Gravereaux <davygrvy@pobox.com>
-
- -- Changes from Peter Spjuth <peter.spjuth@space.se>
- * tools/man2tcl.c: Increased line buffer size and a bail-out if that
- should ever be over-run.
- * tools/man2help.tcl: Include Courier New font in rtf header.
- * tools/man2help2.tcl: Improved handling of CS/CE fields. Use Courier
- New for code samples and indent better.
-
- * doc/file.n:
- * doc/TraceCmd.3: winhelp conversion tools where understanding a ' as
- the first character on a line to be an unknown macro. Not knowing how
- to repair tools/man2tcl.c, I decided to rearrange the text in the docs
- instead.
-
-2002-05-07 Vince Darley <vincentdarley@users.sourceforge.net>
-
- * generic/tclFileName.c: fix to similar segfault when using
- 'glob -types nonsense -dir dirname -join * *'. [Bug 553320]
-
- * doc/FileSystem.3: further documentation on vfs.
- * tests/cmdAH.test:
- * tests/fileSystem.test:
- * tests/pkgMkindex.test: Fix to testsuite bugs when running out of
- directory whose name contains '{' or '['.
-
-2002-05-07 Miguel Sofer <msofer@users.sourceforge.net>
-
- * tests/basic.test: Fix for [Bug 549607]
- * tests/encoding.test: Fix for [Bug 549610]
- These are testsuite bugs that caused failures when the filename
- contained spaces. Report & fix by Kevin Kenny.
-
-2002-05-02 Vince Darley <vincentdarley@users.sourceforge.net>
-
- * generic/tclFileName.c: fix to freeing a bad object (i.e. segfault)
- when using 'glob -types nonsense -dir dirname'.
- * generic/tclWinFile.c: fix to [Bug 551306], also wrapped some long
- lines.
- * tests/fileName.test: added several tests for the above bugs.
- * doc/FileSystem.3: clarified documentation on refCount requirements
- of the object returned by the path type function.
- * generic/tclIOUtil.c:
- * win/tclWinFile.c:
- * unix/tclUnixFile.c:
- * mac/tclMacFile.c: moved TclpFilesystemPathType to the platform
- specific directories, so we can add missing platform-specific
- implementations. On Windows, 'file system' now returns useful results
- like "native NTFS", "native FAT" for that system. Unix and MacOS still
- only return "native".
- * doc/file.n: clarified documentation.
- * tests/winFile.test: test for 'file system' returning correct values.
- * tests/fileSystem.test: test for 'file system' returning correct
- values. Clean up after failed previous test run.
-
-2002-04-26 Jeff Hobbs <jeffh@ActiveState.com>
+ * library/clock.tcl (::tcl::clock::add): Added missing braces to
+ clockval validation code. Pointed out on comp.lang.tcl.
- * unix/configure:
- * unix/tcl.m4: change HP-11 SHLIB_LD_LIBS from "" to ${LIBS} so that
- the .sl knows its dependent libs.
+2006-08-11 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
-2002-04-26 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclNamesp.c: Improvements in buffer management to make
+ namespace creation faster. Plus selected other minor improvements to
+ code quality. [Patch 1352382]
- * tests/obj.test (obj-11.[56]): Test conversion to boolean more
- thoroughly.
- * generic/tclObj.c (SetBooleanFromAny): Was not calling an integer
- parsing function on native 64-bit platforms! [Bug 548686]
+2006-08-10 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
-2002-04-24 Jeff Hobbs <jeffh@ActiveState.com>
+ Misc patches to make code more efficient. [Bug 1530474] (afredd)
+ * generic/*.c, macosx/tclMacOSXNotify.c, unix/tclUnixNotfy.c,
+ * win/tclWinThrd.c: Tidy up invokations of Tcl_Panic() to promote
+ string constant sharing and consistent style.
+ * generic/tclBasic.c (Tcl_CreateInterp): More efficient handling of
+ * generic/tclClock.c (TclClockInit): registration of commands not
+ in global namespace.
+ * generic/tclVar.c (Tcl_UnsetObjCmd): Remove unreachable clause.
- * generic/tclInt.h: corrected TclRememberJoinableThread decl to use
- VOID instead of void.
- * generic/tclThreadJoin.c: noted that this code isn't needed on Unix.
+2006-08-09 Don Porter <dgp@users.sourceforge.net>
-2002-04-23 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclEncoding.c: Replace buffer copy in for loop with
+ call to memcpy(). Thanks to afredd. [Patch 1530262]
- * doc/exec.n:
- * doc/tclvars.n: doc updates [Patch 509426] (gravereaux)
+2006-08-09 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
-2002-04-24 Daniel Steffen <das@users.sourceforge.net>
+ * generic/tclCmdIL.c (Tcl_LassignObjCmd): Make the wrong#args message
+ a bit more consistent with those used elsewhere. [Bug 1534628]
- * mac/tclMacResource.r: added check of TCLTK_NO_LIBRARY_TEXT_RESOURCES
- #define to allow disabling the inclusion of the tcl library code in
- the resource fork of Tcl executables and shared libraries.
+ * generic/tclDictObj.c (DictForCmd): Stop crash when attempting to
+ iterate over an invalid dictionary. [Bug 1531184]
-2002-04-23 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * doc/ParseCmd.3, doc/expr.n, doc/set.n, doc/subst.n, doc/switch.n:
+ * doc/tclvars.n: Ensure that uses of [expr] in documentation examples
+ are also good style (with braces) unless otherwise necessary. [Bug
+ 1526581]
- * doc/TraceCmd.3: New file that documents Tcl_CommandTraceInfo,
- Tcl_TraceCommand and Tcl_UntraceCommand [Bug 414927]
+2006-08-03 Daniel Steffen <das@users.sourceforge.net>
-2002-04-22 Jeff Hobbs <jeffh@ActiveState.com>
+ * unix/tclUnixPipe.c (TclpCreateProcess): for USE_VFORK: ensure
+ standard channels are initialized before vfork() so that the child
+ doesn't potentially corrupt global state in the parent's address space
+
+ * tests/compExpr-old.test: add 'oldExprParser' constraint to all tests
+ * tests/compExpr.test: that depend on the exact format of the
+ * tests/compile.test: error messages of the pre-2006-07-05
+ * tests/expr-old.test: expression parser. The constraint is on by
+ * tests/expr.test: default (i.e those tests still fail), but
+ * tests/for.test: can be turned off by passing '-constraints
+ * tests/if.test: newExprParser' to tcltest, which will skip
+ * tests/parseExpr.test: the 196 failing tests in the testsuite that
+ * tests/while.test: are caused by the new expression parser
+ error messages.
- * generic/tclAlloc.c:
- * generic/tclInt.h:
- * generic/tclThreadAlloc.c (new):
- * unix/Makefile.in:
- * unix/tclUnixThrd.c:
- * win/Makefile.in:
- * win/tclWinInt.h:
- * win/tclWinThrd.c: added new threaded allocator contributed by AOL
- that significantly reduces lock contention when multiple threads are
- in use. Only Windows and Unix implementations are ready, and the
- Windows one may need work. It is only used by default on Unix for now,
- and requires that USE_THREAD_ALLOC be defined (--enable-threads on
- Unix will define this).
+2006-07-31 Kevin B. Kenny <kennykb@acm.org>
- * generic/tclIOUtil.c (Tcl_FSRegister, Tcl_FSUnregister): corrected
- calling of Tcl_ConditionWait to ensure that there would be a condition
- to wait upon.
+ * generic/tclClock.c (ConvertLocalToUTCUsingC): Corrected a regression
+ that caused dates before 1969 to be one day off in the :localtime time
+ zone if TZ is not set. [Bug 1531530]
- * generic/tclCmdAH.c (Tcl_FileObjCmd): added cast in FILE_SIZE.
+2006-07-30 Kevin B. Kenny <kennykb@acm.org>
- * win/tclWinFCmd.c (DoDeleteFile): check return of setattr API calls
- in file deletion for correct Win32 API handling.
+ * generic/tclClock.c (GetJulianDayFromEraYearMonthDay): Corrected
+ several errors in converting dates before the Common Era [Bug 1426279]
+ * library/clock.tcl: Corrected syntax errors in generated code for %EC
+ %Ey, and %W format groups [Bug 1505383]. Corrected a bug in cache
+ management for format strings containing [glob] metacharacters [Bug
+ 1494664]. Corrected several errors in formatting/scanning of years
+ prior to the Common Era, and added the missing %EE format group to
+ indicate the era.
+ * tools/makeTestCases.tcl: Added code to make sure that %U and %V
+ format groups are included in the tests. (The code depends on %U and
+ %V formatting working correctly when 'makeTestCases.tcl' is run,
+ rather than making a completely independent check.) Added tests for
+ [glob] metacharacters in strings. Added tests for years prior to the
+ Common Era.
+ * tests/clock.test: Rebuilt with new test cases for all the above.
- * win/Makefile.in: correct dependencies for shell, gdb, runtest
- targets.
+2006-07-30 Joe English <jenglish@users.sourceforge.net>
- * doc/clock.n:
- * compat/strftime.c (_fmt): change strftime to correctly handle
- localized %c, %x and %X on Windows. Added some notes about how the
- other values could be further localized.
+ * doc/AppInit.3: Fix typo [Bug 1496886]
-2002-04-19 Don Porter <dgp@users.sourceforge.net>
+2006-07-26 Don Porter <dgp@users.sourceforge.net>
- * generic/tclMain.c (Tcl_Main): Free the memory allocated for the
- startup script path. [Bug 543549]
+ * generic/tclExecute.c: Corrected flawed overflow detection in
+ * tests/expr.test: INST_EXPON that caused [expr 2**64] to return
+ 0 instead of the same value as [expr 1<<64].
- * library/msgcat/msgcat.tcl: [mcmax] wasn't using the caller's
- namespace when determining the max translated length. Also made
- revisions for better use of namespace variables and more efficient
- [uplevel]s.
+2006-07-24 Don Porter <dgp@users.sourceforge.net>
- * doc/msgcat.n:
- * library/msgcat/msgcat.tcl:
- * library/msgcat/pkgIndex.tcl: Added [mcload] to the export list of
- msgcat; bumped to 1.2.3. [Bug 544727]
+ * win/tclWinSock.c: Correct un-initialized Tcl_DString. Thanks to
+ afredd. [Bug 1518166]
-2002-04-20 Daniel Steffen <das@users.sourceforge.net>
+2006-07-21 Miguel Sofer <msofer@users.sf.net>
- * generic/tclInt.decls:
- * generic/tclIntPlatDecls.h:
- * generic/tclStubInit.c:
- * mac/tclMacFCmd.c:
- * mac/tclMacFile.c:
- * mac/tclMacUtil.c: Modified TclpObjNormalizePath to be alias file
- aware, and replaced various calls to FSpLocationFrom*Path by calls to
- new alias file aware versions FSpLLocationFrom*Path. The alias file
- aware routines don't resolve the last component of a path if it is an
- alias. This allows [file copy/delete] etc. to act correctly on alias
- files. (c.f. discussion in [Bug 511666])
+ * generic/tclExecute.c:
+ * tests/execute.test (execute-9.1): dgp's fix for [Bug 1522803].
-2002-04-19 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2006-07-20 Daniel Steffen <das@users.sourceforge.net>
- * tests/lindex.test (lindex-3.7):
- * generic/tclUtil.c (TclGetIntForIndex): Stopped indexes from hitting
- wide ints. [Bug 526717]
+ * macosx/tclMacOSXNotify.c (Tcl_InitNotifier, Tcl_WaitForEvent):
+ create notifier thread lazily upon first call to Tcl_WaitForEvent()
+ rather than in Tcl_InitNotifier(). Allows calling exeve() in processes
+ where the event loop has not yet been run (Darwin's execve() fails in
+ processes with more than one thread), in particular allows embedders
+ to call fork() followed by execve(), previously the pthread_atfork()
+ child handler's call to Tcl_InitNotifier() would immediately recreate
+ the notifier thread in the child after a fork.
-2002-04-18 Miguel Sofer <msofer@users.sourceforge.net>
+ * macosx/tclMacOSXFCmd.c (TclMacOSXCopyFileAttributes): add support
+ * macosx/tclMacOSXNotify.c (Tcl_InitNotifier): for weakly
+ * unix/tclUnixInit.c (Tcl_GetEncodingNameFromEnvironment): importing
+ symbols not available on OSX 10.2 or 10.3, enables binaires built on
+ later OSX versions to run on earlier ones.
+ * macosx/Tcl.xcodeproj/project.pbxproj: enable weak-linking; turn on
+ extra warnings.
+ * macosx/README: document how to enable weak-linking; cleanup.
+ * unix/tclUnixPort.h: add support for weak-linking; conditionalize
+ AvailabilityMacros.h inclusion; only disable realpath on 10.2 or
+ earlier when threads are enabled.
+ * unix/tclLoadDyld.c (TclpLoadMemoryGetBuffer): change runtime Darwin
+ * unix/tclUnixInit.c (TclpInitPlatform): release check to use
+ global initialized
+ once
+ * unix/tclUnixFCmd.c (DoRenameFile, TclpObjNormalizePath): add runtime
+ Darwin release check to determine if realpath is threadsafe.
+ * unix/configure.in: add check on Darwin for compiler support of weak
+ * unix/tcl.m4: import and for AvailabilityMacros.h header; move
+ Darwin specific checks & defines that are only relevant to the tcl
+ build out of tcl.m4; restrict framework option to Darwin; clean up
+ quoting and help messages.
+ * unix/configure: autoconf-2.59
+ * unix/tclConfig.h.in: autoheader-2.59
- * generic/tclNamesp.c:
- * tests/info.test: [Bug 545325] info level didn't report namespace
- eval, bug report by Richard Suchenwirth.
+ * generic/regc_locale.c (cclass):
+ * generic/tclExecute.c (TclExecuteByteCode):
+ * generic/tclIOCmd.c (Tcl_ExecObjCmd):
+ * generic/tclListObj.c (NewListIntRep):
+ * generic/tclObj.c (Tcl_GetLongFromObj, Tcl_GetWideIntFromObj)
+ (FreeBignum, Tcl_SetBignumObj):
+ * generic/tclParseExpr.c (Tcl_ParseExpr):
+ * generic/tclStrToD.c (TclParseNumber):
+ * generic/tclStringObj.c (TclAppendFormattedObjs):
+ * unix/tclLoadDyld.c (TclpLoadMemory):
+ * unix/tclUnixPipe.c (TclpCreateProcess): fix signed-with-unsigned
+ comparison and other warnings from gcc4 -Wextra.
-2002-04-18 Don Porter <dgp@users.sourceforge.net>
+2006-07-13 Andreas Kupries <andreask@activestate.com>
- * doc/subst.n: Clarified documentation on handling unusual return
- codes during substitution, and on variable substitutions implied by
- command substitution, and vice versa. [Bug 536838]
+ * unix/tclUnixPort.h: Added the inclusion of <AvailabilityMacros.h>.
+ The missing header caused the upcoming #if conditions to wrongly
+ exclude realpath, causing file normalize to ignore symbolic links in
+ the path.
-2002-04-18 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2006-07-11 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
- * generic/tclCmdIL.c (InfoBodyCmd):
- * tests/info.test (info-2.6): Proc bodies without string reps would
- report as empty [Bug 545644]
+ * generic/tclAsync.c: Made Tcl_AsyncDelete() more tolerant when called
+ after all thread TSD has been garbage-collected.
- * generic/tclCmdMZ.c (Tcl_SubstObj): More clarification for comment on
- behaviour when substitutions are not well-formed, prompted by [Bug
- 536831]; alas, removing the ill-defined behaviour is a lot of work.
+2006-07-05 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclParseExpr.c: Completely new expression parser that
+ builds a parse tree instead of operating with deep recursion. This
+ corrects reports of stack-blowing crashes parsing long expressions
+ [Bug 906201] and replaces a fundamentally O(N^2) algorithm with an
+ O(N) one [RFE 903765]. The new parser is better able to generate error
+ messages that clearly report both the nature and context of the syntax
+ error [Bugs 1029267, 1381715]. For now, the code for the old parser is
+ still present and can be activated with a "#define OLD_EXPR_PARSER
+ 1". This is for the sake of a clean implementation patch, and for ease
+ of benchmarking. The new parser is non-recursive, so much lighter in
+ stack consumption, but it does use more heap, so there may be cases
+ where parsing of long expressions that succeeded with the old parser
+ will lead to out of memory panics with the new one. There are still
+ more improvements possible on that point, though significant progress
+ may require changes to the Tcl_Token specifications documented for the
+ public Tcl_Parse*() routines.
+ ***POTENTIAL INCOMPATIBILITY*** for any callers that rely on the exact
+ (usually terrible) error messages generated by the old parser. This
+ includes a large number of tests in the test suite.
+
+ * generic/tclInt.h: Replaced TclParseWhiteSpace() with
+ * generic/tclParse.c: TclParseAllWhiteSpace() which is what
+ * generic/tclParseExpr.c: all the callers really needed.
+ Breaking whitespace runs at newlines is useful only to the command
+ parsing function, and it can call the file scoped routine
+ ParseWhiteSpace() to do that.
+
+ * tests/expr-old.test: Removed knownBug constraints that masked
+ * tests/expr.test: failures due to revised error messages.
+ * tests/parseExpr.test:
-2002-04-18 Miguel Sofer <msofer@users.sourceforge.net>
+2006-06-20 Don Porter <dgp@users.sourceforge.net>
- * generic/tclExecute.c:
- * tests/expr-old.test: fix for [Bug 542588] (Phil Ehrens), where "too
- large integers" were reported as "floating-point value" in [expr]
- error messages.
+ * generic/tclIOUtil.c: Changed default configuration to
+ * generic/tclInt.decls: #undef USE_OBSOLETE_FS_HOOKS which disables
+ * generic/tclTest.c: access to the Tcl 8.3 internal routines for
+ hooking into filesystem operations. Everyone ought to have migrated to
+ Tcl_Filesystems by now.
+ ***POTENTIAL INCOMPATIBILITY*** for any code still stuck in the
+ pre-Tcl_Filesystem era.
-2002-04-17 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclIntDecls.h: make genstubs
+ * generic/tclStubInit.c:
- * generic/tclEncoding.c (EscapeFromUtfProc):
- * generic/tclIO.c (WriteChars, Tcl_Close): corrected the handling of
- outputting end escapes for escape-based encodings.
- [Bug 526524] (yamamoto)
+ * generic/tclStrToD.c: Removed dead code that permitted disabling of
+ recognition of the new 0b and 0o numeric formats.
-2002-04-17 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclExecute.c: Removed dead code that implemented alternative
+ * generic/tclObj.c: design where numeric values did not
+ automatically narrow to the smallest Tcl_ObjType required to hold them
- * doc/tcltest.n: Removed [saveState] and [restoreState] from tcltest
- 2 documentation, effectively deprecating them. [Bug 495660]
- * library/tcltest/tcltest.tcl: Made separate export for commands kept
- only for tcltest 1 compatibility.
+ * generic/tclCmdAH.c: Removed dead code that was old implementation
+ of [format].
- * tests/iogt.test: Revised to run tests in a namespace, rather than
- use the useless and buggy [saveState] and [restoreState] commands of
- tcltest. Updated to use tcltest 2 as well. [Patch 544911]
+2006-06-14 Daniel Steffen <das@users.sourceforge.net>
-2002-04-16 Don Porter <dgp@users.sourceforge.net>
+ * unix/tclUnixPort.h (Darwin): support MAC_OS_X_VERSION_MAX_ALLOWED
+ define from AvailabilityMacros.h: override configure detection and
+ only use API available in the indicated OS version or earlier.
- * tests/io.test: Revised to run tests in a namespace, rather than use
- the useless and buggy [saveState] and [restoreState] commands of
- tcltest. Updated to use tcltest 2 as well. [Patch 544546]
+2006-06-14 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
-2002-04-15 Miguel Sofer <msofer@users.sourceforge.net>
+ * doc/format.n, doc/scan.n: Added examples for converting between
+ characters and their numeric interpretations following user prompting.
- * generic/tclProc.c:
- * tests/proc-old.test: Improved stack trace for TCL_BREAK and
- TCL_CONTINUE returns from procs. [Bug 536955] (dgp)
+2006-06-13 Donal K. Fellows <dkf@users.sf.net>
- * generic/tclExecute.c:
- * tests/compile.test: made bytecodes check for a catch before
- returning; the compiled [return] is otherwise non-catchable. [Bug
- 542142] reported by Andreas Kupries.
-
-2002-04-15 Don Porter <dgp@users.sourceforge.net>
-
- * tests/socket.test: Increased timeout values so that tests have time
- to successfully complete even on slow/busy machines. [Bug 523470]
-
- * doc/tcltest.n:
- * library/tcltest/tcltest.tcl:
- * tests/tcltest.test: Revised [tcltest::test] to return errors when
- called with invalid syntax and to accept exactly two arguments as
- documented. Improved error messages. [Bug 497446, Patch 513983]
- ***POTENTIAL INCOMPATIBILITY***: Incompatible with previous
- tcltest 2.* releases, found only in alpha releases of Tcl 8.4.
-
-2002-04-11 Jeff Hobbs <jeffh@ActiveState.com>
-
- * generic/tclNotify.c (TclFinalizeNotifier): remove remaining
- unserviced events on finalization.
-
- * win/tcl.m4: Enabled COFF as well as CV style debug info with
- --enable-symbols to allow Dr. Watson users to see function info. More
- info on debugging levels can be obtained at:
- http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
+ * unix/tclLoadDl.c (TclpDlopen): Workaround for a compiler bug in Sun
+ Forte 6. [Bug 1503729]
- * tests/ioCmd.test: fixed iocmd-8.15 to have mac and unixPc variants.
-
- * generic/tclParse.c (Tcl_ParseVar): conditionally incr obj refcount
- to prevent possible mem leak.
-
-2002-04-08 Daniel Steffen <das@users.sourceforge.net>
-
- * generic/tcl.h: no <sys/types.h> on mac.
- * mac/tclMacFile.c: minor fixes to Vince's changes from 03-24.
- * mac/tclMacOSA.c:
- * mac/tclMacResource.c: added missing Tcl_UtfToExternalDString
- conversions of resource file names.
- * mac/tclMacSock.c (TcpGetOptionProc): fixed bug introduced by Andreas
- on 02-25; changed strcmp's to strncmp's so that option comparison
- behaves like on other platforms.
- * mac/tcltkMacBuildSupport.sea.hqx (CW Pro6 changes): added support to
- allow Tk to hookup C library stderr/stdout to TkConsole.
- * tests/basic.test:
- * tests/cmdAH.test:
- * tests/encoding.test:
- * tests/fileSystem.test:
- * tests/ioCmd.test: fixed tests failing on mac: check for existence of
- [exec], changed some result strings.
-
-2002-04-06 Jeff Hobbs <jeffh@ActiveState.com>
-
- * unix/tclUnixFCmd.c (Realpath): added a little extra code to
- initialize a realpath arg when compiling in PURIFY mode in order to
- prevent spurious purify warnings. We should really create our own
- realpath implementation, but this will at least quiet purify for now.
-
-2002-04-05 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclCmdMZ.c (Tcl_SubstObj):
- * tests/subst.test: Corrected [subst] so that return codes TCL_BREAK
- and TCL_CONTINUE returned by variable substitution have the same
- effect as when those codes are returned by command substitution. [Bug
- 536879]
-
-2002-04-03 Jeff Hobbs <jeffh@ActiveState.com>
-
- * library/tcltest/tcltest.tcl: added getMatchingFiles back (alias
- to GetMatchingFiles), which was a public function in tcltest 1.0.
-
-2002-04-01 Vince Darley <vincentdarley@users.sourceforge.net>
-
- * generic/tclEnv.c:
- * generic/tclIOUtil.c: invalidate filesystem cache when the user
- changes env(HOME). Fixes [Bug 535621]. Also cleaned up some of the
- documentation.
- * tests/fileSystem.test: added test for bug just fixed.
-
-2002-04-01 Kevin Kenny <kennykb@acm.org>
-
- * win/tclWinTime.c (Tcl_GetTime): made the checks of clock frequency
- more permissive to cope with the fact that Win98SE is observed to
- return 1.19318 in place of 1.193182 for the performance counter
- frequency.
-
-2002-03-29 Jeff Hobbs <jeffh@ActiveState.com>
-
- * generic/tclCmdMZ.c (Tcl_TraceObjCmd, TraceVarProc)
- (TraceCommandProc, TclTraceCommandObjCmd): corrected potential
- double-free of traces on variables by flagging in Trace*Proc that it
- will free the var in case the eval wants to delete the var trace as
- well. [Bug 536937]
- Also converted Tcl_UntraceVar -> Tcl_UntraceVar2 and Tcl_Eval to
- Tcl_EvalEx in Trace*Proc for slight efficiency improvement.
-
-2002-03-29 Don Porter <dgp@users.sourceforge.net>
-
- * doc/AllowExc.3:
- * generic/tclBasic.c (Tcl_EvalObjv,Tcl_EvalEx,Tcl_EvalObjEx):
- * generic/tclCompile.h (TclCompEvalObj):
- * generic/tclExecute.c (TclCompEvalObj,TclExecuteByteCode):
- * tests/basic.test: Corrected problems with Tcl_AllowExceptions having
- influence over the wrong scope of Tcl_*Eval* calls. Patch from Miguel
- Sofer. Report from Jean-Claude Wippler. [Bug 219181]
-
-2002-03-28 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclVar.c: Refactored CallTraces to collect repeated handling
- of its returned value into CallTraces itself.
-
-2002-03-28 David Gravereaux <davygrvy@pobox.com>
-
- * tools/feather.bmp:
- * tools/man2help.tcl:
- * tools/man2help2.tcl:
- * win/makefile.vc: More winhelp target fixups. Added a feather bitmap
- to the non-scrollable area and changed the color to be yellow from a
- plain white. The colors can be whatever we want them to be, but
- thought I would start with something bold. [Bug 527941]
-
- * doc/SetVar.3:
- * doc/TraceVar.3:
- * doc/UpVar.3: .AP macro syntax repair.
-
-2002-03-27 David Gravereaux <davygrvy@pobox.com>
-
- * tools/man2help.tcl:
- * win/makefile.vc: winhelp target now copies all needed files from
- tools/ to a workarea under $(OUT_DIR) and builds it from there. No
- build cruft is left in tools/ anymore. All paths used in man2help.tcl
- are now relative to where the script is. [Bug 527941]
-
-2002-03-27 David Gravereaux <davygrvy@pobox.com>
-
- * win/.cvsignore:
- * win/buildall.vc.bat:
- * win/coffbase.txt:
- * win/makefile.vc:
- * win/nmakehlp.c (new):
- * win/rules.vc: First draft fix for [Bug 527941]. More changes need to
- done to the makehelp target to get to stop leaving build files in the
- tools/ directory. This does not address the syntax errors in the man
- files. Having the contents of tcl.hpj(.in) inside makefile.vc allows
- for version numbers to be replaced with macros.
+2006-06-06 Don Porter <dgp@users.sourceforge.net>
- The new nmakehlp.c is built by rules.vc in preprocessing and removes
- the need to use tricky shell syntax that wasn't compatible on Win9x
- systems. Clean targets made Win9x complient. This is a first draft
- repair for [Bug 533862].
+ * doc/GetStdChan.3: Added recommendation that each call to
+ Tcl_SetStdChannel() be accompanied by a call to Tcl_RegisterChannel().
-2002-03-28 Miguel Sofer <msofer@users.sourceforge.net>
+2006-06-05 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * generic/tclBasic.c (Tcl_EvalEx): passing the correct commandSize
- to TclEvalObjvInternal. [Bug 219362], fix by David Knoll.
+ * doc/Alloc.3: Added documentation of promise that Tcl_Realloc(NULL,x)
+ is the same as Tcl_Alloc(x), as discussed in comp.lang.tcl. Also fixed
+ nonsense sentence to say something meaningful.
-2002-03-28 Miguel Sofer <msofer@users.sourceforge.net>
+2006-05-29 Jeff Hobbs <jeffh@ActiveState.com>
- * generic/tclBasic.c (Tcl_EvalEx):
- * tests/basic.test: avoid exceptional returns at level 0
- [Bug 219181]
+ * generic/tcl.h (Tcl_DecrRefCount): use if/else construct to allow
+ placement in unbraced outer if/else conditions. (jcw)
-2002-03-27 Don Porter <dgp@users.sourceforge.net>
+2006-05-27 Daniel Steffen <das@users.sourceforge.net>
- * doc/tcltest.n ([mainThread]):
- * library/tcltest/tcltest.tcl:
- * tests/tcltest.test: Major code cleanup to deal with whitespace,
- coding conventions, and namespace issues, with several minor bugs
- fixed in the process.
+ * macosx/tclMacOSXNotify.c: implemented pthread_atfork() handler that
+ * unix/tcl.m4 (Darwin): recreates CoreFoundation state and
+ notifier thread in the child after a fork(). Note that pthread_atfork
+ is available starting with Tiger only. Because vfork() is used by the
+ core on Darwin, [exec]/[open] are not affected by this fix, only
+ extensions or embedders that call fork() directly (such as TclX).
+ However, this only makes fork() safe from corefoundation tcl with
+ --disable-threads; as on all platforms, forked children may deadlock
+ in threaded tcl due to the potential for stale locked mutexes in the
+ child. [Patch 923072]
- * tests/main.test: Added missing [after cancel]s.
+ * unix/configure: autoconf-2.59
+ * unix/tclConfig.h.in: autoheader-2.59
-2002-03-25 Don Porter <dgp@users.sourceforge.net>
+2006-05-24 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * tests/main.test: Removed workarounds for Bug 495977.
+ * unix/tcl.m4 (SC_CONFIG_SYSTEM): Fixed quoting of command script to
+ awk; it was a rarely used branch, but it was wrong. [Bug 1494160]
- * library/tcltest/tcltest.tcl: Keep the value of $::auto_path
- unchanged, so that the tcltest package can test code that depends
- on auto-loading. If a testing application needs $::auto_path pruned,
- it should do that itself. [Bug 495726]
- Improve the processing of the -constraints option to [test] so that
- constraint lists can have arbitrary whitespace, and non-lists don't
- blow things up. [Bug 495977]
- Corrected faulty variable initialization. [Bug 534845]
+2006-05-23 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
-2002-03-25 Miguel Sofer <msofer@users.sourceforge.net>
+ * doc/chan.n, doc/refchan.n: Tighten up the documentation to follow a
+ slightly more consistent style with regard to argument capitalization.
- * doc/CrtTrace.3: small doc correction
- * generic/tclBasic.c (Tcl_DeleteTrace): Allow NULL callback on
- trace deletions [Bug 534728] (Hemang Lavana).
+2006-05-13 Don Porter <dgp@users.sourceforge.net>
-2002-03-24 Miguel Sofer <msofer@users.sourceforge.net>
+ * generic/tclProc.c (ProcCompileProc): When a bump of the compile
+ epoch forces the re-compile of a proc body, take care not to overwrite
+ any Proc struct that may be referred to on the active call stack. This
+ fixes [Bug 1482718]. Note that the fix will not be effective for code
+ that calls the private routine TclProcCompileProc() directly.
- * generic/tclBasic.c (Tcl_EvalObjv): replaced obscure, incorrect
- code as described in [Bug 533907] (Don Porter).
+2006-05-13 Daniel Steffen <das@users.sourceforge.net>
-2002-03-24 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclEvent.c (HandleBgErrors): fix leak. [Coverity issue 86]
- * library/tcltest/tcltest.tcl: Use [interpreter] to set/query the
- executable currently running the tcltest package. [Bug 454050]
+2006-05-05 Don Porter <dgp@users.sourceforge.net>
- * library/tcltest/tcltest.tcl: Allow non-proc commands to be used
- as the customization hooks. [Bug 495662]
+ * generic/tclMain.c (Tcl_Main): Corrected flaw that required
+ * tests/main.test: (Tcl_Main-4.5): processing of one interactive
+ command before passing control to the loop routine registered with
+ Tcl_SetMainLoop(). [Bug 1481986]
-2002-03-24 Vince Darley <vincentdarley@users.sourceforge.net>
+2006-05-04 Don Porter <dgp@users.sourceforge.net>
- * generic/tclFilename.c:
- * generic/tclFCmd.c:
- * generic/tclTest.c:
+ * README: Bump version number to 8.5a5
* generic/tcl.h:
- * generic/tclIOUtil.c:
- * win/tclWinFile.c:
- * win/tclWinFCmd.c:
- * win/tclWinPipe.c:
- * unix/tclUnixFile.c:
- * unix/tclUnixFCmd.c:
- * mac/tclMacFile.c:
- * doc/FileSystem.3:
- * doc/file.n:
- * tests/cmdAH.test:
- * tests/fileName.test:
- * tests/fileSystem.test: (new file)
- * tests/winFCmd.test: fix [Bug 511666] and [Bug 511658], and improved
- documentation of some aspects of the filesystem, particularly
- 'Tcl_FSMatchInDirectory' which now might match a single file/directory
- only, and 'file normalize' which wasn't very clear before. Removed
- inconsistency betweens docs and the Tcl_Filesystem structure. Also
- fixed [Bug 523217] and corrected file normalization on Unix so that it
- expands symbolic links. Added some new tests of the filesystem code
- (in the new file 'fileSystem.test'), and some extra tests for correct
- handling of symbolic links. Fix to [Bug 530960] which shows up on
- Win98. Made comparison with ".com" case insensitive in tclWinPipe.c
-
- ***POTENTIAL INCOMPATIBILITY***: But only between alpha releases
- (users of the new Tcl_Filesystem lookup table in Tcl 8.4a4 need to
- handle the new way in which Tcl may call Tcl_FSMatchInDirectory, and
- 'file normalize' on unix now behaves correctly). Only known impact is
- with the 'tclvfs' extension.
-
-2002-03-22 Miguel Sofer <msofer@users.sourceforge.net>
-
- * tests/basic.test (basic-46.1): adding test for [Bug 533758], fixed
- earlier today.
-
-2002-03-22 Jeff Hobbs <jeffh@ActiveState.com>
-
- * win/tclWinInt.h: moved undef of TCL_STORAGE_CLASS. [Bug 478579]
-
-2002-03-22 Miguel Sofer <msofer@users.sourceforge.net>
-
- * generic/tclBasic.c (Tcl_EvalObjEx):
- * generic/tclExecute.c (TclCompEvalObj): fixed the errorInfo for
- return codes other than (TCL_OK, TCL_ERROR) to runLevel 0 [Bug
- 533758]. Removed the static RecordTracebackInfo(), as its
- functionality is easily replicated by Tcl_LogCommandInfo. Bug and
- redundancy noted by Don Porter.
-
-2002-03-21 Donal K. Fellows <fellowsd@cs.man.ac.uk>
-
- * doc/expr.n: Improved documentation for ceil and floor [Bug 530535]
-
-2002-03-20 Don Porter <dgp@users.sourceforge.net>
-
- * doc/SetVar.3:
- * doc/TraceVar.3:
- * doc/UpVar.3:
- * generic/tcl.h (Tcl_VarTraceProc):
- * generic/tcl.decls (Tcl_GetVar2, Tcl_SetVar2, Tcl_TraceVar2)
- (Tcl_UnsetVar2, Tcl_UntraceVar2, Tcl_UpVar2, Tcl_VarTraceInfo2)
- (Tcl_GetVar2Ex, TclSetVar2Ex):
- * generic/tclCmdMZ.c (TraceVarProc):
- * generic/tclEnv.c (EnvTraceProc):
- * generic/tclEvent.c (VwaitVarProc):
- * generic/tclInt.decls (TclLookupVar,TclPrecTraceProc):
- * generic/tclLink.c (LinkTraceProc):
- * generic/tclUtil.c (TclPrecTraceProc):
- * generic/tclVar.c (CallTraces, MakeUpvar, VarErrMsg, TclLookupVar,
- (Tcl_GetVar2, Tcl_SetVar2, Tcl_TraceVar2, Tcl_UnsetVar2)
- (Tcl_UntraceVar2, Tcl_UpVar2, Tcl_VarTraceInfo2, Tcl_GetVar2Ex)
- (TclSetVar2Ex): Updated interfaces of generic/tclVar.c according to
- TIP 27. In particular, the "part2" arguments were CONSTified.
- [Patch 532642]
- * generic/tclDecls.h:
- * generic/tclIntDecls.h: make genstubs
-
-2002-03-15 Donal K. Fellows <fellowsd@cs.man.ac.uk>
-
- * tests/compile.test (compile-12.3): Test to detect bug 530320.
- * generic/tclCompile.c (TclCompileTokens): Fixed buffer overrun
- reported in bug 530320.
-
-2002-03-14 Mo DeJong <mdejong@users.sourceforge.net>
-
- * win/configure: Regen.
- * win/configure.in: Add configure time test for SEH support in the
- compiler.
- * win/tclWin32Dll.c (ESP, EBP, TclpCheckStackSpace,
- (_except_checkstackspace_handler):
- * win/tclWinChan.c (ESP, EBP, Tcl_MakeFileChannel,
- (_except_makefilechannel_handler):
- * win/tclWinFCmd.c (ESP, EBP, DoRenameFile, DoCopyFile,
- (_except_dorenamefile_handler, _except_docopyfile_handler): Implement
- SEH support under gcc using inline asm. Tcl and Tk should now compile
- with Mingw 1.1. [Patch 525746]
+ * tools/tcl.wse.in:
+ * unix/configure.in:
+ * unix/tcl.spec:
+ * win/README.binary:
+ * win/configure.in:
-2002-03-14 Mo DeJong <mdejong@users.sourceforge.net>
+ * unix/configure: autoconf-2.59
+ * win/configure:
- * win/tclWinFCmd.c (DoRenameFile, DoCopyFile): Handle an SEH exception
- with EXCEPTION_EXECUTE_HANDLER instead of restarting the faulting
- instruction with EXCEPTION_CONTINUE_EXECUTION. Bug 466102 provides an
- example of how restarting could send Tcl into an infinite loop. [Patch
- 525746]
+ * generic/tclBasic.c (ExprSrandFunc): Restore acceptance of wide/big
+ * doc/mathfunc.n: integer values by srand(). [Bug 1480509]
-2002-03-11 Mo DeJong <mdejong@users.sourceforge.net>
+2006-04-26 Don Porter <dgp@users.sourceforge.net>
- * win/tclWinFCmd.c (DoRenameFile, DoCopyFile, DoDeleteFile,
- (DoRemoveJustDirectory): Make sure we don't pass NULL or "" as a path
- name to Win32 API functions since this was crashing under Windows 98.
+ *** 8.5a4 TAGGED FOR RELEASE ***
-2002-03-11 Don Porter <dgp@users.sourceforge.net>
+ * changes: Updates for another RC.
- * library/tcltest/tcltest.tcl:
- * library/tcltest/pkgIndex.tcl: Bumped tcltest package to 2.0.2.
+ * generic/tclBinary.c: Revised the handling of the Q and q format
+ * generic/tclInt.h: specifiers for [binary] to account for the
+ * generic/tclStrToD.c: "middle endian" floating point format used in
+ Nokia N770.
-2002-03-11 Mo DeJong <mdejong@users.sourceforge.net>
+2006-04-25 Don Porter <dgp@users.sourceforge.net>
- * library/tcltest/tcltest.tcl (getMatchingFiles): Pass a proper list
- to foreach to avoid munging a Windows patch like D:\Foo\Bar into
- D:FooBar before the glob.
+ * doc/DoubleObj.3: More doc updates for TIP 237.
+ * doc/expr.n:
+ * doc/format.n:
+ * doc/mathfunc.n:
+ * doc/scan.n:
+ * doc/string.n:
-2002-03-11 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tclScan.c: [scan $s %u] is documented to accept only
+ * tests/scan.test: decimal formatted integers. Fixed to match.
- * generic/tclEncoding.c: Fix typo in comment.
- * generic/tclIO.c (DoReadChars, ReadBytes, ReadChars): Use NULL value
- instead of pointer set to NULL to make things more clear. Reorder
- arguments so that they match the function signatures. Cleanup little
- typos and add more descriptive comment.
+2006-04-19 Kevin B. Kenny <kennykb@acm.org>
-2002-03-08 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tclStrToD.c: Added code to support the "middle endian"
+ floating point format used in the Nokia N770's software-based floating
+ point. Thanks to Bruce Johnson for reporting this bug, originally on
+ http://wiki.tcl.tk/15408.
+ * library/clock.tcl: Fixed a bug with Daylight Saving Time and Posix
+ time zone specifiers reported by Martin Lemburg in
+ http://groups.google.com/group/comp.lang.tcl/browse_thread/thread/9a8b15a4dfc0b7a0
+ (and not at SourceForge).
+ * tests/clock.test: Added test case for the above bug.
- * win/README: Update to indicate that Mingw 1.1 is required to build
- Tcl. Add section describing new msys based build process. Update
- Cygwin build instructions so users know where to find Mingw 1.1.
+2006-04-18 Donal K. Fellows <dkf@users.sf.net>
-2002-03-08 Jeff Hobbs <jeffh@ActiveState.com>
+ * doc/IntObj.3: Minor review fixes, including better documentation of
+ the behaviour of Tcl_GetBignumAndClearObj.
- * win/tclWinFCmd.c (DoCopyFile): correctly set retval to TCL_OK.
+2006-04-17 Don Porter <dgp@users.sourceforge.net>
-2002-03-07 Mo DeJong <mdejong@users.sourceforge.net>
+ * doc/IntObj.3: Documentation changes to account for TIP 237 changes.
+ * doc/Object.3: [Bug 1446971]
- * win/tclWin32Dll.c (TclpCheckStackSpace):
- * win/tclWinFCmd.c (DoRenameFile, DoCopyFile): Replace hard coded
- constants with Win32 symbolic names. Move control flow statements out
- of __try blocks since the documentation indicates it is frowned upon.
+2006-04-12 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
-2002-03-07 Don Porter <dgp@users.sourceforge.net>
+ * generic/regc_locale.c (cclass): Redefined the meaning of [:print:]
+ to be exactly UNICODE letters, numbers, punctuation, symbols and
+ spaces (*not* whitespace). [Bug 1376892]
- * doc/interp.n:
- * generic/tclInterp.c (Tcl_InterpObjCmd,SlaveObjCmd,
- (SlaveRecursionLimit):
- * generic/tclTest.c:
- * tests/interp.test: Added the [interp recursionlimit] command to
- set/query the recursion limit of an interpreter. Proposal and
- implementation from Stephen Trier. [TIP 87, Patch 522849]
+2006-04-11 Don Porter <dgp@users.sourceforge.net>
-2002-03-06 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclTrace.c: Stop some interference between enter traces
+ * tests/trace.test: and enterstep traces. [Bug 1458266]
- * generic/tcl.h, tools/tcl.wse.in, unix/configure.in,
- * unix/tcl.spec, win/README.binary, win/configure.in, README:
- Bumped patchlevel; this might need to change in the future, but it
- will help us distinguish between the CVS version and the most
- recent released version.
+2006-04-07 Don Porter <dgp@users.sourceforge.net>
-2002-03-06 Miguel Sofer <msofer@users.sourceforge.net>
+ * generic/tclPathObj.c: Yet another revised fix for the [Bug 1379287]
+ * tests/fileSystem.test: family of path normalization bugs.
- * generic/tclInt.h: for unshared objects, TclDecrRefCount now frees
- the internal rep before the string rep - just like the non-macro
- Tcl_DecrRefCount/TclFreeObj [Bug 524802].
+2006-04-06 Jeff Hobbs <jeffh@ActiveState.com>
-2002-03-06 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * generic/tclRegexp.c (FinalizeRegexp): full reset data to indicate
+ readiness for reinitialization.
- * doc/lsearch.n: Documentation of new features, plus examples.
- * tests/lsearch.test: Tests of new features.
- * generic/tclCmdIL.c (Tcl_LsearchObjCmd): TIP#80 support. See
- http://purl.org/tcl/tip/80 for details.
+2006-04-06 Don Porter <dgp@users.sourceforge.net>
-2002-03-05 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclIndexObj.c (Tcl_GetIndexFromObjStruct): It seems there
+ * tests/indexObj.test: are extensions that rely on the prior behavior
+ * doc/GetIndex.3: that the empty string cannot succeed as a
+ unique prefix matcher, so I'm restoring Donal Fellows's solution.
+ Added mention of this detail to the documentation. [Bug 1464039]
- *** 8.4a4 TAGGED FOR RELEASE ***
+ * tests/compExpr-old.test: Updated testmathfunctions constraint
+ * tests/compExpr.test: to post-TIP-232 world.
+ * tests/expr-old.test:
+ * tests/expr.test:
+ * tests/info.test:
- * unix/tclUnixChan.c: initial remedy for [Bug 525783] flush problem
- introduced by TIP #35. This may not satisfy true serial channels, but
- it restores the correct flushing of std* channels on exit.
+ * tests/indexObj.test: Corrected other test errors revealed by
+ * tests/upvar.test: testing outside the tcltest application.
- * unix/README: added --enable-langinfo doc.
+ * generic/tclPathObj.c: Revised fix for the [Bug 1379287] family of
+ path normalization bugs.
- * unix/tcl.spec:
- * tools/tcl.wse.in: fixed URL refs to use www.tcl.tk or SF.
+2006-04-06 Daniel Steffen <das@users.sourceforge.net>
-2002-03-04 Jeff Hobbs <jeffh@ActiveState.com>
+ * unix/tcl.m4: removed TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
+ define on Darwin. [Bug 1457515]
+ * unix/configure: autoconf-2.59
+ * unix/tclConfig.h.in: autoheader-2.59
- * README:
- * mac/README:
- * unix/Makefile.in:
- * unix/README:
- * win/README:
- * win/README.binary: updated to use www.tcl.tk URL.
+2006-04-05 Don Porter <dgp@users.sourceforge.net>
- * unix/Makefile.in: added older ChangeLogs to dist target.
+ * win/tclWinInit.c: More careful calls to Tcl_DStringSetLength()
+ * win/tclWinSock.c: to avoid creating invalid DString states. Bump
+ * win/tclWinDde.c: to version 1.3.2. [RFE 1366195]
+ * library/dde/pkgIndex.tcl:
- * tests/io.test:
- * tests/encoding.test: corrected iso2022 encoding results.
- added encoding-24.*
- * generic/tclEncoding.c (EscapeFromUtfProc): corrected output of
- escape codes as per RFC 1468. [Patch 474358] (taguchi)
- (TclFinalizeEncodingSubsystem): corrected potential double-free
- when encodings were finalized on exit. [Bug 219314, 524674]
+ * library/reg/pkgIndex.tcl: Bump to registry 1.2 because
+ * win/tclWinReg.c: Registry_Unload() is a new public routine
+ * win/Makefile.in: compared to the 1.1.* releases.
-2002-03-01 Jeff Hobbs <jeffh@ActiveState.com>
+ * win/configure.in: Bump package version numbers.
+ * win/configure: autoconf 2.59
- * library/encoding/iso2022-jp.enc:
- * library/encoding/iso2022.enc:
- * tools/encoding/iso2022-jp.esc:
- * tools/encoding/iso2022.esc: gave <ESC>$B precedence over <ESC>$@,
- based on comments (point 1) in [Bug 219283] (RFC 1468)
+2006-04-05 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * tests/encoding.test: added encoding-23.* tests
- * generic/tclIO.c (FilterInputBytes): reset the TCL_ENCODING_START
- flags in the ChannelState when using 'gets'. [Bug 523988]
- Also reduced the value of ENCODING_LINESIZE from 30 to 20 as this
- seems to improve the performance of 'gets' according to tclbench.
+ * generic/tclIndexObj.c (Tcl_GetIndexFromObjStruct): Allow empty
+ strings to be matched by the Tcl_GetIndexFromObj machinery, in the
+ same manner as any other key. [Bug 1464039]
-2002-02-28 Jeff Hobbs <jeffh@ActiveState.com>
+2006-04-03 Andreas Kupries <andreask@activestate.com>
- * generic/tclCmdMZ.c (TraceCommandProc): ensure that TraceCommandInfo
- structure was also deleted when a command was deleted to prevent a
- mem leak.
+ * generic/tclIO.c (ReadChars): Added check, panic and commentary to a
+ piece of code which relies on BUFFER_PADDING to create enough space at
+ the beginning of each buffer for the insertion of partial multibyte
+ data at the beginning of a buffer. Commentary explains why this code
+ is OK, and the panic is as a precaution if someone twiddled the
+ BUFFER_PADDING into uselessness.
- * generic/tclBasic.c (Tcl_CreateObjTrace): set tracePtr->flags
- correctly.
+ * generic/tclIO.c (ReadChars): Temporarily suppress the use of
+ TCL_ENCODING_END set when EOF was reached while the buffer we are
+ converting is not truly the last buffer in the queue. Together with
+ the Utf bug below it was possible to completely wreck the buffer data
+ structures, eventually crashing Tcl. [Bug 1462248]
- * generic/tclTimer.c (TimerExitProc): remove remaining events in
- tls on thread exit.
+ * generic/tclEncoding.c (UtfToUtfProc): Stop accessing memory beyond
+ the end of the input buffer when TCL_ENCODING_END is set and the last
+ bytes of the buffer start a multi-byte sequence. This bug contributed
+ to [Bug 1462248].
-2002-02-28 Miguel Sofer <msofer@users.sourceforge.net>
+2006-03-30 Miguel Sofer <msofer@users.sf.net>
- * generic/tclNamesp.c: allow cached fully-qualified namespace names to
- be usable from different namespaces within the same interpreter
- without forcing a new lookup [Patch 458872].
+ * generic/tclExecute.c: remove unused var and silence gcc warning
-2002-02-28 Miguel Sofer <msofer@users.sourceforge.net>
+2006-03-29 Jeff Hobbs <jeffh@ActiveState.com>
- * generic/tclExecute.c: Replaced a few direct stack accesses with the
- POP_OBJECT() macro [Bug 507181] (Don Porter).
+ * win/Makefile.in: convert _NATIVE paths to use / to avoid ".\"
+ path-as-escape issue.
-2002-02-27 Don Porter <dgp@users.sourceforge.net>
+2006-03-29 Don Porter <dgp@users.sourceforge.net>
- * doc/GetIndex.3:
- * generic/tcl.decls (Tcl_GetIndexFromObjStruct):
- * generic/tclIndexObj.c (Tcl_GetIndexFromObjStruct): Revised the
- prototype of the Tcl_GetIndexFromObjStruct to take its struct
- table as a (CONST VOID *) argument, better describing what it is,
- maintaining source compatibility, and adding CONST correctness
- according to TIP 27. Thanks to Joe English for an elegant
- solution. [Bug 520304]
+ * changes: Updates for another RC.
- * generic/tclDecls.h: make genstubs
+ * generic/tclPathObj.c: More fixes for path normalization when /../
+ * tests/fileSystem.test: tries to go beyond root.[Bug 1379287]
- * generic/tclMain.c (Tcl_Main,StdinProc): Corrected some reference
- count management errors on the interactive command Tcl_Obj found by
- Purify. Thanks to Jeff Hobbs for the report and assistance.
+ * generic/tclExecute.c: Revised INST_MOD implementation to do
+ calculations in native types as much as possible, moving to mp_ints
+ only when necessary.
-2002-02-27 Jeff Hobbs <jeffh@ActiveState.com>
+2006-03-28 Jeff Hobbs <jeffh@ActiveState.com>
- * generic/tclBasic.c (Tcl_EvalTokensStandard): corrected mem leak
- in error case.
+ * win/tclWinPipe.c (TclpCreateProcess): change panics to Tcl errors
+ and do proper refcounting of noe objPtr. [Bug 1194429]
- * generic/tclTest.c (TestStatProc[123]): correct harmless UMRs.
+ * unix/tcl.m4, win/tcl.m4: []-quote AC_DEFUN functions.
- * generic/tclLink.c (Tcl_LinkVar): correct mem leak in error case.
+2006-03-28 Daniel Steffen <das@users.sourceforge.net>
-2002-02-27 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+ * macosx/Tcl.xcode/default.pbxuser: add '-singleproc 1' cli arg to
+ * macosx/Tcl.xcodeproj/default.pbxuser: tcltest to ease test debugging
- * tests/socket.test (2.7): Accepted and applied patch for [Bug 523470]
- provided by Don Porter <dgp@users.sourceforge.net> to avoid timing
- problems in that test.
+ * macosx/Tcl.xcode/project.pbxproj: removed $prefix/share from
+ * macosx/Tcl.xcodeproj/project.pbxproj: TCL_PACKAGE_PATH as per change
+ to unix/configure.in of 2006-03-13.
- * unix/tclUnixChan.c (TclpOpenFileChannel): Added code to regonize
- "/dev/tty" (by name) and to not handle it as tty / serial line. This
- is the controlling terminal and is special. Setting it into raw mode
- as is done for other tty's is a bad idea. This is a hackish fix for
- expect [Bug 520624]. The fix has limitation: Tcl_MakeFileChannel
- handles tty's specially too, but is unable to recognize /dev/tty as it
- only gets a file descriptor, and no name for it.
+ * unix/tclUnixFCmd.c (TclpObjNormalizePath): deal with *BSD/Darwin
+ realpath() converting relative paths into absolute paths [Bug 1064247]
-2002-02-26 Jeff Hobbs <jeffh@ActiveState.com>
+2006-03-28 Vince Darley <vincentdarley@sourceforge.net>
- * generic/tclCmdAH.c (StoreStatData): corrected mem leak.
+ * generic/tclIOUtil.c: fix to nativeFilesystemRecord comparisons
+ (lesser part of [Bug 1064247])
- * generic/tclCmdMZ.c (Tcl_RegsubObjCmd): prevent obj leak in remedial
- regsub case.
+2006-03-27 Pat Thoyts <patthoyts@users.sourceforge.net>
- * generic/tclFileName.c (Tcl_TranslateFileName): decr refcount for
- error case to prevent mem leak.
+ * win/tclWinTest.c: Fixes for [Bug 1456373] (mingw-gcc issue)
- * generic/tclVar.c (Tcl_ArrayObjCmd): removed extra obj allocation.
+2006-03-27 Andreas Kupries <andreask@activestate.com>
- * unix/tclUnixSock.c (Tcl_GetHostName): added an extra gethostbyname
- check to guard against failure with truncated names returned by uname.
+ * doc/CrtChannel.3: Added TCL_CHANNEL_VERSION_5, made it the
+ * generic/tcl.h: version where the "truncateProc" is defined at,
+ * generic/tclIO.c: and moved all channel drivers of Tcl to v5.
+ * generic/tclIOGT.c, generic/tclIORChan.c, unix/tclUnixChan.c:
+ * unix/tclUnixPipe.c, win/tclWinChan.c, win/tclWinConsole.c:
+ * win/tclWinPipe.c, win/tclWinSerial.c, win/tclWinSock.c:
- * unix/configure:
- * unix/tcl.m4 (SC_SERIAL_PORT): added sys/modem.h check and defined
- _XOPEN_SOURCE_EXTENDED for HP-11 to get updated header decls.
+2006-03-27 Don Porter <dgp@users.sourceforge.net>
- * unix/tclUnixChan.c: added Unix implementation of TIP #35, serial
- port support. [Patch 438509] (schroedter)
+ * generic/tclExecute.c: Merge INST_MOD computation in with the
+ INST_?SHIFT instructions, which also operate only on two integral
+ values. Also corrected flaw that made INST_BITNOT of wide values
+ require mp_int calculations. Also corrected type that missed optimized
+ handling of the tclBooleanType by the TclGetBooleanFromObj macro.
-2002-02-26 Miguel Sofer <msofer@users.sourceforge.net>
+ * changes: Updates for another RC.
- * generic/tclCmpCmds.c: (bugfix to the bugfix, hopefully the last)
- Bugfix to the new [for] compiling code: was setting a exceptArray
- parameter using another param which wasn't yet initialised, thus
- filling it with noise.
+2006-03-25 Don Porter <dgp@users.sourceforge.net>
-2002-02-25 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+ * generic/tclExecute.c: Corrections to INST_EXPON detection of
+ overflow to use mp_int calculations.
- * mac/tclMacSock.c (TcpGetOptionProc): Changed to recognize the option
- "-error". Essentially ignores the option, always returning an empty
- string.
+2006-03-24 Kevin B. Kenny <kennykb@acm.org>
-2002-02-25 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclExecute.c (TclExecuteByteCode): Added a couple of missing
+ casts to 'int' that were affecting compilablity on VC6.
- * doc/Alloc.3:
- * doc/LinkVar.3:
- * doc/ObjectType.3:
- * doc/PkgRequire.3:
- * doc/Preserve.3:
- * doc/TCL_MEM_DEBUG.3: Updated documentation to describe the ckalloc,
- ckfree, ckrealloc, attemptckalloc, and attemptckrealloc macros, and
- to accurately describe when and how they are used. [Bug 497459] (dgp)
+2006-03-24 Don Porter <dgp@users.sourceforge.net>
- * generic/tclHash.c (AllocArrayEntry, AllocStringEntry): Before
- invoking ckalloc when creating a Tcl_HashEntry, check that the amount
- of memory being allocated is at least as large as
- sizeof(Tcl_HashEntry). The previous code was allocating memory regions
- that were one or two bytes short. [Bug 521950] (dejong)
+ * generic/tclEncoding.c: Reverted latest change [Bug 506653] since it
+ reportedly killed test performance on Windows.
-2002-02-25 Miguel Sofer <msofer@users.sourceforge.net>
+ * generic/tclExecute.c: Revised INST_EXPON implementation to do
+ calculations in native types as much as possible, moving to mp_ints
+ only when necessary.
- * generic/tclBasic.c (Tcl_EvalEx): avoiding a buffer overrun reported
- by Joe English, and restoring tcl7.6 behaviour for [subst]: badly
- terminated nested scripts will raise an error and not be evaluated.
- [Bug 495207]
+2006-03-23 Don Porter <dgp@users.sourceforge.net>
-2002-02-25 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclExecute.c: Merged INST_EXPON handling in with the other
+ binary operators that operate on all number types (INST_ADD, etc.).
- * unix/tclUnixPort.h: corrected strtoll prototype mismatch on Tru64.
- * compat/strtod.c (strtod): simplified #includes
- * compat/strtol.c (strtol): gather result in a long before returning
- as a long: necessary on platforms where sizeof(int) != sizeof(long).
+ * tests/env.test: With case preserved (see 2006-03-21 commit) be sure
+ to do case-insensitive filtering. [Bug 1457065]
-2002-02-25 Daniel Steffen <das@users.sourceforge.net>
+2006-03-23 Reinhard Max <max@suse.de>
- * unix/tclLoadDyld.c: updated to use Mac OS X 10.1 dyld APIs that have
- more libdl-like semantics. [Bug 514392]
+ * unix/tcl.spec: Cleaned up and completed the spec file. An RPM can
+ now be built from the tcl source distribution with "rpmbuild -tb
+ <tarball>"
-2002-02-25 Miguel Sofer <msofer@users.sourceforge.net>
+2006-03-22 Reinhard Max <max@suse.de>
- * generic/tclCompCmds: fixing a bug in patch dated 2002-02-22, in the
- code for [for] and [while]. Under certain conditions, for long bodies,
- the exception range parameters were badly computed. Tests forthcoming:
- I still can't reproduce the conditions in the testsuite (!), although
- the bug (with assorted segfault or panic!) can be triggered from the
- console or with the new parse.bench in tclbench.
+ * tests/stack.test: Run the stack tests in subshells, so that they are
+ reported as failed tests rather than bugs in the test suite if the
+ recursion causes a segfault.
-2002-02-25 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2006-03-21 Don Porter <dgp@users.sourceforge.net>
- * compat/strtoul.c, compat/strtol.c, compat/strtod.c: Added UCHAR,
- CONST and #includes to clean up GCC output.
+ * changes: Updates for another RC.
-2002-02-23 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclStrToD.c: One of the branches of AccumulateDecimalDigit
+ * tests/parseExpr.test: did not. [Bug 1451233]
- * compat/strtoull.c (strtoull):
- * compat/strtoll.c (strtoll):
- * compat/strtoul.c (strtoul): Fixed failure to handle leading sign
- symbols '+' and '-' and '0X' and raise overflow errors. [Bug 440916]
- Also corrects prototype and errno problems.
+ * tests/env.test: Preserve case of saved env vars. [Bug 1409272]
-2002-02-23 Mo DeJong <mdejong@users.sourceforge.net>
+2006-03-21 Daniel Steffen <das@users.sourceforge.net>
- * configure: Regen.
- * unix/tcl.m4 (SC_CONFIG_CFLAGS): Link with -n32 instead of -32 when
- building on IRIX64-6.* system. [Bug 521707]
+ * generic/tclInt.decls: implement globbing for HFS creator & type
+ * macosx/tclMacOSXFCmd.c:codes and 'hidden' flag, as documented in
+ * tests/macOSXFCmd.test: glob.n; objectified OSType handling in [glob]
+ * unix/tclUnixFile.c: and [file attributes]; fix globbing for
+ hidden files with pattern==NULL arg. [Bug 823329]
+ * generic/tclIntPlatDecls.h:
+ * generic/tclStubInit.c: make genstubs
-2002-02-22 Don Porter <dgp@users.sourceforge.net>
+2006-03-20 Andreas Kupries <andreask@activestate.com>
- * generic/tclInt.h:
- * generic/tclObj.c: renamed global variable emptyString ->
- tclEmptyString because it is no longer static.
- * generic/tclPkg.c: Fix for panic when library is loaded on a
- platform without backlinking without proper use of stubs. [Bug 476537]
+ * win/Makefile.in (install-libraries): Generate tcl8/8.4 directory
+ under Windows as well (cygwin Makefile). Related entry: 2006-03-07,
+ dgp. This moved the installation of http from 8.2 to 8.4, partially. A
+ fix of the required directory creation was done for unix on Mar 10,
+ without entry in the Changelog. This entry is for the fix of the
+ directory creation under Windows.
-2002-02-22 Jeff Hobbs <jeffh@ActiveState.com>
+ * unix/installManPage: There is always one even more broken "sed".
+ Moved the # comment starting character in the sed script to the
+ beginning of their respective lines. The AIX sed will not recognize
+ them as comments otherwise :( The actual text stays indented for
+ better association with the commands they belong to.
- * tests/regexpComp.test: updated regexp-11.[1-4] to match changes
- in regexp.test for new regsub syntax
+2006-03-20 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * unix/configure:
- * unix/tcl.m4: added --enable-64bit support for AIX-4 (using -q64
- flag) when using IBM's xlc compiler.
+ * tests/cmdAH.test, tests/fCmd.test, tests/unixFCmd.test:
+ * tests/winFCmd.test: Cleanup of some test constraint handling, and a
+ few other minor issues.
- * tests/safe.test: updated safe-8.5 and safe-8.7
- * library/safe.tcl (CheckFileName): removed the limit on
- sourceable file names (was only *.tcl or tclIndex files with no
- more than one dot and 14 chars). There is enough internal
- protection in a safe interpreter already. Fixes [Tk Bug 521560].
+2006-03-18 Vince Darley <vincentdarley@sourceforge.net>
-2002-02-22 Miguel Sofer <msofer@users.sourceforge.net>
+ * generic/tclFileName.c:
+ * doc/FileSystem.3:
+ * tests/fileName.test: Fix to [Bug 1084705] so that 'glob -nocomplain'
+ finally agrees with its documentation and doesn't swallow genuine
+ errors.
- * generic/tclCompCmds: [FR 465811]. Optimising [if], [for] and
- [while] for constant conditions; in addition, [for] and [while] are
- now compiled with the "loop rotation" optimisation (thanks to Kevin
- Kenny).
+ ***POTENTIAL INCOMPATIBILITY*** for scripts that assumed '-nocomplain'
+ removes the need for 'catch' to deal with non-understood path names.
-2002-02-22 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ Small optimisation to implementation of pattern==NULL case of TclGlob,
+ and clarification to the documentation. [Tclvfs bug 1405317]
- --- TIP#76 CHANGES ---
- * generic/tclCmdMZ.c (Tcl_RegsubObjCmd): Final-argument-less
- [regsub] returns the modified string.
- * doc/regsub.n: Updated docs.
- * tests/regexp.test: Updated and added tests.
+2006-03-18 Vince Darley <vincentdarley@sourceforge.net>
- * compat/strtoll.c (strtoll):
- * compat/strtoull.c (strtoull):
- * unix/tclUnixPort.h:
- * win/tclWinPort.h: Const-ing 64-bit compatability declarations.
- Note that the return pointer is non-const because it is entirely
- legal for the functions to be called from somewhere that owns the
- string being passed. Fixes problem reported by Larry Virden.
+ * tests/fCmd.test: added knownBug test case for [Bug 1394972]
-2002-02-21 David Gravereaux <davygrvy@pobox.com>
+ * tests/winFCmd.test:
+ * tests/tcltest.test: corrected tests to better account for behaviour
+ of writable/non-writable directories on Windows 2000/XP. This, with
+ the previous patches, closes [Bug 1193497]
- * win/mkd.bat (removed):
- * win/coffbase.txt (new):
- * win/makefile.bc:
- * win/makefile.vc: Changed the 'setup' target to stop using the
- mkd.bat file and just make the directory right in the rule. Same
- change to makefile.bc. configure.in nor Makefile.in use it.
+2006-03-17 Andreas Kupries <andreask@activestate.com>
- coffbase.txt will be the master list for our "prefered base addresses"
- set by the linker. This should improve load-time (NT only) by avoiding
- relocations. Submissions to the list by extension authors are
- encouraged.
+ * doc/chan.n: Updated with documentation for the commands 'chan
+ create' and 'chan postevent' (TIP #219).
- Added a 'tidy' target to compliment 'clean' and 'hose' to remove just
- the outputs. Also removed the $(winlibs) macro as it wasn't being
- used.
+ * doc/refchan.n: New file. Documentation of the command handler API
+ for reflected channels (TIP #219).
- Stuff left to do:
- 1) get the winhelp target to stop building in the tools/ directory.
- 2) stop using rmd.bat
- 3) add more dependacy rules.
+2006-03-17 Joe Mistachkin <joe@mistachkin.com>
- * win/tclAppInit.c: Reverted back to -r1.6, as the header file change
- to tclPort.h won't allow for easy embedded support outside of the
- source dist. Thanks to Don Porter for pointing this out to me.
+ * unix/tclUnixPort.h: Include pthread.h prior to pthread_np.h [Bug
+ 1444692]
-2002-02-21 David Gravereaux <davygrvy@pobox.com>
+ * win/tclWinTest.c: Corrected typo of 'initializeMutex' that prevented
+ successful compilation.
- * win/makefile.vc:
- * win/rules.vc: Added a new "loimpact" option that sets the
- -ws:aggressive linker option. Off by default. It's said to keep the
- heap use low at the expense of alloc speed.
+2006-03-16 Andreas Kupries <andreask@activestate.com>
- * win/tclAppInit.c: Changed #include "tcl.h" to be tclPort.h to remove
- the raw windows.h include. tclPort.h brings in windows.h already and
- lessens the pre-compiled-header mush and the randomly useless #pragma
- comment (lib,...) references throughout the big windows.h tree (as
- observed at high linker warning levels).
+ * doc/open.n: Documented the changed behaviour of 'a'ppend mode.
-2002-02-21 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * tests/io.test (io-43.1 io-44.[1234]): Rewritten to be self-contained
+ with regard to setup and cleanup. [Bug 681793]
- * generic/tcl.h: Better guessing of LP64/ILP32 architecture, but
- now sensitive to presence of (suitable) <limits.h>
+ * generic/tclIOUtil.c (TclGetOpenMode): Added the flag O_APPEND to the
+ list of POSIX modes used when opening a file for 'a'ppend. This
+ enables the proper automatic seek-to-end-on-write by the OS. See [Bug
+ 680143] for longer discussion.
-2002-02-20 Don Porter <dgp@users.sourceforge.net>
+ * tests/ioCmd.test (iocmd-13.7.*): Extended the testsuite to check the
+ new handling of 'a'.
- * generic/tcl.decls (Tcl_RegExpRange,Tcl_GetIndexFromObjStruct):
- Overlooked a few source incompatibilities. Now using CONST84.
- * generic/tclDecls.h: make genstubs
- * generic/tcl.h (Tcl_CmdObjTraceProc): silence warning from Sun
- Workshop compiler.
+2006-03-15 Andreas Kupries <andreask@activestate.com>
-2002-02-20 David Gravereaux <davygrvy@pobox.com>
+ * tests/socket.test: Extended the timeout in socket-11.11 from 10 to
+ 40 seconds to allow for really slow machines. Also extended
+ actual/expected results with value of variable 'done' to make it
+ clearer when a test fails due to a timeout. [Bug 792159]
- * win/buildall.vc.bat:
- * win/makefile.vc:
- * win/rules.vc: General clean-ups. Added compiler and linker tests for
- a) the pentium 0x0F errata, b) optimizing (not all have this), and c)
- linker v6 section alignment confusion. All these are tested first to
- make sure any D4002 or LNK1117 warnings aren't displayed. The pentium
- 0x0F errata is a recommended switch. The v5 linker's section alignment
- default is 512, but the v6 linker was changed to 4096 in an attempt to
- speed loading on Win98. I changed the default to always be 512 across
- both linkers, unless linking statically, then 4096 is used for the
- claimed speed effect. Using a 512 alignment saves 12k bytes of dead
- space in the DLL.
+2006-03-15 Vince Darley <vincentdarley@sourceforge.net>
- Added IA64 B-stepping errata switch when the compiler supports it.
+ * win/fCmd.test: add proper test constraints so the new tests don't
+ run on Unix.
- Added profiling to $(lflags) when requested and also removed the
- explict -entry option as the default works fine as is.
+2006-03-14 Andreas Kupries <andreask@activestate.com>
- Removed win/tclWinInit.c from the special case section to let it use
- the common implicit rule as the $(EXTFLAGS) macro it had was never
- referenced anywhere.
+ * generic/tclPipe.c (TclCreatePipeline): Modified the processing of
+ pipebars to fail if the last bar is followed only by redirections.
+ [Bug 768659]
-2002-02-20 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2006-03-14 Andreas Kupries <andreask@activestate.com>
- * generic/tcl.h: Added code to guess the correct settings for
- TCL_WIDE_INT_IS_LONG and TCL_WIDE_INT_TYPE when configure doesn't tell
- us them, as can happen with extensions.
+ * doc/fconfigure.n: Clarified that -translation is binary is reported
+ as lf when queried, because it is identical to lf, except for the
+ special additional behaviour when setting it. [Bug 666770]
-2002-02-19 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2006-03-14 Andreas Kupries <andreask@activestate.com>
- * doc/format.n: Updated docs to list the specification.
- * generic/tclCmdAH.c (Tcl_FormatObjCmd): Made behaviour on 64-bit
- platforms correctly meet the specification, that %d works with the
- native word-sized integer, instead of trying to guess (wrongly) from
- the value being passed.
+ * doc/clock.n: Removed double-quotes around section title NAME; not
+ needed.
+ * unix/installManpage: Reverted part to handle double-quotes in
+ section NAME, chokes older sed installations.
-2002-02-19 Don Porter <dgp@users.sourceforge.net>
+2006-03-14 Andreas Kupries <andreask@activestate.com>
- * changes: First draft of updated changes for 8.4a4 release.
+ * library/tm.tcl (::tcl::tm::Defaults): Fixed handling of environment
+ variable TCLX.y_TM_PATH, bad variable reference. Thanks to Julian
+ Noble. [Bug 1448251]
-2002-02-15 Jeff Hobbs <jeffh@ActiveState.com>
+2006-03-14 Vince Darley <vincentdarley@sourceforge.net>
- * unix/tclUnixPort.h: add strtoll/strtoull declarations for platforms
- that do not define them.
+ * win/tclWinFile.c: updated patch to deal with 'file writable' issues
+ on Windows XP/2000.
+ * generic/tclTest.c:
+ * unix/tclUnixTest.c:
+ * win/tclWinTest.c:
+ * tests/fCmd.test: updated test suite to deal with correct permissions
+ setting and differences between XP/2000 and 95/98 3 tests still fail;
+ to be dealt with shortly
- * generic/tclIndexObj.c (STRING_AT): removed ptrdiff_t cast and use of
- VOID* in default case (GNU-ism).
+2006-03-13 Don Porter <dgp@users.sourceforge.net>
-2002-02-15 Kevin Kenny <kennykb@acm.org>
+ * generic/tclEncoding.c: Report error when an escape encoding is
+ missing one of its sub-encodings. [Bug 506653]
- * compat/strtoll.c:
- * compat/strtoul.c:
- * compat/strtoull.c:
- * generic/tclIOUtil.c:
- * generic/tclPosixStr.c:
- * generic/tclTest.c:
- * generic/tclTestObj.c:
- * tests/get.test:
- * win/Makefile.vc: Further tweaks to the TIP 72 patch to make it
- compile under VC++.
-
-2002-02-15 Andreas Kupries <andreas_kupries@users.sourceforge.net>
-
- * tclExecute.c:
- * tclIOGT.c:
- * tclIndexObj.c: Touchups to the TIP 72 patch to make it compileable
- under Windows again. The changes are not complete, there is one nasty
- regarding _stati64
-
-2002-02-15 Donal K. Fellows <fellowsd@cs.man.ac.uk>
-
- +----------------------+
- | TIP #72 IMPLEMENTED. |
- +----------------------+
-
- There are a lot of changes from this TIP, so please see
- http://tip.tcl.tk/72.html for discussion of backward-compatability
- issues, but the main ones modifications are in:
-
- * generic/tcl.h: New types.
- * generic/tcl.decls: New public functions.
- * generic/tclExecute.c: 64-bit aware bytecode engine.
- * generic/tclBinary.c: 64-bit handling in [binary] command.
- * generic/tclScan.c: 64-bit handling in [scan] command.
- * generic/tclCmdAH.c: 64-bit handling in [file] and [format]
- commands.
- * generic/tclBasic.c: New "wordSize" entry in ::tcl_platform.
- * generic/tclFCmd.c: Large-file support (with many consequences.)
- * generic/tclIO.c: Large-file support (with many consequences.)
- * compat/strtoll.c, compat/strtoull.c: New support functions.
- * unix/tcl.m4, unix/configure: 64-bit support and greatly enhanced
- cacheing.
-
- Most other changes, including all those in doc/* and test/* as well as
- the majority in the platform directories, follow on from these.
-
- Also coming out of the woodwork:
- * generic/tclIndex.c: Better support for Cray PVP.
- * win/tclWinMtherr.c: Better Borland support.
-
- Note that, in a number of places through the Unix part of the platform
- support, there are Tcl_Platform* references. These are expanded into
- the correct way to call that particular underlying function, i.e. with
- or without a '64' suffix, and should be used by people working on the
- core in preference to the API functions they overlay so that the code
- remains portable depending on the presence or absence of 64-bit
- support on the underlying platform.
-
- ***POTENTIAL INCOMPATIBILITY***: Extracted from the TIP
-
- SUMMARY OF INCOMPATIBILITIES AND FIXES
- ======================================
-
- The behaviour of expressions containing constants that appear positive
- but which have a negative internal representation will change, as
- these will now usually be interpreted as wide integers. This is always
- fixable by replacing the constant with int(constant).
-
- Extensions creating new channel types will need to be altered as
- different types are now in use in those areas. The change to the
- declaration of Tcl_FSStat and Tcl_FSLstat (which are the new preferred
- API in any case) are less serious as no non-alpha releases have been
- made yet with those API functions.
-
- Scripts that are lax about the use of the l modifier in format and
- scan will probably need to be rewritten. This should be very uncommon
- though as previously it had absolutely no effect.
-
- Extensions that create new math functions that take more than one
- argument will need to be recompiled (the size of Tcl_Value changes),
- and functions that accept arguments of any type (TCL_EITHER) will need
- to be rewritten to handle wide integer values. (I do not expect this
- to affect many extensions at all.)
-
-2002-02-14 Andreas Kupries <andreas_kupries@users.sourceforge.net>
-
- * generic/tclIOCmd.c (Tcl_GetsObjCmd): Trivial fix for [Bug 517503], a
- memory leak reported by Miguel Sofer <msofer@users.sourceforge.net>.
- The leak happens if an error occurs for "set var [gets $chan]" and
- leak one empty object.
-
-2002-02-12 David Gravereaux <davygrvy@pobox.com>
-
- * djgpp/ (new directory)
- * djgpp/Makefile (new):
- * unix/tclAppInit.c:
- * unix/tclMtherr.c:
- * unix/tclUnixFCmd.c:
- * unix/tclUnixFile.c:
- * unix/tclUnixInit.c:
- * unix/tclUnixPort.h: Early stage of DJGPP support for building Tcl
- on DOS. Dynamic loading isn't working, yet. Requires watt32 for the
- TCP/IP stack. No autoconf, yet. Barely tested, but makes a working exe
- that runs Tcl in protected-mode, flat memory. [exec] and pipes will
- need the most work as multi-tasking on DOS has to be carefully.
+ * unix/configure.in: Revert change from 2005-07-26 that sometimes
+ * unix/configure: added $prefix/share to the tcl_pkgPath. See
+ [Patch 1231015]. autoconf-2.59.
-2002-02-10 Kevin Kenny <kennykb@acm.org>
+2006-03-10 Miguel Sofer <msofer@users.sf.net>
- * doc/CrtObjCmd.3:
- * doc/CrtTrace.3:
- * generic/tcl.decls:
- * generic/tcl.h:
- * generic/tclBasic.c:
- * generic/tclInt.h:
- * generic/tclTest.c:
- * tests/basic.test: Added Tcl_CreateObjTrace,
- Tcl_GetCommandInfoFromToken and Tcl_SetCommandInfoFromToken.
- (TIPs #32 and #79.)
+ * generic/tclProc.c (ObjInterpProcEx):
+ * tests/apply.test (apply-5.1): Fix [apply] error messages so that
+ they quote the lambda expression. [Bug 1447355]
- * generic/tclDecls.h:
- * generic/tclStubInit.c: Regenerated Stubs tables.
+2006-03-10 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
-2002-02-08 Jeff Hobbs <jeffh@ActiveState.com>
+ -- Summary of changes fixing [Bug 1437595] --
- * unix/configure:
- * unix/tcl.m4: added -pthread for FreeBSD to EXTRA_CFLAGS and
- LDFLAGS. Also triggered nodots only for FreeBSD-3.
- Added AC_DEFINE(_POSIX_PTHREAD_SEMANTICS) for Solaris.
+ * generic/tclEvent.c: Cosmetic touches and identation
+ * generic/tclInt.h: Added TclpFinalizeSockets() call.
- * unix/tclUnixPort.h:
- * unix/tclUnixThrd.c: added thread-safe versions of readdir,
- localtime, gmtime and inet_ntoa for threaded build. (jgdavidson)
+ * generic/tclIO.c: Calls TclpFinalizeSockets() as part of the
+ TclFinalizeIOSubsystem().
- * generic/tclScan.c (Tcl_ScanObjCmd): prevented ckfree being
- called on a pointer to NULL.
+ * unix/tclUnixSock.c: Added no-op TclpFinalizeSockets().
-2002-02-07 Don Porter <dgp@users.sourceforge.net>
+ * win/tclWinPipe.c, win/tclWinSock.c: Finalization of sockets/pipes is
+ now solely done in TclpFinalizeSockets() and TclpFinalizePipes() and
+ not over the thread-exit handler, because the order of actions the Tcl
+ generic core will impose may result in cores/hangs if the thread exit
+ handler tears down corresponding subsystem(s) too early.
- * doc/DString.3:
- * doc/Encoding.3:
- * doc/GetCwd.3:
- * doc/SplitPath.3:
- * doc/Translate.3:
- * doc/Utf.3:
- * generic/tcl.decls:
- * generic/tcl.h:
- * generic/tclEncoding.c:
- * generic/tclEnv.c:
- * generic/tclFileName.c:
- * generic/tclIOUtil.c:
- * generic/tclUtf.c:
- * generic/tclUtil.c:
- * mac/tclMacInit.c:
- * unix/tclUnixFile.c:
- * unix/tclUnixInit.c:
- * unix/tclUnixPipe.c:
- * win/tclWin32Dll.c:
- * win/tclWinFCmd.c:
- * win/tclWinFile.c:
- * win/tclWinInit.c: Partial TIP 27 rollback. Following routines
- restored to return (char *): Tcl_DStringAppend,
- Tcl_DStringAppendElement, Tcl_JoinPath, Tcl_TranslateFileName,
- Tcl_ExternalToUtfDString, Tcl_UtfToExternalDString,
- Tcl_UniCharToUtfDString, Tcl_GetCwd, Tcl_WinTCharToUtf. Also
- restored Tcl_WinUtfToTChar to return (TCHAR *) and
- Tcl_UtfToUniCharDString to return (Tcl_UniChar *). Modified
- some callers. This change recognizes that Tcl_DStrings are
- de-facto white-box objects.
+2006-03-10 Vince Darley <vincentdarley@sourceforge.net>
- * generic/tclDecls.h:
- * generic/tclPlatDecls.h: make genstubs
+ * win/tclWinFile.c: previous patch breaks tests, so removed.
- * generic/tclCmdMZ.c: corrected use of C++-style comment.
+2006-03-09 Vince Darley <vincentdarley@sourceforge.net>
-2002-02-06 Jeff Hobbs <jeffh@ActiveState.com>
+ * win/tclWinFile.c: fix to 'file writable' in certain XP directories.
+ Thanks to fvogel and jfg. [Patch 1344540] Modified patch to make use
+ of existing use of getSecurityProc.
- * tests/scan.test:
- * generic/tclScan.c (Tcl_ScanObjCmd): corrected scan 0x... %x handling
- that didn't accept the 0x as a prelude to a base 16 number. [Bug
- 495213]
+2006-03-08 Don Porter <dgp@users.sourceforge.net>
- * generic/tclCompCmds.c (TclCompileRegexpCmd): made early check
- for bad RE to stop checking further.
+ * generic/tclExecute.c: Complete missing bit of TIP 215 implementation
+ * tests/incr.test:
- * generic/tclCmdMZ.c (Tcl_RegsubObjCmd): added special case to
- search for simple 'string map' style regsub calls.
- Delayed creation of resultPtr object until an initial match is
- made, as the input string object can then be reused for no matches.
- (Tcl_StringObjCmd): optimization improvements to the STR_MAP
- algorithm for zero-length and nocase cases.
+2006-03-07 Joe English <jenglish@users.sourceforge.net>
- * tests/regexp.test:
- * tests/regexpComp.test: extra code coverage tests.
+ * unix/tcl.m4: Set SHLIB_LD_FLAGS='${LIBS}' on NetBSD, as per the
+ other *BSD variants. [Bug 1334613]
+ * unix/configure: Regenerated.
- * tests/string.test: added 10.18 and 10.19 extra tests.
+2006-03-07 Don Porter <dgp@users.sourceforge.net>
- * generic/regc_locale.c (casecmp): slight performance improvement.
+ * changes: Update in prep. for 8.5a4 release.
-2002-02-05 Don Porter <dgp@users.sourceforge.net>
+ * unix/Makefile.in: Package http 2.5.2 requires Tcl 8.4, so the
+ * win/Makefile.in: *.tm installation has to be placed in an "8.4"
+ directory, not an "8.2" directory.
- * library/http/http.tcl:
- * library/http/pkgIndex.tcl: Corrected use of http::error when
- ::error was intended. Bump to http 2.4.2.
+2006-03-06 Don Porter <dgp@users.sourceforge.net>
-2002-02-04 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+ * generic/tclBasic.c: Revised handling of TCL_EVAL_* flags to
+ * tests/parse.test: simplify TclEvalObjvInternal and to correct
+ the auto-loading of alias targets (parse-8.12). [Bug 1444291]
- * unix/tclUnixChan.c (FileOutputProc): Fixed [bug 465765] reported by
- Dale Talcott <daletalcott@users.sourceforge.net>. Avoid writing
- nothing into a file as STREAM based implementations will consider this
- a EOF (if the file is a pipe). Not done in the generic layer as this
- type of writing is actually useful to check the state of a socket.
+2006-03-03 Don Porter <dgp@users.sourceforge.net>
- * doc/open.n: Fixed [Bug 511540], added cross-reference to 'pid' as
- the command to use to retrieve the pid of a command pipeline created
- via 'open'.
+ * generic/tclPathObj.c: Revised yesterday's fix for [Bug 1379287] to
+ work on Windows.
-2002-02-01 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclObj.c: Compatibility support for existing code that
+ calls Tcl_GetObjType("boolean").
- * generic/tclCmdMZ.c (Tcl_RegexpObjCmd): handle quirky about case
- earlier to avoid shimmering problem.
+2006-03-02 Don Porter <dgp@users.sourceforge.net>
-2002-02-01 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+ * generic/tclPathObj.c: Fix for failed normalization of paths
+ * tests/fileSystem.test: with /../ that lead back to the root
+ of the filesystem, like /foo/.. [Bug 1379287]
- * tests/io.test: io-39.22 split into two tests, one platform
- dependent, the other not. -eofchar is not empty on the windows
- platform.
+2006-03-01 Reinhard Max <max@suse.de>
-2002-02-01 Vince Darley <vincentdarley@users.sourceforge.net>
+ * unix/installManPage: Fix the script for manpages that have quotes
+ around the .SH arguments, as doctools produces them. [Bug 1292145]
+ Some minor cleanups and improvements.
- * generic/tclTest.c: fix to picky windows compiler problem with the
- 'MainLoop' function declaration.
+2006-02-28 Don Porter <dgp@users.sourceforge.net>
-2002-01-31 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+ * generic/tclBasic.c: Corrections to be sure that TCL_EVAL_GLOBAL
+ * tests/namespace.test: evaluations act the same as [uplevel #0]
+ * tests/parse.test: evaluations, even when execution traces or
+ * tests/trace.test: invocations of [::unknown] are present. [Bug
+ 1439836]
- * win/tclWinFCmd.c: TIP 27: Applied patch fixing CONST warnings on
- behalf of Don Porter <dgp@users.sourceforge.net>.
+2006-02-22 Don Porter <dgp@users.sourceforge.net>
-2002-01-30 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclBasic.c: Corrected a few bugs in how [namespace
+ * tests/namespace.test: unknown] interacts with TCL_EVAL_* flags.
+ [Patch 958222]
- * generic/tcl.decls:
- * generic/tcl.h:
- * generic/tclInt.h: For each interface identified in the TIP 27
- changes below as a POTENTIAL INCOMPATIBILITY, the source of the
- incompatibility has been parameterized so that it can be removed. When
- compiling extension code against the Tcl header files, use the
- compiler flag -DUSE_NON_CONST to remove the irresolvable source
- incompatibilities introduced by the TIP 27 changes. Resolvable changes
- are left for extension authors to resolve.
- * generic/tclDecls.h: make genstubs
+2006-02-17 Don Porter <dgp@users.sourceforge.net>
-2002-01-30 Vince Darley <vincentdarley@users.sourceforge.net>
+ * generic/tclIORChan.c: Revised error message generation and handling
+ * tests/ioCmd.test: of exceptional return codes in the channel
+ reflection layer. [Bug 1372348]
- * doc/FileSystem.3: added documentation for 3 public functions which
- had been overlooked. Fixes [Bug 507701]
- * unix/mkLinks: make mklinks
+2006-02-16 Don Porter <dgp@users.sourceforge.net>
-2002-01-29 Jeff Hobbs <jeffh@ActiveState.com>
+ * generic/tclIndexObj.c: Disallow the "ambiguous" error message
+ * tests/indexObj.test: when TCL_EXACT matching is requested.
+ * tests/ioCmd.test:
- * tests/regexpComp.test:
- * generic/tclCompCmds.c (TclCompileRegexpCmd): enhanced to support
- -nocase and -- options.
+2006-02-15 Don Porter <dgp@users.sourceforge.net>
-2002-01-28 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tclIO.c: Made several routines tolerant of
+ * generic/tclIORChan.c: interp == NULL arguments. [Bug 1380662]
+ * generic/tclIOUtil.c:
- * unix/tcl.m4 (SC_LOAD_TCLCONFIG):
- * win/tcl.m4 (SC_LOAD_TCLCONFIG): Set TCL_LIB_SPEC, TCL_STUB_LIB_SPEC,
- and TCL_STUB_LIB_PATH to the values of TCL_BUILD_LIB_SPEC,
- TCL_BUILD_STUB_LIB_SPEC, and TCL_BUILD_STUB_LIB_PATH when tclConfig.sh
- is loaded from the build directory. A Tcl extension should make use of
- the non-build versions of these variables since they will work in both
- cases. This modification was described in TIP #34.
+2006-02-09 Don Porter <dgp@users.sourceforge.net>
-2002-01-28 Jeff Hobbs <jeffh@ActiveState.com>
+ TIP#215 IMPLEMENTATION
- * win/tclWinReg.c (regConnectRegistryProc,RecursiveDeleteKey)
- (DeleteKey,GetKeyNames,GetType,GetValue,OpenSubKey,SetValue):
- redid the CONSTification as previous changes caused failing tests.
+ * doc/incr.n: Revised [incr] to auto-initialize when varName
+ * generic/tclExecute.c: argument is unset. [Patch 1413115]
+ * generic/tclVar.c:
+ * tests/compile.test:
+ * tests/incr-old.test:
+ * tests/incr.test:
+ * tests/set.test:
+
+ * tests/main.test (Tcl_Main-6.7): Improved robustness of
+ command auto-completion test. [Bug 1422736]
+
+2006-02-08 Donal K. Fellows <dkf@users.sf.net>
+
+ * doc/Encoding.3, doc/encoding.n: Updates due to review at request of
+ Don Porter. Mostly minor changes.
+
+2006-02-08 Don Porter <dgp@users.sourceforge.net>
+
+ TIP#258 IMPLEMENTATION
+
+ * doc/Encoding.3: New subcommand [encoding dirs].
+ * doc/encoding.n: New routine Tcl_GetEncodingNameFromEnvironment
+ * generic/tcl.decls: Made public:
+ * generic/tclBasic.c: TclGetEncodingFromObj
+ * generic/tclCmdAH.c: -> Tcl_GetEncodingFromObj
+ * generic/tclEncoding.c:TclGetEncodingSearchPath
+ * generic/tclInt.decls: -> Tcl_GetEncodingSearchPath
+ * generic/tclInt.h: TclSetEncodingSearchPath
+ * generic/tclTest.c: -> Tcl_SetEncodingSearchPath
+ * library/init.tcl: Removed commands:
+ * tests/cmdAH.test: [tcl::unsupported::EncodingDirs]
+ * tests/encoding.test: [testencoding path] (Tcltest)
+ * unix/tclUnixInit.c: [Patch 1413934]
+ * win/tclWinInit.c:
- * tests/regexpComp.test (new):
- * generic/tclInt.h:
- * generic/tclBasic.c: added TclCompileRegexpCmd entry
- * generic/tclCompCmds.c (TclCompileStringCmd): corrected to return
- TCL_OUT_LINE_COMPILE instead of TCL_ERROR for parsing errors, so
- it only throws the error for runtime compile, in case the user
- modifies 'string'.
- (TclCompileRegexpCmd): first try at a byte-compiled regexp
- command. It handles static strings and ^$ bounded static strings.
- (TclCompileAppendCmd): made TclPushVarName call always use
- TCL_CREATE_VAR as numWords is always > 2 at that point.
+ * generic/tclDecls.h: make genstubs
+ * generic/tclIntDecls.h:
+ * generic/tclStubInit.c:
- * generic/tclExecute.c (TclExecuteByteCode:INST_LIST): correct
- possibly dangerous decr in macro call.
+2006-02-01 Miguel Sofer <msofer@users.sf.net>
- * win/tclWinInit.c (TclpFindVariable): CONSTification touch-up
+ * generic/tclProc.c: minor improvements to [apply]
+ * tests/apply.test: new tests; apply-5.1 currently fails to indicate
+ missing work in error reporting
- * win/tclWinReg.c (OpenSubKey): corrected bug introduced in
- CONSTification that dropped pointer reference.
+2006-02-01 Don Porter <dgp@users.sourceforge.net>
- * ChangeLog.2000 (new file):
- * ChangeLog: broke changes from 2000 into ChangeLog.2000 to reduce
- size of the main ChangeLog.
+ TIP#194 IMPLEMENTATION
-2002-01-28 David Gravereaux <davygrvy@pobox.com>
+ * doc/apply.n: (New file) New command [apply]. [Patch 944803]
+ * doc/uplevel.n:
+ * generic/tclBasic.c:
+ * generic/tclInt.h:
+ * generic/tclProc.c:
+ * tests/apply.test: (New file)
+ * tests/proc-old.test:
+ * tests/proc.test:
- * generic/tclPlatDecls.h: Added preprocessor logic to force a typedef
- of TCHAR when __STDC__ is defined when using the uncommon -Za compiler
- switch with the microsoft compiler.
+ TIP#181 IMPLEMENTATION
-2002-01-27 Don Porter <dgp@users.sourceforge.net>
+ * doc/Namespace.3: New command [namespace unknown]. New public C
+ * doc/namespace.n: routines Tcl_(Get|Set)NamespaceUnknownHandler.
+ * doc/unknown.n: [Patch 958222]
+ * generic/tcl.decls:
+ * generic/tclBasic.c:
+ * generic/tclInt.h:
+ * generic/tclNamesp.c:
+ * tests/namespace.test:
- * doc/package.n: Documented global namespace context for script
- evaluation by [package require].
+ * generic/tclDecls.h: make genstubs
+ * generic/tclStubInit.c:
-2002-01-27 Daniel Steffen <das@users.sourceforge.net>
+ TIP#250 IMPLEMENTATION
- * generic/tclInt.decls:
- * generic/tclIntPlatDecls.h:
- * mac/tclMacChan.c:
- * mac/tclMacFCmd.c:
- * mac/tclMacFile.c:
- * mac/tclMacInit.c:
- * mac/tclMacLoad.c:
- * mac/tclMacResource.c:
- * mac/tclMacSock.c: TIP 27 CONSTification induced changes
-
- * tests/event.test:
- * tests/main.test: added catches/constraints to test that use features
- that don't exist on the mac.
-
-2002-01-25 Mo DeJong <mdejong@users.sourceforge.net>
-
- Make -eofchar and -translation options read only for server sockets.
- [Bug 496733]
-
- * generic/tclIO.c (Tcl_GetChannelOption, Tcl_SetChannelOption):
- Instead of returning nothing for the -translation option on a server
- socket, always return "auto". Return the empty string enclosed in
- quotes for the -eofchar option on a server socket. Fixup -eofchar
- usage message so that it matches the implementation.
- * tests/io.test: Add -eofchar tests and -translation tests to ensure
- options are read only on server sockets.
- * tests/socket.test: Update tests to account for -eofchar and
- -translation option changes.
-
-2002-01-25 Don Porter <dgp@users.sourceforge.net>
-
- * compat/strstr.c (strstr):
- * generic/tclCmdAH.c (Tcl_FormatObjCmd):
- * generic/tclCmdIL.c (InfoNameOfExecutableCmd):
- * generic/tclEnv.c (ReplaceString):
- * generic/tclFileName.c (ExtractWinRoot):
- * generic/tclIO.c (FlushChannel,Tcl_BadChannelOption):
- * generic/tclStringObj.c (AppendUnicodeToUtfRep):
- * generic/tclThreadTest.c (TclCreateThread):
- * generic/tclUtf.c (Tcl_UtfPrev):
- * mac/tclMacFCmd.c (TclpObjListVolumes):
- * mac/tclMacResource.c (TclMacRegisterResourceFork)
- (BuildResourceForkList):
- * win/tclWinInit.c (AppendEnvironment): Sought out and eliminated
- instances of CONST-casting that are no longer needed after the
- TIP 27 effort.
-
- * Following is [Patch 501006]
- * generic/tclInt.decls (Tcl_AddInterpResolvers, Tcl_Export)
- (Tcl_FindNamespace, Tcl_GetInterpResolvers, Tcl_ForgetImport)
- (Tcl_Import, Tcl_RemoveInterpResolvers):
- * generic/tclNamesp.c (Tcl_Export, Tcl_Import, Tcl_ForgetImport)
- (Tcl_FindNamespace):
- * generic/tclResolve.c (Tcl_AddInterpResolvers,Tcl_GetInterpResolvers,
- (Tcl_RemoveInterpResolvers): Updated APIs in generic/tclResolve.c and
- generic/tclNamesp.c according to the guidelines of TIP 27.
- * generic/tclIntDecls.h: make genstubs
-
- * Following is [Patch 505630]
- * doc/AddErrorInfo.3:
- * generic/tcl.decls (Tcl_LogCommandInfo):
- * generic/tclBasic.c (Tcl_LogCommandInfo): Updated interfaces
- of generic/tclBasic.cc according to TIP 27.
- * generic/tclDecls.h: make genstubs
-
- * Following is [Patch 506818]
- * doc/Hash.3:
- * generic/tcl.decls (Tcl_HashStats):
- * generic/tclHash.c (Tcl_HashStats): Updated APIs of generic/tclHash.c
- according to guidelines of TIP 27.
- * generic/tclDecls.h: make genstubs
- * generic/tclVar.c (Tcl_ArrayObjCmd): Updated callers.
-
- * Following is [Patch 506807]
- * doc/ObjectType.3:
- * generic/tcl.decls (Tcl_GetObjType):
- * generic/tclObj.c (Tcl_GetObjType): Updated APIs of generic/tclObj.c
- according to guidelines of TIP 27.
- * generic/tclDecls.h: make genstubs
-
- * Following is [Patch 507304]
- * doc/Encoding.3:
- * generic/tcl.decls (Tcl_WinUtfToTChar,Tcl_WinTCharToUtf):
- * win/tclWin32Dll.c (Tcl_WinUtfToTChar,Tcl_WinTCharToUtf):
- Updated interfaces in win/tclWin32Dll.c according to TIP 27.
- * generic/tclPlatDecls.h: make genstubs
- * generic/tclIOUtil.c (TclpNativeToNormalized):
- * win/tclWinFCmd.c (TclpObjNormalizePath):
- * win/tclWinFile.c (TclpFindExecutable,TclpMatchInDirectory)
- (NativeIsExec,NativeStat):
- * win/tclWinLoad.c (TclpLoadFile):
- * win/tclWinPipe.c (TclpOpenFile,ApplicationType):
- * win/tclWinReg.c (regConnectRegistryProc,RecursiveDeleteKey,DeleteKey)
- (GetKeyNames,GetType,GetValue,OpenSubKey,SetValue):
- * win/tclWinSerial.c (SerialSetOptionProc): Update callers.
-
- * Following is [Patch 505072]
- * doc/Concat.3:
- * doc/Encoding.3:
- * doc/Filesystem.3:
- * doc/Macintosh.3:
- * doc/OpenFileChnl.3
- * doc/SetResult.3:
- * doc/SetVar.3:
- * doc/SplitList.3:
- * doc/SplitPath.3:
- * doc/Translate.3:
- * generic/tcl.h (Tcl_FSMatchInDirectoryProc):
- * generic/tclInt.h (TclpMatchInDirectory):
- * generic/tcl.decls (Tcl_Concat,Tcl_GetStringResult,Tcl_GetVar,
- (Tcl_GetVar2,Tcl_JoinPath,Tcl_Merge,Tcl_OpenCommandChannel,Tcl_SetVar)
- (Tcl_SetVar2,Tcl_SplitList,Tcl_SplitPath,Tcl_TranslateFileName)
- (Tcl_ExternalToUtfDString,Tcl_GetEncodingName,Tcl_UtfToExternalDString)
- (Tcl_GetDefaultEncodingDir,Tcl_SetDefaultEncodingDir)
- (Tcl_FSMatchInDirectory,Tcl_MacEvalResource,Tcl_MacFindResource):
- * generic/tclInt.decls (TclCreatePipeline,TclGetEnv,TclpGetCwd,
- (TclpCreateProcess):
- * mac/tclMacFile.c (TclpGetCwd):
- * generic/tclEncoding.c (Tcl_GetDefaultEncodingDir)
- (Tcl_SetDefaultEncodingDir,Tcl_GetEncodingName)
- (Tcl_ExternalToUtfDString,Tcl_UtfToExternalDString, OpenEncodingFile)
- (LoadEscapeEncoding):
- * generic/tclFileName.c (DoTildeSubst,Tcl_JoinPath,Tcl_SplitPath,
- (Tcl_TranslateFileName):
- * generic/tclIOUtil.c (Tcl_FSMatchInDirectory):
- * generic/tclPipe.c (FileForRedirect,TclCreatePipeline)
- (Tcl_OpenCommandChannel):
- * generic/tclResult.c (Tcl_GetStringResult):
- * generic/tclUtil.c (Tcl_Concat,Tcl_SplitList,Tcl_Merge):
- * generic/tclVar.c (Tcl_GetVar,Tcl_GetVar2,Tcl_SetVar,Tcl_SetVar2):
- * mac/tclMacResource.c (Tcl_MacEvalResource,Tcl_MacFindResource):
- Updated interfaces of generic/tclEncoding, generic/tclFilename.c,
- generic/tclIOUtil.c, generic/tclPipe.c, generic/tclResult.c,
- generic/tclUtil.c, generic/tclVar.c and mac/tclMacResource.c according
- to TIP 27. Tcl_TranslateFileName rewritten as wrapper around
- VFS-aware version.
- ***POTENTIAL INCOMPATIBILITY***
- Includes source incompatibilities: argv arguments of Tcl_Concat,
- Tcl_JoinPath, Tcl_OpenCommandChannel, Tcl_Merge; argvPtr arguments of
- Tcl_SplitList and Tcl_SplitPath.
- * generic/tclDecls.h:
- * generic/tclIntDecls.h: make genstubs
-
- * generic/tclCkalloc.c (MemoryCmd):
- * generic/tclClock.c (FormatClock):
- * generic/tclCmdAH.c (Tcl_CaseObjCmd,Tcl_EncodingObjCmd,Tcl_FileObjCmd):
- * generic/tclCmdIL.c (InfoLibraryCmd,InfoPatchLevelCmd,
- (InfoTclVersionCmd):
- * generic/tclCompCmds.c (TclCompileForeachCmd):
- * generic/tclCompCmds.h (TclCompileForeachCmd):
- * generic/tclCompile.c (TclFindCompiledLocal):
- * generic/tclEnv.c (TclSetupEnv,TclSetEnv,Tcl_PutEnv,TclGetEnv,
- (EnvTraceProc):
- * generic/tclEvent.c (Tcl_BackgroundError):
- * generic/tclIO.c (Tcl_BadChannelOption,Tcl_SetChannelOption):
- * generic/tclIOCmd.c (Tcl_ExecObjCmd,Tcl_OpenObjCmd):
- * generic/tclIOSock.c (TclSockGetPort):
- * generic/tclIOUtil.c (SetFsPathFromAny):
- * generic/tclLink.c (LinkTraceProc):
- * generic/tclMain.c (Tcl_Main):
- * generic/tclNamesp.c (TclTeardownNamespace):
- * generic/tclProc.c (TclCreateProc):
- * generic/tclTest.c (TestregexpObjCmd,TesttranslatefilenameCmd,
- (TestchmodCmd,GetTimesCmd,TestsetCmd,TestOpenFileChannelProc1,
- (TestOpenFileChannelProc2,TestOpenFileChannelProc3,AsyncHandlerProc,
- (TestpanicCmd):
- * generic/tclThreadTest.c (ThreadErrorProc,ThreadEventProc):
- * generic/tclUtil.c (TclPrecTraceProc):
- * mac/tclMacFCmd.c (GetFileSpecs):
- * mac/tclMacFile.c (TclpMatchInDirectory):
- * mac/tclMacInit.c (TclpInitLibraryPath,Tcl_SourceRCFile):
- * mac/tclMacOSA.c (tclOSAStore,tclOSALoad):
- * mac/tclMacResource.c (Tcl_MacEvalResource):
- * unix/tclUnixFCmd.c (TclpObjNormalizePath):
- * unix/tclUnixFile.c (TclpMatchInDirectory,TclpGetUserHome,TclpGetCwd,
- (TclpReadLink):
- * unix/tclUnixInit.c (TclpInitLibraryPath,TclpSetVariables,
- (Tcl_SourceRCFile):
- * unix/tclUnixPipe.c (TclpOpenFile,TclpCreateTempFile,
- (TclpCreateProcess):
- * win/tclWinFile.c (TclpGetCwd,TclpMatchInDirectory):
- * win/tclWinInit.c (TclpInitLibraryPath,Tcl_SourceRCFile,
- (TclpSetVariables):
- * win/tclWinPipe.c (TclpCreateProcess): Updated callers.
-
-2002-01-24 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclIOUtil.c (SetFsPathFromAny): Corrected tilde-substitution
- of pathnames where > 1 separator follows the ~. [Bug 504950]
-
-2002-01-24 Jeff Hobbs <jeffh@ActiveState.com>
+ * doc/namespace.n: New command [namespace upvar]. [Patch 1275435]
+ * generic/tclInt.h:
+ * generic/tclNamesp.c:
+ * generic/tclVar.c:
+ * tests/namespace.test:
+ * tests/upvar.test:
- * library/http/pkgIndex.tcl:
- * library/http/http.tcl: don't add port in default case to handle
- broken servers. http bumped to 2.4.1 [Bug 504508]
-
-2002-01-23 Andreas Kupries <andreas_kupries@users.sourceforge.net>
-
- * unix/mkLinks: Regenerated.
- * doc/CrtChannel.3:
- * doc/ChnlStack.3: Moved documentation for 'Tcl_GetTopChannel' from
- 'CrtChannel' to 'ChnlStack'. Added documentation of
- 'Tcl_GetStackedChannel'. [Bug 506147] reported by Mark Patton
- <msp@users.sourceforge.net>
-
-2002-01-23 Don Porter <dgp@users.sourceforge.net>
-
- * win/tclWinFile.c (NativeAccess,NativeStat,NativeIsExec,
- (TclpGetUserHome):
- * win/tclWinPort.h (TclWinSerialReopen):
- * win/tclWinSerial.c (TclWinSerialReopen):
- * win/tclWinSock.c (Tcl_OpenTcpServer): Corrections to earlier TIP
- #27 changes. Thanks to Andreas Kupries for the feedback.
- * generic/tclPlatDecls.h: make genstubs
-
- * doc/GetHostName.3:
- * doc/GetOpnFl.3:
- * doc/OpenTcp.3:
- * tcl.decls (Tcl_GetHostName,Tcl_GetOpenFile,Tcl_OpenTcpClient,
- (Tcl_OpenTclServer):
- * mac/tclMacSock.c (CreateSocket,Tcl_OpenTcpClient,Tcl_OpenTcpServer,
- (Tcl_GetHostName,GetHostFromString):
- * unix/tclUnixChan.c (CreateSocket,CreateSocketAddress,
- (Tcl_OpenTcpClient,Tcl_OpenTcpServer,Tcl_GetOpenFile):
- * unix/tclUnixSock.c (Tcl_GetHostName):
- * win/tclWinSock.c (CreateSocket,CreateSocketAddress,
- (Tcl_OpenTcpClient,Tcl_OpenTcpServer,Tcl_GetHostName):
- Updated socket interfaces according to TIP 27.
- * generic/tclCmdIL.c (InfoHostnameCmd): Updated callers.
- * generic/tclDecls.h: make genstubs
-
-2002-01-21 David Gravereaux <davygrvy@pobox.com>
-
- * generic/tclLoadNone.c: TclpLoadFile() didn't match proto of typedef
- Tcl_FSLoadFileProc. OK'd by vincentdarley. [Patch 502488]
-
-2002-01-21 Andreas Kupries <andreas_kupries@users.sourceforge.net>
-
- * generic/tclIO.c (WriteChars): Fix for [Bug 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.
-
-2002-01-21 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclTest.c: Converted declarations of TestReport file system
- to more portable form. [Bug 501417].
-
- * generic/tcl.decls (Tcl_TraceCommand,Tcl_UntraceCommand,
- (Tcl_CommandTraceInfo):
- * generic/tclCmdMZ.c (Tcl_TraceCommand,Tcl_UntraceCommand,
- (Tcl_CommandTraceInfo): Updated APIs in generic/tclCmdMZ.c
- according to the guidelines of TIP 27.
- * generic/tclDecls.h: make genstubs
-
-2002-01-18 Don Porter <dgp@users.sourceforge.net>
+2006-01-26 Donal K. Fellows <dkf@users.sf.net>
- * win/tclWinChan.c:
- * win/tclWinFCmd.c:
- * win/tclWinFile.c: Overlooked callers of Tcl_FSGetNativePath
+ * doc/dict.n: Fixed silly bug in example. Thanks to Heiner Marxen
+ <heiner.marxen@unsel.de> for catching this! [Bug 1415725]
- * win/tclWinDde.c:
- * win/tclWinReg.c: Overlooked callers of Tcl_GetIndexFromObj
+2006-01-26 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
-2002-01-18 Daniel Steffen <das@users.sourceforge.net>
+ * unix/tclUnixChan.c (TclpOpenFileChannel): Tidy up and comment the
+ mess to do with setting up serial channels. This (deliberately) breaks
+ a broken FreeBSD port, indicates what we're really doing, and reduces
+ the amount of conditional compilation sections for better maintenance.
- * generic/tclThreadTest.c:
- * mac/tclMacChan.c:
- * mac/tclMacFCmd.c:
- * mac/tclMacFile.c:
- * mac/tclMacLoad.c:
- * mac/tclMacResource.c: TIP 27 CONSTification broke the mac build in a
- number of places.
+2006-01-25 Donal K. Fellows <dkf@users.sf.net>
-2002-01-17 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+ * unix/tclUnixInit.c (TclpInitPlatform): Improved conditions on when
+ to update the FP rounding mode on FreeBSD, taken from FreeBSD port.
- * generic/tclIOCmd.c (Tcl_GetsObjCmd): Fixed [Bug 504642] as reported
- by Brian Griffin <bgriffin@users.sourceforge.net>, using his patch.
- Before the patch the generic I/O layer held an unannounced reference
- to the interp result to store the read line into. This unfortunately
- has disastrous results if the channel driver executes a Tcl script to
- perform its operation, this freeing the interp result. In that case we
- are dereferencing essentially a dangling reference. It is not truly
- dangling because the object is in the free list, but this only causes
- us to smash the free list and have the error occur later somewhere
- else. The patch simply creates a new object for the line and later
- sets it into the interp result when we are done with reading.
+2006-01-23 Donal K. Fellows <dkf@users.sf.net>
-2002-01-16 Mo DeJong <mdejong@users.sourceforge.net>
+ * tests/string.test (string-12.21): Added test for [Bug 1410553] based
+ on original bug report.
- * unix/tcl.m4 (SC_LOAD_TCLCONFIG):
- * win/tcl.m4 (SC_LOAD_TCLCONFIG): Subst TCL_DBGX into
- TCL_STUB_LIB_FILE and TCL_STUB_LIB_FLAG variables so that an extension
- does not need to subst TCL_DBGX into its makefile. [Tk Bug 504356]
+2006-01-23 Miguel Sofer <msofer@users.sf.net>
-2002-01-16 Don Porter <dgp@users.sourceforge.net>
+ * generic/tclStringObj.c: fixed incorrect handling of internal rep in
+ Tcl_GetRange. Thanks to twylite and Peter Spjuth. [Bug 1410553]
- * doc/FileSystem.3:
- * doc/GetCwd.3:
- * doc/GetIndex.3:
- * generic/tcl.decls (Tcl_GetIndexFromObj, Tcl_GetIndexFromObjStruct,
- (Tcl_GetCwd, Tcl_FSFileAttrStrings, Tcl_FSGetNativePath,
- (Tcl_FSGetTranslatedStringPath):
- * generic/tcl.h (Tcl_FSFileAttrStringsProc):
- * generic/tclFCmd.c (TclFileAttrsCmd):
- * generic/tclIOUtil.c (Tcl_GetCwd,NativeFileAttrStrings,
- (Tcl_FSFileAttrStrings,Tcl_FSGetTranslatedStringPath,
- (Tcl_FSGetNativePath):
- * generic/tclIndexObj.c (Tcl_GetIndexFromObj,Tcl_GetIndexFromObjStruct):
- More TIP 27 updates in tclIOUtil.c and tclIndexObj.c that were
- overlooked before. [Patch 504671]
- ***POTENTIAL INCOMPATIBILITY***
- Includes a source incompatibility in the tablePtr arguments of the
- Tcl_GetIndexFromObj* routines.
- * generic/tclDecls.h: make genstubs
-
- * generic/tclBinary.c (Tcl_BinaryObjCmd):
- * generic/tclClock.c (Tcl_ClockObjCmd):
- * generic/tclCmdAH.c (Tcl_EncodingObjCmd, Tcl_FileObjCmd):
- * generic/tclCmdIL.c (Tcl_InfoObjCmd,Tcl_LsearchObjCmd,Tcl_LsortObjCmd):
- * generic/tclCmdMZ.c (Tcl_TraceObjCmd,Tcl_RegexpObjCmd,Tcl_RegsubObjCmd,
- (Tcl_StringObjCmd,Tcl_SubstObjCmd,Tcl_SwitchObjCmd,
- (TclTraceCommandObjCmd,TclTraceVariableObjCmd):
- * generic/tclCompCmds.c (TclCompileStringCmd):
- * generic/tclEvent.c (Tcl_UpdateObjCmd):
- * generic/tclFileName.c (Tcl_GlobObjCmd):
- * generic/tclIO.c (Tcl_FileEventObjCmd):
- * generic/tclIOCmd.c (Tcl_SeekObjCmd,Tcl_ExecObjCmd,Tcl_SocketObjCmd,
- (Tcl_FcopyObjCmd):
- * generic/tclInterp.c (Tcl_InterpObjCmd,SlaveObjCmd):
- * generic/tclNamesp.c (Tcl_NamespaceObjCmd):
- * generic/tclPkg.c (Tcl_PackageObjCmd):
- * generic/tclTest.c (Tcltest_Init,TestencodingObjCmd,TestgetplatformCmd,
- (TestlocaleCmd,TestregexpObjCmd,TestsaveresultCmd,
- (TestGetIndexFromObjStructObjCmd,TestReportFileAttrStrings):
- * generic/tclTestObj.c (TestindexObjCmd,TeststringObjCmd):
- * generic/tclTimer.c (Tcl_AfterObjCmd):
- * generic/tclVar.c (Tcl_ArrayObjCmd):
- * mac/tclMacFCmd.c (SetFileFinderAttributes):
- * unix/tclUnixChan.c (TclpOpenFileChannel):
- * unix/tclUnixFCmd.c (tclpFileAttrStrings):
- * unix/tclUnixFile.c (TclpObjAccess,TclpObjChdir,TclpObjStat,
- (TclpObjLstat):
- * win/tclWinFCmd.c (tclpFileAttrStrings): Updated callers.
-
- * doc/RegExp.3:
- * doc/Utf.3:
- * generic/tcl.decls:
- * generic/tclInt.decls:
- * generic/tclRegexp.c:
- * generic/tclUtf.c: Updated APIs in generic/tclUtf.c and
- generic/tclRegexp.c according to the guidelines of TIP 27.
- [Patch 471509]
-
- * generic/regc_locale.c (element,cclass):
- * generic/tclCmdMZ.c (Tcl_StringObjCmd):
- * generic/tclFileName.c (TclpGetNativePathType,SplitMacPath):
- * generic/tclIO.c (ReadChars):
- * mac/tclMacLoad.c (TclpLoadFile):
- * win/tclWinFile.c (TclpGetUserHome): Updated callers.
-
- * generic/tclDecls.h:
- * generic/tclIntDecls.h: make genstubs
-
- * doc/ParseCmd.3 (Tcl_ParseVar):
- * generic/tcl.decls (Tcl_ParseVar):
- * generic/tclParse.c (Tcl_ParseVar):
- * generic/tclTest.c (TestparsevarObjCmd): Updated APIs in
- generic/tclParse.c according to the guidelines of TIP 27. Updated
- callers. [Patch 501046]
- * generic/tclDecls.h: make genstubs
-
- * generic/tcl.decls (Tcl_RecordAndEval):
- * generic/tclDecls.h: make genstubs
- * generic/tclHistory.c (Tcl_RecordAndEval): Updated APIs in
- generic/tclHistory.c according to the guidelines of TIP 27.
- [Patch 504091]
-
- * doc/CrtSlave.3:
- * generic/tcl.decls (Tcl_CreateAlias, Tcl_CreateAliasObj,
- (Tcl_CreateSlave, Tcl_GetAlias, Tcl_GetAliasObj, Tcl_GetSlave):
- * generic/tclInterp.c (Tcl_CreateAlias, Tcl_CreateAliasObj,
- (Tcl_CreateSlave, Tcl_GetAlias, Tcl_GetAliasObj, Tcl_GetSlave):
- Updated APIs in the file generic/tclInterp.c according to the
- guidelines of TIP 27. [Patch 501371]
- ***POTENTIAL INCOMPATIBILITY***
- Includes a source incompatibility in the targetCmdPtr arguments of
- the Tcl_GetAlias* routines.
-
- * generic/tclDecls.h: make genstubs
-
-2002-01-15 Don Porter <dgp@users.sourceforge.net>
-
- * doc/SetErrno.3 (Tcl_ErrnoMsg): Corrected documentation for
- Tcl_ErrnoMsg; it takes an integer argument. Thanks to Georgios
- Petasis. [Bug 468183]
-
- * doc/AddErrInfo.3 (Tcl_PosixError):
- * doc/Eval.3 (Tcl_EvalFile):
- * doc/FileSystem.c (Tcl_FSOpenFileChannel,Tcl_FSOpenFileChannelProc):
- * doc/OpenFileChnl.3 (Tcl_OpenFileChannel):
- * doc/SetErrno.3 (Tcl_ErrnoId,Tcl_ErrnoMsg):
- * doc/Signal.3 (Tcl_SignalId,Tcl_SignalMsg):
- * generic/tcl.decls (Tcl_ErrnoId,TclErrnoMsg,Tcl_EvalFile,
- (Tcl_OpenFileChannel,Tcl_PosixError,Tcl_SignalId,Tcl_SignalMsg,
- (Tcl_FSOpenFileChannel):
- * generic/tcl.h (Tcl_FSOpenFileChannelProc):
- * generic/tclIO.c (FlushChannel):
- * generic/tclIOUtil.c (Tcl_OpenFileChannel,Tcl_EvalFile,TclGetOpenMode,
- (Tcl_PosixError,Tcl_FSOpenFileChannel):
- * generic/tclInt.decls (TclGetOpenMode):
- * generic/tclInt.h (TclOpenFileChannelProc_,TclGetOpenMode,
- (TclpOpenFileChannel):
- * generic/tclPipe.c (TclCleanupChildren):
- * generic/tclPosixStr.c (Tcl_ErrnoId,Tcl_ErrnoMsg,Tcl_SignalId,
- (Tcl_SignalMsg):
- * generic.tclTest.c (PretendTclpOpenFileChannel,
- (TestOpenFileChannelProc1,TestOpenFileChannelProc2,
- (TestOpenFileChannelProc3,TestReportOpenFileChannel):
- * mac/tclMacChan.c (TclpOpenFileChannel):
- * unix/tclUnixChan.c (TclpOpenFileChannel):
- * win/tclWinChan.c (TclpOpenFileChannel): Updated APIs in
- generic/tclIOUtil.c and generic/tclPosixStr.c according to the
- guidelines of TIP 27. Updated callers. [Patch 499196]
-
- * generic/tclDecls.h:
- * generic/tclIntDecls.h: make genstubs
-
- * doc/CrtChannel.3:
- * doc/OpenFileChnl.3:
- * generic/tcl.decls:
- * generic/tclIO.h:
- * generic/tclIO.c (DoWrite, Tcl_RegisterChannel, Tcl_GetChannel,
- (Tcl_CreateChannel, Tcl_GetChannelName, CloseChannel, Tcl_Write,
- (Tcl_WriteRaw, Tcl_Ungets, Tcl_BadChannelOption, Tcl_GetChannelOption,
- (Tcl_SetChannelOption, Tcl_GetChannelNamesEx, Tcl_ChannelName):
- Updated APIs in the file generic/tclIO.c according to the guidelines
- of TIP 27. Several minor documentation corrections as well. [Patch
- 503565]
- * generic/tclDecls.h: make genstubs
-
- * generic/tcl.h (Tcl_DriverOutputProc, Tcl_DriverGetOptionProc,
- (Tcl_DriverSetOptionProc):
- * generic/tclIOGT.c (TransformOutputProc, TransformGetOptionProc,
- (TransformSetOptionProc):
- * mac/tclMacChan.c (FileOutput, StdIOOutput):
- * man/tclMacSock.c (TcpGetOptionProc, TcpOutput):
- * unix/tclUnixChan.c (FileOutputProc, TcpGetOptionProc, TcpOutputProc,
- (TtyGetOptionProc, TtySetOptionProc):
- * unix/tclUnixPipe.c (PipeOuputProc):
- * win/tclWinChan.c (FileOutputProc):
- * win/tclWinConsole.c (ConsleOutputProc):
- * win/tclWinPipe.c (PipeOuputProc):
- * win/tclWinSerial.c (SerialOutputProc, SerialGetOptionProc,
- (SerialSetOptionProc):
- * win/tclWinSock.c (TcpGetOptionProc, TcpOutput): Updated channel
- driver interface according to the guidelines of TIP 27. See also [Bug
- 500348].
-
- * doc/CrtChannel.3:
- * generic/tcl.h:
- * generic/tclIO.c:
- * generic/tclIO.h:
- * generic/tclInt.h:
- * tools/checkLibraryDoc.tcl:
- Moved Tcl_EolTranslation enum declaration from generic/tcl.h to
- generic/tclInt.h (renamed to TclEolTranslation). It is not used
- anywhere in Tcl's public interface.
+ * generic/tclProc.c: fixed args handling for precompiled bodies [Bug
+ 1412695]; thanks to Uwe Traum.
-2002-01-14 Don Porter <dgp@users.sourceforge.net>
+2006-01-16 Reinhard Max <max@suse.de>
- * doc/GetIndex.3:
- * doc/WrongNumArgs.3:
- * generic/tcl.decls (Tcl_GetIndexFromObj, Tcl_GetIndexFromObjStruct,
- (Tcl_WrongNumArgs):
- * generic/tclIndexObj.c (Tcl_GetIndexFromObj, Tcl_GetIndexFromObjStruct,
- (Tcl_WrongNumArgs): Updated APIs in the file generic/tclIndexObj.c
- according to the guidelines of TIP 27. [Patch 501491]
- * generic/tclDecls.h: make genstubs
+ * generic/tclPipe.c (FileForRedirect): Prevent nameString from being
+ freed without having been initialized.
+ * tests/exec.test: Added a test for the above.
-2002-01-11 Mo DeJong <mdejong@users.sourceforge.net>
+2006-01-12 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
- * unix/configure: Regen.
- * unix/configure.in:
- * win/configure: Regen.
- * win/configure.in: Use ${libdir} instead of ${exec_prefix}/lib
- to properly support the --libdir option to configure. [Bug 489370]
-
-2002-01-11 Andreas Kupries <andreas_kupries@users.sourceforge.net>
-
- * win/tclWinSerial.c (SerialSetOptionProc): Applied patch for [Bug
- 500348] supplied by Rolf Schroedter <schroedter@users.sf.net>. The
- function modified the contents of the the 'value' string and now does
- not do this anymore. This is a followup to the change made on
- 2001-12-17.
-
-2002-01-11 David Gravereaux <davygrvy@pobox.com>
-
- * win/makefile.vc: Removed -GD compiler option. It was intended for
- future use, but MS is again changing the future at their whim. The
- D4002 warning was harmless though, but someone using VC .NET logged it
- as a concern. [Bug 501565]
-
-2002-01-11 Mo DeJong <mdejong@users.sourceforge.net>
-
- * unix/Makefile.in: Burn Tcl build directory into tcltest executable
- to avoid crashes caused by ld loading a previously installed version
- of the tcl shared library. [Bug 218110]
-
-2002-01-10 Don Porter <dgp@users.sourceforge.net>,
- Kevin Kenny <kennykb@users.sourceforge.net>
-
- * unix/tclLoadDld.c (TclpLoadFile): syntax error: unbalanced parens.
- Kevin notes that it's far from clear that this file is ever included
- in an actual build; Linux without dlopen appears to be a nonexistent
- configuration.
-
-2002-01-08 Don Porter <dgp@users.sourceforge.net>,
- Kevin Kenny <kennykb@users.sourceforge.net>
-
- * doc/StaticPkg.3 (Tcl_StaticPackage):
- * generic/tcl.decls (Tcl_StaticPackage):
- * generic/tclDecls.h (Tcl_StaticPackage):
- * generic/tclInt.decls (TclGuessPackageName):
- * generic/tclInt.h (TclGuessPackageName):
- * generic/tclLoad.c (Tcl_StaticPackage):
- * generic/tclLoadNone.c (TclGuessPackageName):
- * mac/tclMacLoad.c (TclGuessPackageName):
- * unix/tclLoadAout.c (TclGuessPackageName):
- * unix/tclLoadDl.c (TclGuessPackageName):
- * unix/tclLoadDld.c (TclGuessPackageName):
- * unix/tclLoadDyld.c (TclGuessPackageName):
- * unix/tclLoadNext.c (TclGuessPackageName):
- * unix/tclLoadOSF.c (TclGuessPackageName):
- * unix/tclLoadShl.c (TclGuessPackageName):
- * win/tclWinLoad.c (TclGuessPackageName): Updated APIs in the files
- */tcl*Load*.c according to the guidelines of TIP 27. [Patch 501096]
-
-2002-01-09 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclTest.c (MainLoop):
- * tests/main.test (Tcl_Main-1.{3,4,5,6}): Corrected some non-portable
- tests from the new Tcl_Main changes. Thanks to Kevin Kenny.
-
-2002-01-07 Don Porter <dgp@users.sourceforge.net>
-
- * generic/tclEvent.c (TclInExit):
- * generic/tclIOUtil.c (SetFsPathFromAbsoluteNormalized,
- (SetFsPathFromAny,Tcl_FSNewNativePath,DupFsPathInternalRep):
- * generic/tclListObj.c (TclLsetList,TclLsetFlat): Added some type
- casts to satisfy picky compilers.
-
- * generic/tclMain.c: Bug fix: neglected the NULL case in
- TclGetStartupScriptFileName(). Broke Tk/wish.
-
-2002-01-05 Don Porter <dgp@users.sourceforge.net>
-
- * doc/Tcl_Main.3:
- * generic/tclMain.c: Substantial rewrite and expanded documentation
- of Tcl_Main to correct a number of bugs and flaws:
-
- * Interactive Tcl_Main can now enter a main loop, exit that
- loop and continue interactive operations. The loop may even
- exit in the midst of interactive command typing without loss
- of the partial command. [Bugs 486453, 474131]
- * Tcl_Main now gracefully handles deletion of its master
- interpreter.
- * Interactive Tcl_Main can now operate with non-blocking stdin
- * Interactive Tcl_Main can now detect EOF on stdin even in
- mid-command. [Bug 491341]
- * Added VFS-aware internal routines for managing the startup
- script selection.
- * Tcl variable 'tcl_interactive' is now linked to C variable
- 'tty' so that one can disable/enable interactive prompts at
- the script level when there is no startup script. This is
- meant for use by the test suite.
- * Consistent use of the Tcl libraries standard channels as
- returned by Tcl_GetStdChannel(); as opposed to the channels
- named 'stdin', 'stdout', and 'stderr' in the master interp,
- which can be different or unavailable.
- * Tcl_Main now calls Tcl_Exit() if evaluation of [exit] in the
- master interpreter returns, assuring Tcl_Main does not
- return.
- * Documented Tcl_Main's absence from public stub table
- * Documented that Tcl_Main does not return.
- * Documented Tcl variables set by Tcl_Main.
- * All prompts are done from a single procedure, Prompt.
- * Use of Tcl_Obj-enabled interfaces everywhere.
-
- * generic/tclInt.decls (TclGetStartupScriptPath,
- (TclSetStartupScriptPath): New internal VFS-aware routines for
- managing the startup script of Tcl_Main.
- * generic/tclIntDecls.h:
- * generic/tclStubInit.c: make genstubs
+ * generic/tclPathObj.c (Tcl_FSGetInternalRep): backported patch from
+ core-8-4-branch. A freed pointer has been overwritten causing all
+ sorts of coredumps.
- * generic/tclTest.c (TestsetmainloopCmd,TestexitmainloopCmd,
- (Tcltest_Init,TestinterpdeleteCmd):
- * tests/main.test (new): Added new file to test suite that thoroughly
- tests generic/tclMain.c; added some new test commands for testing
- Tcl_SetMainLoop().
+2006-01-12 Vince Darley <vincentdarley@sourceforge.net>
-2002-01-04 Don Porter <dgp@users.sourceforge.net>
+ * win/tclWinFile.c: fix to sharing violation [Bug 1366227]
- * doc/Alloc.3:
- * doc/Concat.3:
- * doc/CrtMathFnc.3:
- * doc/Hash.3:
- * doc/Interp.3:
- * doc/LinkVar.3:
- * doc/ObjectType.3:
- * doc/PkgRequire.3:
- * doc/Preserve.3:
- * doc/SetResult.3:
- * doc/SplitList.3:
- * doc/SplitPath.3:
- * doc/TCL_MEM_DEBUG.3: Updated documentation to describe the ckalloc,
- ckfree, ckrealloc, attemptckalloc, and attemptckrealloc macros, and to
- accurately describe when and how they are used. [Bug 497459]
+2006-01-11 Don Porter <dgp@users.sourceforge.net>
- * generic/tclThreadJoin.c (TclRememberJoinableThread,TclJoinThread):
- Replaced Tcl_Alloc and Tcl_Free calls with ckalloc and ckfree so that
- memory debugging is supported.
+ * generic/tclBasic.c: Moved Tcl_LogCommandInfo from tclBasic.c to
+ * generic/tclNamesp.c: tclNamesp.c to get access to identifier with
+ * tests/error.test (error-7.0): file scope. Added check for traces on
+ ::errorInfo, and when present fall back to contruction of the stack
+ trace in the variable so that write trace notification timings are
+ compatible with earlier Tcl releases. This reduces, but does not
+ completely eliminate the ***POTENTIAL INCOMPATIBILITY*** created by
+ the 2004-10-15 commit. [Bug 1397843]
-2002-01-04 Daniel Steffen <das@users.sourceforge.net>
+2006-01-10 Daniel Steffen <das@users.sourceforge.net>
- * mac/tclMacTime.c (TclpGetTZName): fix for daylight savings TZName
- bug
+ * unix/configure: add caching, use AC_CACHE_CHECK instead of
+ * unix/configure.in: AC_CACHE_VAL where possible, consistent message
+ * unix/tcl.m4: quoting, sync relevant tclconfig/tcl.m4 changes
+ and gratuitous formatting differences, fix SC_CONFIG_MANPAGES with
+ default argument, Darwin improvements to SC_LOAD_*CONFIG.
-2002-01-03 Don Porter <dgp@users.sourceforge.net>
+2006-01-09 Don Porter <dgp@users.sourceforge.net>
- * doc/FileSystem.3:
- * generic/tclIOUtil.c: Updated some old uses of "fileName" to new VFS
- terminology, "pathPtr".
+ * generic/tclNamesp.c (NamespaceInscopeCmd): [namespace inscope]
+ * tests/namespace.test: commands were not reported by [info level].
+ [Bug 1400572]
-2002-01-03 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+2006-01-09 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
- * tests/basic.test (basic-39.4): Greatly simplified test while still
- leaving it so that it crashes when run without the fix to the
- [foreach] implementation.
- * generic/tclCmdAH.c (Tcl_ForeachObjCmd): Stopped [Bug 494348] from
- happening by not trying to be so clever with cacheing; if nothing
- untoward is happening anyway, the less efficient technique will only
- add a few instruction cycles (one function call and a few
- derefs/assigns per list per iteration, with no change in the number of
- tests) and if something odd *is* going on, the code is now far more
- robust.
+ * generic/tclTrace.c: Stop exporting the guts of the trace command;
+ nothing outside this file needs to see it. [Bug 971336]
- * tests/basic.test (basic-39.4): Reproducable script from [Bug 494348]
+2006-01-05 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
-2002-01-02 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+ * unix/tcl.m4 (TCL_CONFIG_SYSTEM): Factor out the code to determine
+ the operating system version number, as it was replicated in several
+ places.
- * tests/util.test (Wrapper_Tcl_StringMatch,util-5.*): Rewrote so the
- test is performed with the right internal function since [string
- match] no longer uses Tcl_StringCaseMatch internally.
+2006-01-04 David Gravereaux <davygrvy@pobox.com>
- * tests/string.test (string-11.51):
- * generic/tclUtf.c (Tcl_UniCharCaseMatch):
- * generic/tclUtil.c (Tcl_StringCaseMatch): Fault with matching
- case-insensitive non-ASCII patterns containing upper case characters.
- [Bug 233257]
+ * win/tclAppInit.c: WIN32 native console signal handler removed. This
+ was found to be interfering with TWAPI extension one. IMO, special
+ services such as signal handlers should best be done with extensions
+ to the core after discussions on c.l.t. about Roy Terry's tclsh
+ children of a real windows service shell.
******************************************************************
+ *** 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.1999 b/ChangeLog.1999
index a7483a0..3bf4e9a 100644
--- a/ChangeLog.1999
+++ b/ChangeLog.1999
@@ -15,7 +15,7 @@
* unix/Makefile.in: added -srcdir=... for 'make html'
- * doc/Hash.3: fixed reference to ckfree [Bug: 3912]
+ * doc/Hash.3: fixed reference to ckfree [Bug 3912]
* doc/RegExp.3: fixed calling params for Tcl_RegExecFromObj
* doc/open.n: fixed minor formatting errors
* doc/string.n: fixed minor formatting errors
@@ -24,12 +24,12 @@
* tests/cmdIL.test:
* generic/tclCmdIL.c: added -unique option to lsort
- * generic/tclThreadTest.c: changed thread ids to longs [Bug: 3902]
+ * generic/tclThreadTest.c: changed thread ids to longs [Bug 3902]
- * mac/tclMacOSA.c: fixed applescript for I18N [Bug: 3644]
+ * mac/tclMacOSA.c: fixed applescript for I18N [Bug 3644]
* win/mkd.bat:
- * win/rmd.bat: removed necessity of tag.txt [Bug: 3874]
+ * win/rmd.bat: removed necessity of tag.txt [Bug 3874]
* win/tclWinThrd.c: changed CreateThread to _beginthreadex and
ExitThread to _endthreadex
@@ -47,43 +47,43 @@
* mac/tclMacFile.c:
* unix/tclUnixFile.c:
* win/tclWinFile.c: enhanced the glob command with the new options
- -types -path -directory and -join. Deprecated TclpMatchFiles with
+ -types -path -directory and -join. Deprecated TclpMatchFiles with
TclpMatchFilesTypes, extended TclGlob and TclDoGlob and added
- GlobTypeData structure. [Bug: 2363]
+ GlobTypeData structure. [Bug 2363]
1999-12-10 Jeff Hobbs <hobbs@scriptics.com>
* tests/var.test:
- * generic/tclCompile.c: fixed problem where setting to {} array
- would intermittently not work. (Fontaine) [Bug: 3339]
+ * generic/tclCompile.c: fixed problem where setting to {} array would
+ intermittently not work. [Bug 3339] (Fontaine)
* generic/tclCmdMZ.c:
- * generic/tclExecute.c: optimized INST_TRY_CVT_TO_NUMERIC to
- recognize boolean objects. (Spjuth) [Bug: 2815]
+ * generic/tclExecute.c: optimized INST_TRY_CVT_TO_NUMERIC to recognize
+ boolean objects. [Bug 2815] (Spjuth)
* tests/info.test:
* tests/parseOld.test:
* generic/tclCmdAH.c:
* generic/tclProc.c: changed Tcl_UplevelObjCmd (uplevel) and
- Tcl_EvalObjCmd (eval) to use TCL_EVAL_DIRECT in the single arg
- case as well, to take advantage of potential pure list input
- optimization. This means that it won't get byte compiled though,
- which should be acceptable.
- * generic/tclBasic.c: made Tcl_EvalObjEx pure list object aware in
- the TCL_EVAL_DIRECT case for efficiency.
- * generic/tclUtil.c: made Tcl_ConcatObj pure list object aware,
- and return a list object in that case [Bug: 2098 2257]
+ Tcl_EvalObjCmd (eval) to use TCL_EVAL_DIRECT in the single arg case as
+ well, to take advantage of potential pure list input optimization.
+ This means that it won't get byte compiled though, which should be
+ acceptable.
+ * generic/tclBasic.c: made Tcl_EvalObjEx pure list object aware in the
+ TCL_EVAL_DIRECT case for efficiency.
+ * generic/tclUtil.c: made Tcl_ConcatObj pure list object aware, and
+ return a list object in that case [Bug 2098 2257]
* generic/tclMain.c: changed Tcl_Main to not constantly reuse the
commandPtr object (interactive case) as it could be shared. (Fellows)
* unix/configure.in:
* unix/tcl.m4:
- * unix/tclUnixPipe.c: removed checking for compatible vfork
- function and use of the vfork function. Modern VM systems rarely
- suffer any performance degradation when fork is used, and it
- solves multiple problems with vfork. Users that still want vfork
- can add -Dfork=vfork to the compile flags. [Bug: 942 2228 1312]
+ * unix/tclUnixPipe.c: removed checking for compatible vfork function
+ and use of the vfork function. Modern VM systems rarely suffer any
+ performance degradation when fork is used, and it solves multiple
+ problems with vfork. Users that still want vfork can add -Dfork=vfork
+ to the compile flags. [Bug 942 2228 1312]
1999-12-09 Jeff Hobbs <hobbs@scriptics.com>
@@ -96,44 +96,44 @@
* win/tclWinFCmd.c:
* win/tclWinInit.c:
* win/tclWinPipe.c:
- * win/tclWinSock.c: removed all code that supported Win32s. It
- was no longer officially supported, and likely didn't work anyway.
+ * win/tclWinSock.c: removed all code that supported Win32s. It was no
+ longer officially supported, and likely didn't work anyway.
* win/makefile.vc: removed 16 bit stuff, cleaned up.
* win/tcl16.rc:
* win/tclWin16.c:
- * win/winDumpExts.c: these files have been removed from the
- source tree (no longer necessary to build)
+ * win/winDumpExts.c: these files have been removed from the source
+ tree (no longer necessary to build)
1999-12-07 Jeff Hobbs <hobbs@scriptics.com>
- * tests/io.test: removed 'knownBug' tests that were for
- unsupported0, which is now fcopy (that already has tests)
+ * tests/io.test: removed 'knownBug' tests that were for unsupported0,
+ which is now fcopy (that already has tests)
* mac/tclMacPort.h: added utime.h include
* generic/tclDate.c:
- * unix/Makefile.in: fixed make gendate to swap const with CONST
- so it uses the Tcl defined CONST type [Bug: 3521]
+ * unix/Makefile.in: fixed make gendate to swap const with CONST so it
+ uses the Tcl defined CONST type [Bug 3521]
- * generic/tclIO.c: removed panic that could occur in FlushChannel
- when a "blocking" channel would receive EAGAIN, instead treating
- it the same as non-blocking. [Bug: 3773]
+ * generic/tclIO.c: removed panic that could occur in FlushChannel when
+ a "blocking" channel would receive EAGAIN, instead treating it the
+ same as non-blocking. [Bug 3773]
- * generic/tclUtil.c: fixed Tcl_ScanCountedElement to not step
- beyond the end of the counted string [Bug: 3336]
+ * generic/tclUtil.c: fixed Tcl_ScanCountedElement to not step beyond
+ the end of the counted string. [Bug 3336]
1999-12-03 Jeff Hobbs <hobbs@scriptics.com>
* doc/load.n: added note about NT's buggy handling of './' with
LoadLibrary
- * library/http2.1/http.tcl: fixed error handling in http::Event
- [Bug: 3752]
+ * library/http2.1/http.tcl: fixed error handling in http::Event. [Bug
+ 3752]
* tests/env.test: removed knownBug limitation from working test
- * tests/all.tcl: ensured that ::tcltest::testsDirectory would be
- set to an absolute path
+ * tests/all.tcl: ensured that ::tcltest::testsDirectory would be set
+ to an absolute path
* tests/expr-old.test:
* tests/parseExpr.test:
@@ -144,86 +144,82 @@
* generic/tclParseExpr.c:
* generic/tclUtil.c:
* generic/tclExecute.c: added TclCheckBadOctal routine to enhance
- error message checking for when users use invalid octal numbers
- (like 08), as well as replumbed the Expr*Funcs with a new
- VerifyExprObjType to simplify type handling. [Bug: 2467]
+ error message checking for when users use invalid octal numbers (like
+ 08), as well as replumbed the Expr*Funcs with a new VerifyExprObjType
+ to simplify type handling. [Bug 2467]
* tests/expr.test:
- * generic/tclCompile.c: fixed 'bad code length' error for
- 'expr + {[incr]}' case, with new test case [Bug: 3736]
- and seg fault on 'expr + {[error]}' (different cause) that
- was caused by a correct optimization that didn't correctly
- track how it was modifying the source string in the opt.
- The optimization was removed, which means that:
+ * generic/tclCompile.c: fixed 'bad code length' error for 'expr +
+ {[incr]}' case, with new test case [Bug 3736] and seg fault on 'expr
+ + {[error]}' (different cause) that was caused by a correct
+ optimization that didn't correctly track how it was modifying the
+ source string in the opt. The optimization was removed, which means
+ that:
expr 1 + {[string length abc]}
- will be not be compiled inline as before, but this should be
- written:
+ will be not be compiled inline as before, but this should be written:
expr {1 + [string length abc]}
- which will be compiled inline for speed. This prevents
+ which will be compiled inline for speed. This prevents:
expr 1 + {[mindless error]}
- from seg faulting, and only affects optimizations for
- degenerate cases [Bug: 3737]
+ from seg faulting, and only affects optimizations for degenerate cases
+ [Bug 3737]
1999-12-01 Scott Redman <redman@scriptics.com>
- * generic/tcl.decls :
- * generic/tclMain.c :
- * unix/tclAppInit.c:
+ * generic/tcl.decls:
+ * generic/tclMain.c:
+ * unix/tclAppInit.c:
* win/tclAppInit.c: Added two new internal functions,
- TclSetStartupScriptFileName() and TclGetStartupScriptFileName()
- and added hooks into the main() code for supporting TclPro and
- other "big" shells more easily without requiring a copy of the
- main() code.
-
+ TclSetStartupScriptFileName() and TclGetStartupScriptFileName() and
+ added hooks into the main() code for supporting TclPro and other "big"
+ shells more easily without requiring a copy of the main() code.
+
* generic/tclEncoding.c:
- * generic/tclEvent.c: Moved encoding-related startup code from
+ * generic/tclEvent.c: Moved encoding-related startup code from
tclEvent.c into the more appropriate tclEncoding.c.
-
+
1999-11-30 Jeff Hobbs <hobbs@scriptics.com>
* generic/tclIO.c: fix from Kupries for Tcl_UnstackChannel that
correctly handles resetting translation and encoding.
- * generic/tclLoad.c: #def'd out the unloading of DLLs at finalize
- time for Unix in TclFinalizeLoad. [Bug: 2560 3373] Should be
- parametrized to allow for user to specify unload or not.
+ * generic/tclLoad.c: #def'd out the unloading of DLLs at finalize time
+ for Unix in TclFinalizeLoad. [Bug 2560 3373] Should be parametrized
+ to allow for user to specify unload or not.
- * win/tclWinTime.c: fixed handling of %Z on NT for time zones
- that don't have DST.
+ * win/tclWinTime.c: fixed handling of %Z on NT for time zones that
+ don't have DST.
1999-11-29 Jeff Hobbs <hobbs@scriptics.com>
* library/dde1.1/pkgIndex.tcl:
- * library/reg1.0/pkgIndex.tcl: added supported for debugged
- versions of the libraries
+ * library/reg1.0/pkgIndex.tcl: added supported for debugged versions
+ of the libraries
* unix/tclUnixPipe.c: fixed PipeBlockModeProc to properly set
- isNonBlocking flag on pipe. [Bug: 1356 710]
+ isNonBlocking flag on pipe. [Bug 1356 710]
removed spurious fcntl call from PipeBlockModeProc
* tests/scan.test:
- * generic/tclScan.c: fixed scan where %[..] didn't match anything
- and added test case [Bug: 3700]
+ * generic/tclScan.c: fixed scan where %[..] didn't match anything and
+ added test case. [Bug 3700]
1999-11-24 Jeff Hobbs <hobbs@scriptics.com>
* doc/open.n:
* win/tclWinSerial.c: adopted patch from Schroedter to handle
- fconfigure $sock -lasterror on Windows. [RFE: 3368]
+ fconfigure $sock -lasterror on Windows. [RFE 3368]
- * generic/tclCmdIL.c: made SORTMODE_INTEGER work with Longs
- [Bug: 3652]
+ * generic/tclCmdIL.c: made SORTMODE_INTEGER work with Longs [Bug 3652]
1999-11-23 Scott Stanton <stanton@scriptics.com>
- * library/tcltest1.0/tcltest.tcl: Fixed bug where tcltest output
- went to stdout instead of the specified output file in some
- cases.
+ * library/tcltest1.0/tcltest.tcl: Fixed bug where tcltest output went
+ to stdout instead of the specified output file in some cases.
1999-11-19 Jeff Hobbs <hobbs@scriptics.com>
- * generic/tclProc.c: backed out change from 1999-11-18 as it
- could affect return string from upvar as well.
+ * generic/tclProc.c: backed out change from 1999-11-18 as it could
+ affect return string from upvar as well.
* tools/tcl.wse.in: added tcltest1.0 library to distribution list
@@ -234,49 +230,49 @@
1999-11-18 Jeff Hobbs <hobbs@scriptics.com>
* unix/tcl.m4: added defined for _THREAD_SAFE in --enable-threads
- case; added check for pthread_mutex_init in libc; in AIX case,
- with --enable-threads ${CC}_r is used; fixed flags when using gcc
- on SCO
+ case; added check for pthread_mutex_init in libc; in AIX case, with
+ --enable-threads ${CC}_r is used; fixed flags when using gcc on SCO
- * generic/tclProc.c: corrected error reporting for default case
- at the global level for uplevel command.
+ * generic/tclProc.c: corrected error reporting for default case at the
+ global level for uplevel command.
- * generic/tclIOSock.c: changed int to size_t type for len
- in TclSockMinimumBuffers.
+ * generic/tclIOSock.c: changed int to size_t type for len in
+ TclSockMinimumBuffers.
- * generic/tclCkalloc.c: fixed Tcl_DbCkfree to return a value
- on NULL input. [Bug: 3400]
+ * generic/tclCkalloc.c: fixed Tcl_DbCkfree to return a value on NULL
+ input. [Bug 3400]
- * generic/tclStringObj.c: fixed support for passing in negative
- length to Tcl_SetUnicodeObj, et al handling routines. [Bug: 3380]
+ * generic/tclStringObj.c: fixed support for passing in negative length
+ to Tcl_SetUnicodeObj, et al handling routines. [Bug 3380]
* doc/scan.n:
* tests/scan.test:
- * generic/tclScan.c: finished support for inline scan by
- supporting XPG identifiers.
+ * generic/tclScan.c: finished support for inline scan by supporting
+ XPG identifiers.
* doc/http.n:
- * library/http2.1/http.tcl: added register and unregister
- commands to http:: package (better support for tls/SSL),
- as well as -type argument to http::geturl. [RFE: 2617]
+ * library/http2.1/http.tcl: added register and unregister commands to
+ http:: package (better support for tls/SSL), as well as -type argument
+ to http::geturl. [RFE 2617]
- * generic/tclBasic.c: removed extra decr of numLevels in
- Tcl_EvalObjEx that could cause seg fault. (mjansen@wendt.de)
+ * generic/tclBasic.c: removed extra decr of numLevels in Tcl_EvalObjEx
+ that could cause seg fault. (mjansen@wendt.de)
* generic/tclEvent.c: fixed possible lack of MutexUnlock in
- Tcl_DeleteExitHandler [Bug: 3545]
+ Tcl_DeleteExitHandler. [Bug 3545]
- * unix/tcl.m4: Added better pthreads library check and inclusion
- of _THREAD_SAFE in --enable-threads case
+ * unix/tcl.m4: Added better pthreads library check and inclusion of
+ _THREAD_SAFE in --enable-threads case
Added support for gcc config on SCO
* doc/glob.n: added note about ..../ glob behavior on Win9*
- * doc/tcltest.n: fixed minor example errors [Bug: 3551]
+ * doc/tcltest.n: fixed minor example errors. [Bug 3551]
1999-11-17 Brent Welch <welch@scriptics.com>
- * library/http2.1/http.tcl: Correctly fixed the -timeout
- problem mentioned in the 10-29 change. Also added error
- handling for failed writes on the socket during the protocol.
+
+ * library/http2.1/http.tcl: Correctly fixed the -timeout problem
+ mentioned in the 10-29 change. Also added error handling for failed
+ writes on the socket during the protocol.
1999-11-09 Jeff Hobbs <hobbs@scriptics.com>
@@ -291,54 +287,53 @@
* generic/tclParse.c: added code in Tcl_ParseBraces to test for
possible unbalanced open brace in a comment
- * library/init.tcl: removed the installed binary directory from
- the auto_path variable
+ * library/init.tcl: removed the installed binary directory from the
+ auto_path variable
- * tools/tcl.wse.in: updated to 8.3a1, fixed install of twind.tcl
- and koi8-r.enc files
+ * tools/tcl.wse.in: updated to 8.3a1, fixed install of twind.tcl and
+ koi8-r.enc files
* unix/tcl.m4: added recognition of pthreads library for AIX
1999-10-29 Brent Welch <welch@scriptics.com>
- * generic/tclInt.h: Modified the TclNewObj and TclDecrRefCount
- in two ways. First, in the case of TCL_THREADS, we do not use
- the special Tcl_Obj allocator because that is a source of
- lock contention. Second, general code cleanup to eliminate
- duplicated code. In particular, TclDecrRefCount now uses
- TclFreeObj instead of duplicating that code, so it is now
- identical to Tcl_DecrRefCount.
-
- * generic/tclObj.c: Changed Tcl_NewObj so it uses the
- TclNewObj macro instead of duplicating the code. Adjusted
- TclFreeObj so it understands the TCL_THREADS case described
- above.
-
- * library/http2.1/http.tcl: Fixed a bug in the handling of
- the state(status) variable when the -timeout flag is specified.
- Previously it was possible to leave the status undefined
- instead of empty, which caused errors in http::status
+
+ * generic/tclInt.h: Modified the TclNewObj and TclDecrRefCount in two
+ ways. First, in the case of TCL_THREADS, we do not use the special
+ Tcl_Obj allocator because that is a source of lock contention. Second,
+ general code cleanup to eliminate duplicated code. In particular,
+ TclDecrRefCount now uses TclFreeObj instead of duplicating that code,
+ so it is now identical to Tcl_DecrRefCount.
+
+ * generic/tclObj.c: Changed Tcl_NewObj so it uses the TclNewObj macro
+ instead of duplicating the code. Adjusted TclFreeObj so it understands
+ the TCL_THREADS case described above.
+
+ * library/http2.1/http.tcl: Fixed a bug in the handling of the
+ state(status) variable when the -timeout flag is specified. Previously
+ it was possible to leave the status undefined instead of empty, which
+ caused errors in http::status
1999-10-28 Jeff Hobbs <hobbs@scriptics.com>
* unix/aclocal.m4: made it just include tcl.m4
- * library/tcltest1.0/tcltest.tcl: updated makeFile to return
- full pathname of file created
+ * library/tcltest1.0/tcltest.tcl: updated makeFile to return full
+ pathname of file created
* generic/tclStringObj.c: fixed Tcl_AppendStringsToObjVA so it only
- iterates once over the va_list (avoiding a memcpy of it,
- which is not portable).
+ iterates once over the va_list (avoiding a memcpy of it, which is not
+ portable).
* generic/tclEnv.c: fixed possible ABR error in environ array
* tests/scan.test:
- * generic/tclScan.c: added support for use of inline scan,
- XPG3 currently not included
+ * generic/tclScan.c: added support for use of inline scan, XPG3
+ currently not included
* tests/incr.test:
* tests/set.test:
- * generic/tclCompCmds.c: fixed improper bytecode handling of
- 'eval {set array($unknownvar) 5}' (also for incr) [Bug: 3184]
+ * generic/tclCompCmds.c: fixed improper bytecode handling of 'eval
+ {set array($unknownvar) 5}' (also for incr). [Bug 3184]
* win/tclWinTest.c: added testvolumetype command, as atime is
completely ignored for Windows FAT file systems
@@ -346,67 +341,67 @@
* unix/tclUnixPort.h: added utime.h to includes
* doc/file.n:
* tests/cmdAH.test:
- * generic/tclCmdAH.c: added time arguments to atime and mtime
- file command methods (support 'touch' functionality)
+ * generic/tclCmdAH.c: added time arguments to atime and mtime file
+ command methods (support 'touch' functionality)
1999-10-20 Jeff Hobbs <hobbs@scriptics.com>
- * unix/tclUnixNotfy.c: fixed event/io threading problems by
- making triggerPipe non-blocking [Bug: 2792]
+ * unix/tclUnixNotfy.c: fixed event/io threading problems by making
+ triggerPipe non-blocking. [Bug 2792]
* library/tcltest1.0/tcltest.tcl:
* generic/tclThreadTest.c: fixed mem leaks in threads
- * generic/tclResult.c: fixed Tcl_AppendResultVA so it only
- iterates once over the va_list (avoiding a memcpy of it,
- which is not portable).
+ * generic/tclResult.c: fixed Tcl_AppendResultVA so it only iterates
+ once over the va_list (avoiding a memcpy of it, which is not
+ portable).
* generic/regc_color.c: fixed mem leak and assertion, from HS
- * generic/tclCompile.c: removed savedChar trick that appeared to
- be causing a segv when the literal table was released
+ * generic/tclCompile.c: removed savedChar trick that appeared to be
+ causing a segv when the literal table was released
* tests/string.test:
- * generic/tclCmdMZ.c: fixed [string index] to return ByteArrayObj
- when indexing into one (test case string-5.16) [Bug: 2871]
+ * generic/tclCmdMZ.c: fixed [string index] to return ByteArrayObj when
+ indexing into one (test case string-5.16). [Bug 2871]
- * library/http2.1/http.tcl: protected gets with catch [Bug: 2665]
+ * library/http2.1/http.tcl: protected gets with catch. [Bug 2665]
1999-10-19 Jennifer Hom <jenn@scriptics.com>
* tests/tcltest.test:
* doc/tcltest.n:
- * library/tcltest1.0/tcltest.tcl: Removed the extra return at the
- end of the tcltest.tcl file, added version information about tcl.
+ * library/tcltest1.0/tcltest.tcl: Removed the extra return at the end
+ of the tcltest.tcl file, added version information about tcl.
Applied patches sent in by Andreas Kupries to add helper procs for
debug output, add 3 new flags (-testsdir, -load, -loadfile), and
- internally refactors common code for dealing with paths into
- separate procedures. [Bug: 2838, 2842]
+ internally refactors common code for dealing with paths into separate
+ procedures. [Bug 2838, 2842]
Merged code from core-8-2-1 branch that changes the checks for the
- value of tcl_interactive to also incorporate a check for the
- existence of the variable.
+ value of tcl_interactive to also incorporate a check for the existence
+ of the variable.
* tests/autoMkindex.test:
- * tests/pkgMkIndex.test: Explicitly cd to
- ::tcltest::testsDirectory at the beginning of the test run
+ * tests/pkgMkIndex.test: Explicitly cd to ::tcltest::testsDirectory at
+ the beginning of the test run
- * tests/basic.test: Use version information defined in tcltest
- instead of hardcoded version number
+ * tests/basic.test: Use version information defined in tcltest instead
+ of hardcoded version number
- * tests/socket.test: package require tcltest before attempting to
- use variable defined in tcltest namespace
+ * tests/socket.test: package require tcltest before attempting to use
+ variable defined in tcltest namespace
+
+ * tests/unixInit.test:
+ * tests/unixNotfy.test: Added explicit exits needed to avoid problems
+ when the tests area run in wish.
- * tests/unixInit.test:
- * tests/unixNotfy.test: Added explicit exits needed to avoid
- problems when the tests area run in wish.
-
1999-10-12 Jim Ingham <jingham@scriptics.com>
* mac/tclMacLoad.c: Stupid bug - we converted the filename to
external, but used the unconverted version.
- * mac/tclMacFCmd.c: Fix a merge error in the bug fix for [Bug: 2869]
+ * mac/tclMacFCmd.c: Fix a merge error in the bug fix for [Bug 2869]
1999-10-12 Jeff Hobbs <hobbs@scriptics.com>
@@ -423,21 +418,20 @@
* generic/tclRegexp.c:
* generic/tclTest.c:
* tests/reg.test: updated to Henry Spencer's new regexp engine
- (mid-Sept 99). Should greatly reduce stack space reqs.
+ (mid-Sept 99). Should greatly reduce stack space reqs.
* library/tcltest1.0/pkgIndex.tcl: fixed procs in pkgIndex.tcl file
* generic/tclEnv.c: fixed mem leak with putenv and DStrings
* doc/Encoding.3: corrected docs
* tests/basic.test: updated test cases for 8.3
- * tests/encoding.test: fixed test case that change system
- encoding to a double-byte one (this causes a bogus mem read
- error for purify)
+ * tests/encoding.test: fixed test case that change system encoding to
+ a double-byte one (this causes a bogus mem read error for purify)
* unix/Makefile.in: purify has to use -best-effort to instrument
* unix/tclAppInit.c: identified potential mem leak when compiling
tcltest (not critical)
- * unix/tclUnixPipe.c: fixed mem leak in TclpCreateProcess when
- doing alloc between vfork and execvp.
+ * unix/tclUnixPipe.c: fixed mem leak in TclpCreateProcess when doing
+ alloc between vfork and execvp.
* unix/tclUnixTest.c: fixed mem leak in findexecutable test command
1999-10-05 Jeff Hobbs <hobbs@scriptics.com>
@@ -452,127 +446,126 @@
* library/http2.1/http.tcl: fixed possible use of global c var.
* win/tclWinReg.c: fixed registry command to properly 'get'
- HKEY_PERFORMANCE_DATA root key data. Needs more work.
-
+ HKEY_PERFORMANCE_DATA root key data. Needs more work.
+
* generic/tclNamesp.c:
* generic/tclVar.c:
* generic/tclCmdIL.c: fixed comment typos
- * mac/tclMacFCmd.c: fixed filename stuff to support UTF-8 [Bug: 2869]
+ * mac/tclMacFCmd.c: fixed filename stuff to support UTF-8. [Bug 2869]
- * win/tclWinSerial.c: changed SerialSetOptionProc to return
- TCL_OK by default. (patch from Rolf Schroedter)
+ * win/tclWinSerial.c: changed SerialSetOptionProc to return TCL_OK by
+ default. (patch from Rolf Schroedter)
1999-09-21 Jennifer Hom <jenn@scriptics.com>
- * library/tcltest1.0/tcltest.tcl: Applied patches sent in by
- Andreas Kupries to fix typos in comments and ::tcltest::grep,
- fix hook redefinition problems, and change "string compare" to
- "string equal." [Bug: 2836, 2837, 2839, 2840]
+ * library/tcltest1.0/tcltest.tcl: Applied patches sent in by Andreas
+ Kupries to fix typos in comments and ::tcltest::grep, fix hook
+ redefinition problems, and change "string compare" to "string equal".
+ [Bug 2836, 2837, 2839, 2840]
1999-09-20 Jeff Hobbs <hobbs@scriptics.com>
* tests/env.test:
- * unix/Makefile.in: added support for AIX LIBPATH env var [Bug: 2793]
+ * unix/Makefile.in: added support for AIX LIBPATH env var. [Bug 2793]
removed second definition of INCLUDE_INSTALL_DIR (the one that
- referenced @includedir@) [Bug: 2805]
- * unix/dltest/Makefile.in: added -lc to LIBS [Bug: 2794]
+ referenced @includedir@) [Bug 2805]
+ * unix/dltest/Makefile.in: added -lc to LIBS. [Bug 2794]
1999-09-16 Jeff Hobbs <hobbs@scriptics.com>
- * tests/timer.test: changed after delay in timer test 6.29 from
- 1 to 10. [Bug: 2796]
+ * tests/timer.test: changed after delay in timer test 6.29 from 1 to
+ 10. [Bug 2796]
* tests/pkg.test:
* generic/tclPkg.c: fixed package version check to disallow 1.2..3
- [Bug: 2539]
-
- * unix/Makefile.in: fixed gendate target - this never worked
- since RCS was intro'd.
- * generic/tclGetDate.y: updated to reflect previous changes
- to tclDate.c (leap year calc) and added CEST and UCT time zone
- recognition. Fixed 4 missing UCHAR() casts. [Bug: 2717, 954,
- 1245, 1249]
-
- * generic/tclCkalloc.c: changed Tcl_DumpActiveMemory to really
- dump to stderr and close it [Bug: 725] and changed Tcl_Ckrealloc
- and Tcl_Ckfree to not bomb when NULL was passed in [Bug: 1719]
- and changed Tcl_Alloc, et al to not panic when a alloc request
- for zero came through and NULL was returned (valid on AIX, Tru64)
- [Bug: 2795, etc]
+ [Bug 2539]
+
+ * unix/Makefile.in: fixed gendate target - this never worked since RCS
+ was intro'd.
+ * generic/tclGetDate.y: updated to reflect previous changes to
+ tclDate.c (leap year calc) and added CEST and UCT time zone
+ recognition. Fixed 4 missing UCHAR() casts. [Bug 2717, 954, 1245,
+ 1249]
+
+ * generic/tclCkalloc.c: changed Tcl_DumpActiveMemory to really dump to
+ stderr and close it [Bug 725] and changed Tcl_Ckrealloc and
+ Tcl_Ckfree to not bomb when NULL was passed in [Bug 1719] and changed
+ Tcl_Alloc, et al to not panic when a alloc request for zero came
+ through and NULL was returned (valid on AIX, Tru64) [Bug 2795, etc]
* tests/clock.test:
* doc/clock.n:
- * generic/tclClock.c: added -milliseconds switch to clock clicks
- to guarantee that the return value of clicks is in the millisecs
- granularity [Bug: 2682, 1332]
+ * generic/tclClock.c: added -milliseconds switch to clock clicks to
+ guarantee that the return value of clicks is in the millisecs
+ granularity. [Bug 2682, 1332]
1999-09-15 Jeff Hobbs <hobbs@scriptics.com>
- * generic/tclIOCmd.c: fixed potential core dump in conjunction
- with stacked channels with result obj manipulation in
- Tcl_ReadChars [Bug: 2623]
+ * generic/tclIOCmd.c: fixed potential core dump in conjunction with
+ stacked channels with result obj manipulation in Tcl_ReadChars. [Bug
+ 2623]
* tests/format.test:
- * generic/tclCmdAH.c: fixed translation of %0#s in format [Bug: 2605]
+ * generic/tclCmdAH.c: fixed translation of %0#s in format. [Bug 2605]
- * doc/msgcat.n: fixed \\ bug in example [Bug: 2548]
+ * doc/msgcat.n: fixed \\ bug in example. [Bug 2548]
* unix/tcl.m4:
- * unix/aclocal.m4: added fix for FreeBSD-[1-2] recognition
- [Bug: 2070] and fix for IRIX SHLIB_LB_LIBS. [Bug: 2610]
+ * unix/aclocal.m4: added fix for FreeBSD-[1-2] recognition [Bug 2070]
+ and fix for IRIX SHLIB_LB_LIBS. [Bug 2610]
* doc/array.n:
* tests/var.test:
* tests/set.test:
- * generic/tclVar.c: added an array unset operation, with docs
- and tests. Variation of [Bug: 1775]. Added fix in TclArraySet
- to check when trying to set in a non-existent namespace. [Bug: 2613]
+ * generic/tclVar.c: added an array unset operation, with docs and
+ tests. Variation of [Bug 1775]. Added fix in TclArraySet to check
+ when trying to set in a non-existent namespace. [Bug 2613]
1999-09-14 Jeff Hobbs <hobbs@scriptics.com>
* tests/linsert.test:
* doc/linsert.n:
- * generic/tclCmdIL.c: fixed end-int interpretation of linsert
- to correctly calculate value for end, added test and docs [Bug: 2693]
+ * generic/tclCmdIL.c: fixed end-int interpretation of linsert to
+ correctly calculate value for end, added test and docs. [Bug 2693]
* doc/regexp.n:
* doc/regsub.n:
* tests/regexp.test:
- * generic/tclCmdMZ.c: add -start switch to regexp and regsub
- with docs and tests
+ * generic/tclCmdMZ.c: add -start switch to regexp and regsub with docs
+ and tests
* doc/switch.n: added proper use of comments to example.
- * generic/tclCmdMZ.c: changed switch to complain when an error
- occurs that seems to be due to a misplaced comment.
+ * generic/tclCmdMZ.c: changed switch to complain when an error occurs
+ that seems to be due to a misplaced comment.
- * generic/tclCmdMZ.c: fixed illegal ref for \[0-9] substitutions
- in regsub [Bug: 2723]
+ * generic/tclCmdMZ.c: fixed illegal ref for \[0-9] substitutions in
+ regsub. [Bug 2723]
- * generic/tclCmdMZ.c: changed [string equal] to return an Int
- type object (was a Boolean)
+ * generic/tclCmdMZ.c: changed [string equal] to return an Int type
+ object (was a Boolean)
1999-09-01 Jennifer Hom <jenn@scriptics.com>
- * library/tcltest1.0/tcltest.tcl: Process command-line arguments
- only ::tcltest doesn't have a child namespace (requires that
- command-line args are processed in that namespace)
+ * library/tcltest1.0/tcltest.tcl: Process command-line arguments only
+ ::tcltest doesn't have a child namespace (requires that command-line
+ args are processed in that namespace)
1999-09-01 Jeff Hobbs <hobbs@scriptics.com>
- * generic/tclParseExpr.c: changed '"' to '\"' to make FreeBSD
- happy [Bug: 2625]
- * generic/tclProc.c: moved static buf to better location and
- changed static msg that would overflow in ProcessProcResultCode
- [Bug: 2483] and added Tcl_DStringFree to Tcl_ProcObjCmd.
- Also reworked size of static buffers.
+ * generic/tclParseExpr.c: changed '"' to '\"' to make FreeBSD happy.
+ [Bug 2625]
+ * generic/tclProc.c: moved static buf to better location and changed
+ static msg that would overflow in ProcessProcResultCode [Bug 2483]
+ and added Tcl_DStringFree to Tcl_ProcObjCmd. Also reworked size of
+ static buffers.
* tests/stringObj.test: added test 9.11
- * generic/tclStringObj.c: changed Tcl_AppendObjToObj to
- properly handle the 1-byte dest and mixed src case where
- both had had Unicode string len checks made on them. [Bug: 2678]
+ * generic/tclStringObj.c: changed Tcl_AppendObjToObj to properly
+ handle the 1-byte dest and mixed src case where both had had Unicode
+ string len checks made on them. [Bug 2678]
* unix/aclocal.m4:
- * unix/tcl.m4: adjusted fix from 8-21 to add -bnoentry to the
- AIX-* case and readjusted the range
+ * unix/tcl.m4: adjusted fix from 8-21 to add -bnoentry to the AIX-*
+ case and readjusted the range
1999-08-31 Jennifer Hom <jenn@scriptics.com>
@@ -588,79 +581,76 @@
* tests/exec.test:
* tests/io.test:
* tests/event.test:
- * tests/tcltest.test: Added 'exit' calls to scripts that the tests
+ * tests/tcltest.test: Added 'exit' calls to scripts that the tests
themselves write, and removed accidental checkin of knownBugThreaded
constraints for Solaris and Linux.
-
- * library/tcltest1.0/tcltest.tcl: Modified tcltest so that
- variables are only initialized to their default values if they did
- not previously exist.
+
+ * library/tcltest1.0/tcltest.tcl: Modified tcltest so that variables
+ are only initialized to their default values if they did not
+ previously exist.
1999-08-26 Jennifer Hom <jenn@scriptics.com>
* tests/tcltest.test:
- * library/tcltest1.0/tcltest.tcl: Added a -args flag that sets a
- variable named ::tcltest::parameters based on whatever's being
- sent in as the argument to the -args flag.
+ * library/tcltest1.0/tcltest.tcl: Added a -args flag that sets a
+ variable named ::tcltest::parameters based on whatever's being sent in
+ as the argument to the -args flag.
1999-08-23 Jennifer Hom <jenn@scriptics.com>
- * tests/tcltest.test: Added additional tests for -tmpdir, marked
- all tests that use exec as unixOrPc.
+ * tests/tcltest.test: Added additional tests for -tmpdir, marked all
+ tests that use exec as unixOrPc.
* tests/encoding.test:
- * tests/interp.test:
+ * tests/interp.test:
* tests/macFCmd.test:
* tests/parseOld.test:
- * tests/regexp.test: Applied patches from Jim Ingham to add
- encoding to a Mac only interp test, change an error message in
- macFCmd.tet, put a comment in parseOld.test, fix tests using the
- testencoding path command, and put unixOrPc constraints on tests
- that use exec.
+ * tests/regexp.test: Applied patches from Jim Ingham to add encoding
+ to a Mac only interp test, change an error message in macFCmd.tet, put
+ a comment in parseOld.test, fix tests using the testencoding path
+ command, and put unixOrPc constraints on tests that use exec.
1999-08-21 Jeff Hobbs <hobbs@scriptics.com>
- * unix/aclocal.m4: Changed AIX-4.[2-9] check to AIX-4.[1-9]
- [Bug: 1909]
+ * unix/aclocal.m4: Changed AIX-4.[2-9] check to AIX-4.[1-9] [Bug 1909]
1999-08-20 Jeff Hobbs <hobbs@scriptics.com>
- * generic/tclPosixStr.c: fixed typo [Bug: 2592]
+ * generic/tclPosixStr.c: fixed typo. [Bug 2592]
- * doc/*: fixed various nroff bugs in man pages [Bug: 2503 2588]
+ * doc/*: fixed various nroff bugs in man pages. [Bug 2503 2588]
1999-08-19 Jeff Hobbs <hobbs@scriptics.com>
- * win/README.binary: fixed version info and some typos [Bug: 2561]
-
+ * win/README.binary: fixed version info and some typos. [Bug 2561]
+
* doc/interp.n: updated list of commands available in a safe
- interpreter [Bug: 2526]
+ interpreter. [Bug 2526]
* generic/tclIO.c: changed Tcl_GetChannelNames* to use style guide
headers (pleases HP cc)
1999-08-18 Jeff Hobbs <hobbs@scriptics.com>
- * doc/Eval.3: fixed doc on input args [Bug: 2114]
+ * doc/Eval.3: fixed doc on input args. [Bug 2114]
* doc/OpenFileChnl.3:
* doc/file.n:
* tests/cmdAH.test:
* tclIO.c:
* tclCmdAH.c: added "file channels ?pattern?" tcl command, with
- associated Tcl_GetChannelNames and Tcl_GetChannelNamesEx public
- C APIs (added to tcl.decls as well), with docs and tests.
+ associated Tcl_GetChannelNames and Tcl_GetChannelNamesEx public C APIs
+ (added to tcl.decls as well), with docs and tests.
* tests/expr.test:
- * generic/tclCompile.c: add TCL_TOKEN_VARIABLE to the part types
- that cause differed compilation for exprs, to correct the expr
- double-evaluation problem for vars. Added test cases.
- Related to [Bug: 732]
-
- * unix/Makefile.in: changed the dependency structure so that
- install-* is dependent on * (ie - install-binaries is dependent
- on binaries).
-
+ * generic/tclCompile.c: add TCL_TOKEN_VARIABLE to the part types that
+ cause differed compilation for exprs, to correct the expr
+ double-evaluation problem for vars. Added test cases. Related to [Bug
+ 732]
+
+ * unix/Makefile.in: changed the dependency structure so that install-*
+ is dependent on * (ie - install-binaries is dependent on binaries).
+
* library/auto.tcl:
* library/init.tcl:
* library/ldAout.tcl:
@@ -668,14 +658,13 @@
* library/safe.tcl:
* library/word.tcl:
* library/http2.1/http.tcl:
- * library/msgcat1.0/msgcat.tcl: updated libraries to better
- Tcl style guide (no more string comparisons with == or !=, spacing
- changes).
+ * library/msgcat1.0/msgcat.tcl: updated libraries to better Tcl style
+ guide (no more string comparisons with == or !=, spacing changes).
1999-08-05 Jim Ingham <jingham@cygnus.com>
* mac/tclMacProjects.sea.hqx: Rearrange the projects so that the build
- directory is separate from the sources. Much more convenient!
+ directory is separate from the sources. Much more convenient!
1999-08-13 Scott Redman <redman@scriptics.com>
@@ -683,18 +672,18 @@
1999-08-12 Scott Stanton <stanton@scriptics.com>
- * win/Makefile.in: Added COMPILE_DEBUG_FLAGS macro to make it
- easier to turn on compiler tracing.
+ * win/Makefile.in: Added COMPILE_DEBUG_FLAGS macro to make it easier
+ to turn on compiler tracing.
- * tests/parse.test:
- * generic/tclParse.c: Fixed bug in Tcl_EvalEx where the termOffset
- was not being updated in cases where the evaluation returned a non
- TCL_OK error code. [Bug: 2535]
+ * tests/parse.test:
+ * generic/tclParse.c: Fixed bug in Tcl_EvalEx where the termOffset was
+ not being updated in cases where the evaluation returned a non TCL_OK
+ error code. [Bug 2535]
1999-08-12 Scott Redman <redman@scriptics.com>
- * win/tclWinSerial.c: Applied patch from Petteri Kettunen to
- remove compiler warning.
+ * win/tclWinSerial.c: Applied patch from Petteri Kettunen to remove
+ compiler warning.
1999-08-10 Scott Redman <redman@scriptics.com>
@@ -707,12 +696,12 @@
Windows (and he fixed the bug in the Unix thread implementation).
1999-08-09 Brent Welch <welch@scriptics.com>
-
+
* generic/tcl.decls:
* generic/tclAlloc.c:
* generic/tclCkalloc.c:
* generic/tclCmdIL.c:
- * generic/tclDecls.h:
+ * generic/tclDecls.h:
* generic/tclIO.c:
* generic/tclInt.decls:
* generic/tclIntDecls.h:
@@ -720,12 +709,11 @@
* generic/tclVar.c:
* mac/tclMacThrd.c:
* unix/tclUnixThrd.c:
- * win/tclWinThrd.c: Added use of Tcl_GetAllocMutex to tclAlloc.c
- and tclCkalloc.c so they can be linked against alternate thread
- packages. Added Tcl_GetChannelNames to tclIO.c. Added
- TclVarTraceExists hook so "info exists" triggers read traces
- exactly like it did in Tcl 7.6. Stubs table changes to reflect new
- internal and external APIs.
+ * win/tclWinThrd.c: Added use of Tcl_GetAllocMutex to tclAlloc.c and
+ tclCkalloc.c so they can be linked against alternate thread packages.
+ Added Tcl_GetChannelNames to tclIO.c. Added TclVarTraceExists hook so
+ "info exists" triggers read traces exactly like it did in Tcl 7.6.
+ Stubs table changes to reflect new internal and external APIs.
1999-08-09 Jeff Hobbs <hobbs@scriptics.com>
@@ -733,36 +721,36 @@
machines and int overflow testing.
* tests/tcltest.test: fixed minor error in 8.2 result (from dgp)
- * doc/Object.3: clarified Tcl_DecrRefCount docs [Bug: 1952]
- * doc/array.n: clarified array pattern docs [Bug: 1330]
- * doc/clock.n: fixed clock docs [Bug: 693]
+ * doc/Object.3: clarified Tcl_DecrRefCount docs. [Bug 1952]
+ * doc/array.n: clarified array pattern docs. [Bug 1330]
+ * doc/clock.n: fixed clock docs. [Bug 693]
* doc/lindex.n: clarified to account for new end-int behavior.
- * doc/string.n: fixed formatting errors [Bug: 2188 2189]
- * doc/tclvars.n: fixed doc error [Bug: 2042]
- * library/init.tcl: fixed path handling in auto_execok (it could
- miss including the normal path on some Windows machines) [Bug: 1276]
+ * doc/string.n: fixed formatting errors. [Bug 2188 2189]
+ * doc/tclvars.n: fixed doc error. [Bug 2042]
+ * library/init.tcl: fixed path handling in auto_execok (it could miss
+ including the normal path on some Windows machines). [Bug 1276]
1999-08-05 Jeff Hobbs <hobbs@scriptics.com>
- * doc/tclvars.n: Made it clear that tcl_pkgPath was not set
- for Windows (already mentioned in init.tcl) [Bug: 2455]
- * generic/tclLiteral.c: fixed reference to bytes that might
- not be null terminated (using objPtr->bytes, which is) [Bug: 2496]
- * library/http2.1/http.tcl: Made use of "i" in init section use
- local var and start at 0 (was 1). [Bug: 2502]
+ * doc/tclvars.n: Made it clear that tcl_pkgPath was not set for
+ Windows (already mentioned in init.tcl). [Bug 2455]
+ * generic/tclLiteral.c: fixed reference to bytes that might not be
+ null terminated (using objPtr->bytes, which is). [Bug 2496]
+ * library/http2.1/http.tcl: Made use of "i" in init section use local
+ var and start at 0 (was 1). [Bug 2502]
1999-08-04 Scott Stanton <stanton@scriptics.com>
* tests/reg.test: Added test for REG_EXPECT bug fixed by Henry's
patch.
- * generic/regc_nfa.c:
- * generic/regcomp.c:
+ * generic/regc_nfa.c:
+ * generic/regcomp.c:
* generic/rege_dfa.c:
- * generic/regexec.c:
+ * generic/regexec.c:
* generic/regguts.h: Applied patches supplied by Henry Spencer to
greatly enhance the performance of certain classes of regular
- expressions. [Bug: 2440, 2447]
+ expressions. [Bug 2440, 2447]
1999-08-03 Scott Redman <redman@scriptics.com>
@@ -773,7 +761,7 @@
* unix/configure.in:
* win/configure.in: Change beta level to b2.
-
+
* generic/tcl.h:
* generic/tcl.decls:
* generic/tclDecls.h:
@@ -782,104 +770,101 @@
* generic/tclIntDecls.h:
* generic/tclRegexp.h:
* generic/tclStubInit.c: Move some exported public and internal
- functions to the stub tables. Removed functions that are in the
- stub tables (from this and previous changes) from the original
- header files.
+ functions to the stub tables. Removed functions that are in the stub
+ tables (from this and previous changes) from the original header
+ files.
1999-08-01 Scott Redman <redman@scriptics.com>
- * win/tclWinSock.c: Added comment block to SocketThread()
- function. Added code to avoid calling TerminateThread(), but
- instead to send a message to the socket event window to tell it to
- terminate its thread.
+ * win/tclWinSock.c: Added comment block to SocketThread() function.
+ Added code to avoid calling TerminateThread(), but instead to send a
+ message to the socket event window to tell it to terminate its thread.
1999-07-30 Jennifer Hom <jenn@scriptics.com>
* tests/tcltest.test:
- * library/tcltest1.0/tcltest.tcl: Exit with non-zero status if
- there were problems with the way the test suite was started
- (e.g. wrong # arguments).
+ * library/tcltest1.0/tcltest.tcl: Exit with non-zero status if there
+ were problems with the way the test suite was started (e.g. wrong #
+ arguments).
1999-07-30 Jeff Hobbs <hobbs@scriptics.com>
- * generic/tclInt.decls: added declaractions necessary for the
- Tcl test code to work wth stubs [Bug: 2445]
+ * generic/tclInt.decls: added declaractions necessary for the Tcl test
+ code to work wth stubs. [Bug 2445]
-1999-07-30 <redman@scriptics.com>
+1999-07-30 Scott Redman <redman@scriptics.com>
* win/tclWinPipe.c:
- * win/Makefile.in: Fixing launching of 16-bit apps on Win9x from
- wish. The command line was primed with tclpip82.dll, but it was
- ignored. Fixed that, then fixed the gmake makefile to build
- tclpip82.dll as an executable.
+ * win/Makefile.in: Fixing launching of 16-bit apps on Win9x from wish.
+ The command line was primed with tclpip82.dll, but it was ignored.
+ Fixed that, then fixed the gmake makefile to build tclpip82.dll as an
+ executable.
- * win/tclWinSock.c: Applied small patch to get thread-specific
- data after initializing the socket driver.
+ * win/tclWinSock.c: Applied small patch to get thread-specific data
+ after initializing the socket driver.
- * unix/tclUnixThrd.c: Applied patch to fix threads on Irix 6.5.
- Patch from James Dennett. [Bug: 2450]
+ * unix/tclUnixThrd.c: Applied patch to fix threads on Irix 6.5. Patch
+ from James Dennett. [Bug 2450]
- * tests/info.test: Enable test for tclParse.c change (info
- complete).
-
-1999-07-30 <hobbs@scriptics.com>
+ * tests/info.test: Enable test for tclParse.c change (info complete).
+
+1999-07-30 Jeff Hobbs <hobbs@scriptics.com>
- * tclIO.c: added fix for Kupries' trf patch [Bug: 2386]
+ * tclIO.c: added fix for Kupries' trf patch. [Bug 2386]
* tclParse.c: fixed bug in info complete regarding nested square
- brackets [Bug: 2382, 2466]
-
-1999-07-29 <redman@scriptics.com>
+ brackets. [Bug 2382, 2466]
+
+1999-07-29 Scott Redman <redman@scriptics.com>
* win/tclWinChan.c: Allow tcl to open CON and NUL, even for std
- channels. Checking for bad/unusable std channels was moved to Tk
- since its only purpose was to check whether to use the Tk Console
- Window for the std channels. [Bug: 2393 2392 2209 2458]
+ channels. Checking for bad/unusable std channels was moved to Tk since
+ its only purpose was to check whether to use the Tk Console Window for
+ the std channels. [Bug 2393 2392 2209 2458]
* unix/mkLinks.tcl: Applied patch to avoid linking pack.n to
- pack-old.n. Patch from Don Porter. [Bug: 2469]
+ pack-old.n. Patch from Don Porter. [Bug 2469]
+
+ * doc/Encoding.n: Applied patch to fix typo in .SH NAME line. Patch
+ from Don Porter. [Bug 2451]
- * doc/Encoding.n: Applied patch to fix typo in .SH NAME line.
- Patch from Don Porter. [Bug: 2451]
-
- * win/tclWinSock.c: Free Win32 Event handles when destroying
- the socket helper thread.
+ * win/tclWinSock.c: Free Win32 Event handles when destroying the
+ socket helper thread.
-1999-07-28 <jenn@scriptics.com>
+1999-07-28 Jennifer Hom <jenn@scriptics.com>
* tests/tcltest.test:
* library/tcltest1.0/tcltest.tcl: Fixed the condition under which
- ::tcltest::PrintError had an infinite loop problem and added a
- test case for it. Added an optional argument to
- ::tcltest::getMatchingFiles telling it where to search for test
- files.
+ ::tcltest::PrintError had an infinite loop problem and added a test
+ case for it. Added an optional argument to ::tcltest::getMatchingFiles
+ telling it where to search for test files.
-1999-07-27 <redman@scriptics.com>
+1999-07-27 Scott Redman <redman@scriptics.com>
- * tools/tclSplash.bmp: Updated Windows installer bitmap
- to ready Tcl/Tk Version 8.2.
+ * tools/tclSplash.bmp: Updated Windows installer bitmap to ready
+ Tcl/Tk Version 8.2.
-1999-07-26 <redman@scriptics.com>
+1999-07-26 Scott Redman <redman@scriptics.com>
- * tests/tcltest.test: Need to close the new core file, there
- seems to be a hang in threaded WinNT if the file isn't closed.
- Open issue, need to fix that hang.
+ * tests/tcltest.test: Need to close the new core file, there seems to
+ be a hang in threaded WinNT if the file isn't closed. Open issue, need
+ to fix that hang.
- * tests/httpold.test: Add time delay in response from Http server
- so that test cases can properly detect timeout conditions with
- threads enabled on multi-CPU WinNT.
+ * tests/httpold.test: Add time delay in response from Http server so
+ that test cases can properly detect timeout conditions with threads
+ enabled on multi-CPU WinNT.
- * tests/winFCmd.test: Test case winFcmd-1.33 was looking for
- c:\windows, which may not exist. Instead, create a new directory
- on c:\ and use it for the test.
+ * tests/winFCmd.test: Test case winFcmd-1.33 was looking for
+ c:\windows, which may not exist. Instead, create a new directory on
+ c:\ and use it for the test.
* win/tclWinConsole.c:
* win/tclWinPipe.c:
- * win/tclWinSock.c: Fix terminating helper threads by holding any
- mutexes from the primary thread while waiting for the helper
- thread to terminate. Without these changes, the test suite hangs
- on WinNT with 2 CPUs and threads enabled. Open issue, seems to be
- a sporadic hang on dual CPU systems still (very rare).
+ * win/tclWinSock.c: Fix terminating helper threads by holding any
+ mutexes from the primary thread while waiting for the helper thread to
+ terminate. Without these changes, the test suite hangs on WinNT with 2
+ CPUs and threads enabled. Open issue, seems to be a sporadic hang on
+ dual CPU systems still (very rare).
1999-07-26 Jennifer Hom <jenn@scriptics.com>
@@ -888,92 +873,91 @@
* doc/tcltest.n: Cleaned up code in ::tcltest::PrintError, revised
documentation, and added tests for the tcltest package.
-1999-07-23 <redman@scriptics.com>
+1999-07-23 Scott Redman <redman@scriptics.com>
* tests/info.test:
- * generic/tclParse.c: Removed patch for info command, breaks test
- cases on Unix. Patch was bad and needs to be redone
- properly. [Bug: 2382]
+ * generic/tclParse.c: Removed patch for info command, breaks test
+ cases on Unix. Patch was bad and needs to be redone properly. [Bug
+ 2382]
-1999-07-22 <redman@scriptics.com>
+1999-07-22 Scott Redman <redman@scriptics.com>
* Changed version to 8.2b2.
- * win/tclWinSock.c: Fixed hang with threads enabled, fixed
- semaphores with threads disabled.
+ * win/tclWinSock.c: Fixed hang with threads enabled, fixed semaphores
+ with threads disabled.
* win/safe.test: Fixed safe-6.3 with threads enabled.
-
- * win/Makefile.in: Fixed calling of tcltest to fix safe.test
- failures due to path TCL_LIBRARY path.
- * win/tclWinPort.h: Block out include of sys/*.h in order to
- build extensions with MetroWerks compiler for Win32. [Bug: 2385]
-
+ * win/Makefile.in: Fixed calling of tcltest to fix safe.test failures
+ due to path TCL_LIBRARY path.
+
+ * win/tclWinPort.h: Block out include of sys/*.h in order to build
+ extensions with MetroWerks compiler for Win32. [Bug 2385]
+
* generic/tclCmdMZ.c:
* generic/tclIO.c: Fix ANSI-style prototypes based on patch from
- Ulrich Ring. [Bug: 2391]
-
- * unix/Makefile.in: Need to make install-sh executable before
- calling (with chmod +x). [Bug: 2413]
-
+ Ulrich Ring. [Bug 2391]
+
+ * unix/Makefile.in: Need to make install-sh executable before calling
+ (with chmod +x). [Bug 2413]
+
* tests/var.test:
- * generic/tclVar.c: Fixed bug that caused a seg. fault when using
- "array set a(b) {}", which is a bad array name anyway. Now the
- "array set" command will return an error in this case. Added test
- case and fixed existing test. [Bug: 2427]
+ * generic/tclVar.c: Fixed bug that caused a seg. fault when using
+ "array set a(b) {}", which is a bad array name anyway. Now the "array
+ set" command will return an error in this case. Added test case and
+ fixed existing test. [Bug 2427]
-1999-07-21 <redman@scriptics.com>
+1999-07-21 Scott Redman <redman@scriptics.com>
* tests/info.test:
- * generic/tclParse.c: Applied patch to fix "info complete"
- for the string {[a [b]}. Patch from Peter Spjuth. [Bug: 2382]
+ * generic/tclParse.c: Applied patch to fix "info complete" for the
+ string {[a [b]}. Patch from Peter Spjuth. [Bug 2382]
* doc/Utf.3:
* generic/tcl.decls:
* generic/tclDecls.h:
* generic/tclUtf.c: Changed function declarations in
non-platform-specific public APIs to use "unsigned long" instead of
- "size_t", which may not be defined on certain compilers (rather
- than include sys/types.h, which may not exist).
-
+ "size_t", which may not be defined on certain compilers (rather than
+ include sys/types.h, which may not exist).
+
* unix/Makefile.in: Added the Windows configure script to the
distribution file list, already shipping configure.in and the .m4
files, but needed the configure script itself.
-
+
* win/makefile.vc: Changed version number of DDE package in VC++
makefile to use 1.1 instead of 1.0.
* doc/open.n: Added documentation of \\.\comX notation for opening
serial ports on Windows (alternative to comX:).
-
+
* tests/ioCmd.test:
* doc/open.n:
* win/tclWinSerial.c: Applied patch from Rolf Schroedter to add
- -pollinterval option to fconfigure to modify the maxblocktime used
- in the fileevent polling. Added documentation and fixed the test
- case as well.
-
- * win/tclWinSock.c: Modified 8.1.0 version of the Win32 socket
- driver to move the handling of the socket event window in a
- separate thread. It also turned out that Win95 & Win98 were, in
- some cases, getting multiple FD_ACCEPTs but only handling one.
- Added a count for the FD_ACCEPT to take care of this. Tested on
- NT4 SP3, NT4 SP4, Win95, and Win98.
- [Bug: 2178 2256 2259 2329 2323 2355]
-
-1999-07-21 <jpeek@scriptics.com>
+ -pollinterval option to fconfigure to modify the maxblocktime used in
+ the fileevent polling. Added documentation and fixed the test case as
+ well.
+
+ * win/tclWinSock.c: Modified 8.1.0 version of the Win32 socket driver
+ to move the handling of the socket event window in a separate thread.
+ It also turned out that Win95 & Win98 were, in some cases, getting
+ multiple FD_ACCEPTs but only handling one. Added a count for the
+ FD_ACCEPT to take care of this. Tested on NT4 SP3, NT4 SP4, Win95, and
+ Win98. [Bug 2178 2256 2259 2329 2323 2355]
+
+1999-07-21 Jerry Peek <jpeek@scriptics.com>
* README: Small tweaks to clean up typos and wording.
1999-07-20 Melissa Hirschl <hershey@matisse.scriptics.com>
- * generic/tclInitScript.h:
- * unix/tclUnixInit.c: merged code with 8.0.5. We now use an
+ * generic/tclInitScript.h:
+ * unix/tclUnixInit.c: merged code with 8.0.5. We now use an
intermediate global tcl var "tclDefaultLibrary" to keep the
- "tcl_library" var from being set by the default value in the
- Makefile. Also fixed a bug in which caused the value of
- TCL_LIBRARY env var to be ignored.
+ "tcl_library" var from being set by the default value in the Makefile.
+ Also fixed a bug in which caused the value of TCL_LIBRARY env var to
+ be ignored.
* unix/tclWinInit.c: just updated some comments.
1999-07-19 Melissa Hirschl <hershey@matisse.scriptics.com>
@@ -981,119 +965,115 @@
* library/http2.1/http.tcl: updated -useragent text to say version
2.1.
-1999-07-16 <redman@scriptics.com>
+1999-07-16 Scott Redman <redman@scriptics.com>
* generic/tcl.decls:
* generic/tclDecls.h:
- * generic/tclStubInit.c: Add Tcl_SetNotifier to stub table.
- [Bug: 2364]
-
+ * generic/tclStubInit.c: Add Tcl_SetNotifier to stub table. [Bug 2364]
+
* unix/aclocal.m4:
- * unix/tcl.m4: Add check for Alpha/Linux to correct the IEEE
- floating flag to the compiler, should be -mieee. Patch from Don
- Porter.
-
- * tools/tcl.hpj.in: Change version number of .cnt file referenced
- in .HPJ file.
-
-1999-07-15 <redman@scriptics.com>
-
+ * unix/tcl.m4: Add check for Alpha/Linux to correct the IEEE floating
+ flag to the compiler, should be -mieee. Patch from Don Porter.
+
+ * tools/tcl.hpj.in: Change version number of .cnt file referenced in
+ .HPJ file.
+
+1999-07-15 Scott Redman <redman@scriptics.com>
+
* tools/tcl.wse.in: Fixed naming of target files for Windows.
-1999-07-14 <jpeek@scriptics.com>
+1999-07-14 Jerry Peek <jpeek@scriptics.com>
* doc/re_syntax.n: Deleted sentence as suggested by Scott S.
-1999-07-12 <jpeek@scriptics.com>
+1999-07-12 Jerry Peek <jpeek@scriptics.com>
- * doc/re_syntax.n: Removed two notes to myself (oops), cleaned
- up wording, fixed changebars, made two examples easier to read.
+ * doc/re_syntax.n: Removed two notes to myself (oops), cleaned up
+ wording, fixed changebars, made two examples easier to read.
-1999-07-11 <redman@scriptics.com>
+1999-07-11 Scott Redman <redman@scriptics.com>
- * win/makefile.vc: Since the makefile.vc should continue to work
- while we're working out bugs/issues in the new TEA-style
+ * win/makefile.vc: Since the makefile.vc should continue to work while
+ we're working out bugs/issues in the new TEA-style
autoconf/configure/gmake build mechanism for Windows, the version
- numbers of the Tcl libraries need to remain in sync. Modified the
+ numbers of the Tcl libraries need to remain in sync. Modified the
version numbers in the makefile to reflect the change to 8.2b1.
-1999-07-09 <redman@scriptics.com>
+1999-07-09 Scott Redman <redman@scriptics.com>
- * win/configure.in: Eval DLLSUFFIX, LIBSUFFIX, and EXESUFFIX in
- the configure script so that substitutions get expanded before
- being placed in the Makefile. The "d" portion for debug libraries
- and DLLs was not being set properly.
-
-1999-07-08 <stanton@scriptics.com>
+ * win/configure.in: Eval DLLSUFFIX, LIBSUFFIX, and EXESUFFIX in the
+ configure script so that substitutions get expanded before being
+ placed in the Makefile. The "d" portion for debug libraries and DLLs
+ was not being set properly.
- * tests/string.test:
- * generic/tclCmdMZ.c: Fixed bug in string range bounds checking
- code.
+1999-07-08 Scott Stanton <stanton@scriptics.com>
+
+ * tests/string.test:
+ * generic/tclCmdMZ.c: Fixed bug in string range bounds checking code.
1999-07-08 Jennifer Hom <jenn@scriptics.com>
* doc/tcltest.n:
* library/tcltest1.0/tcltest.tcl: Removed -asidefromdir and
- -relateddir flags, removed unused ::tcltest::dotests proc, cleaned
- up implementation of core file checking, and fixed the code that
- checks for 1-letter flag abbreviations.
+ -relateddir flags, removed unused ::tcltest::dotests proc, cleaned up
+ implementation of core file checking, and fixed the code that checks
+ for 1-letter flag abbreviations.
-1999-07-08 <stanton@scriptics.com>
+1999-07-08 Scott Stanton <stanton@scriptics.com>
- * win/Makefile.in: Added tcltest target so runtest works
- properly. Added missing names to the clean/distclean targets.
+ * win/Makefile.in: Added tcltest target so runtest works properly.
+ Added missing names to the clean/distclean targets.
- * tests/reg.test:
- * generic/rege_dfa.c: Applied fix supplied by Henry Spencer for
- bug in DFA state caching under lookahead conditions. [Bug: 2318]
+ * tests/reg.test:
+ * generic/rege_dfa.c: Applied fix supplied by Henry Spencer for bug in
+ DFA state caching under lookahead conditions. [Bug 2318]
-1999-07-07 <stanton@scriptics.com>
+1999-07-07 Scott Stanton <stanton@scriptics.com>
* doc/fconfigure.n: Clarified default buffering behavior for the
- standard channels. [Bug: 2335]
+ standard channels. [Bug 2335]
-1999-07-06 <redman@scriptics.com>
+1999-07-06 Scott Redman <redman@scriptics.com>
- * win/tclWinSerial.c: New implementation of serial port driver
- from Rolf Shroedter (Rolf.Schroedter@dlr.de) that allows more than
- one byte to be read from the port. Implemented using polling
- instead of threads, there is a max. 10ms latency between checking the
- port for file events. [Bug: 1980 2217]
+ * win/tclWinSerial.c: New implementation of serial port driver from
+ Rolf Shroedter (Rolf.Schroedter@dlr.de) that allows more than one byte
+ to be read from the port. Implemented using polling instead of
+ threads, there is a max. 10ms latency between checking the port for
+ file events. [Bug 1980 2217]
-1999-07-06 <welch@scriptics.com>
+1999-07-06 Brent Welch <welch@scriptics.com>
- * library/http2.0/http.tcl: Fixed the -timeout option so it
- handles timeouts that occur during connection attempts to
- hosts that are down (the only case that really matters!)
+ * library/http2.0/http.tcl: Fixed the -timeout option so it handles
+ timeouts that occur during connection attempts to hosts that are down
+ (the only case that really matters!)
-1999-07-03 <welch@scriptics.com>
+1999-07-03 Brent Welch <welch@scriptics.com>
* doc/ChnlStack.3:
* generic/tcl.decls:
- * generic/tclIO.c: Added a new variant of the "Trf patch"
- from Andreas Kupres that adds new C APIs Tcl_StackChannel,
- Tcl_UnstackChannel, and Tcl_GetStackedChannel.
+ * generic/tclIO.c: Added a new variant of the "Trf patch" from Andreas
+ Kupres that adds new C APIs Tcl_StackChannel, Tcl_UnstackChannel, and
+ Tcl_GetStackedChannel.
-1999-07-03 <welch@scriptics.com>
+1999-07-03 Brent Welch <welch@scriptics.com>
* generic/tclNotify.c:
* unix/tclUnixNotfy.c:
* unix/tclXtTest.c:
* unix/tclXtNotify.c:
* win/tclWinNotify.c:
- * mac/tclMacNotify.c: Added Tcl_SetNotifier and the associated
- hook points in the notifiers to be able to replace the notifier
- calls at runtime The Xt notifier and test program use this hook.
+ * mac/tclMacNotify.c: Added Tcl_SetNotifier and the associated hook
+ points in the notifiers to be able to replace the notifier calls at
+ runtime. The Xt notifier and test program use this hook.
-1999-07-03 <welch@scriptics.com>
+1999-07-03 Brent Welch <welch@scriptics.com>
- * generic/tclParse.c: Changed parsing of variable names to
- allow empty array names. Now "$(foo)" is a variable reference!
- Previous you had to use something like $::(foo), which is slower.
- This change is requested by Jean-Luc Fontaine for his STOOOP
- package.
+ * generic/tclParse.c: Changed parsing of variable names to allow empty
+ array names. Now "$(foo)" is a variable reference! Previous you had to
+ use something like $::(foo), which is slower. This change is requested
+ by Jean-Luc Fontaine for his STOOOP package.
-1999-07-01 <redman@scriptics.com>
+1999-07-01 Scott Redman <redman@scriptics.com>
* generic/tclCmdAH.c:
* generic/tclFCmd.c: Call TclStat instead of TclpStat in order to
@@ -1104,30 +1084,27 @@
* library/tcltest1.0/pkgIndex.tcl:
* library/tcltest1.0/tcltest.tcl:
* doc/tcltest.n:
- * tests/all.tcl: Added -preservecore, -limitconstraints, -help,
- -file, -notfile, -relateddir and -asidefromdir flags to the
- tcltest package along with exported proc
- ::tcltest::getMatchingFiles. The documentation was modified to
- match and all.tcl was modified to use the new functionality
- instead of implementing -file itself.
+ * tests/all.tcl: Added -preservecore, -limitconstraints, -help, -file,
+ -notfile, -relateddir and -asidefromdir flags to the tcltest package
+ along with exported proc ::tcltest::getMatchingFiles. The
+ documentation was modified to match and all.tcl was modified to use
+ the new functionality instead of implementing -file itself.
-1999-06-28 <redman@scriptics.com>
+1999-06-28 Scott Redman <redman@scriptics.com>
* generic/tclIndexObj.c:
* doc/GetIndex.3:
* tests/binary.test:
- * tests/winDde.test: Applied patch from Peter Hardie (with
- changes) to fix problem with Tcl_GetIndexFromObj() when the key
- being passed is the empty string. It used to match "" and return
- TCL_OK, but it should have returned TCL_ERROR instead. Added test
- case to "binary" and "dde" commands to check the behavior. Added
- documentation note as well.
+ * tests/winDde.test: Applied patch from Peter Hardie (with changes) to
+ fix problem with Tcl_GetIndexFromObj() when the key being passed is
+ the empty string. It used to match "" and return TCL_OK, but it should
+ have returned TCL_ERROR instead. Added test case to "binary" and "dde"
+ commands to check the behavior. Added documentation note as well.
-1999-06-26 <redman@scriptics.com>
+1999-06-26 Scott Redman <redman@scriptics.com>
- * win/tclWinDde.c: Applied patch from Peter Hardie to add poke
- command to dde. Also rev'd version of dde package to 1.1.
- [Bug: 1738]
+ * win/tclWinDde.c: Applied patch from Peter Hardie to add poke command
+ to dde. Also rev'd version of dde package to 1.1. [Bug 1738]
1999-06-25 Jennifer Hom <jenn@scriptics.com>
@@ -1136,25 +1113,24 @@
* library/tcltest1.0/pkgIndex.tcl:
* library/tcltest1.0/tcltest.tcl:
* library/tcltest1.0: Added initial implementation of the Tcl test
- harness package. This package was based on the defs.tcl file that
- was part of the tests directory. Reversed the way that tests were
+ harness package. This package was based on the defs.tcl file that was
+ part of the tests directory. Reversed the way that tests were
evaluated to fix a problem with false passes.
* doc/tcltest.n: Added documentation for the tcltest package.
* tests/README:
* tests/defs.tcl:
- * tests/all.tcl: Modified all test files (tests/*.test) and
- all.tcl to use the new tcltest package and removed references to
- the defs.tcl file. Modified the README file to point to the man
- page for tcltest.
-
-1999-06-25 <stanton@scriptics.com>
-
- * tests/reg.test:
+ * tests/all.tcl: Modified all test files (tests/*.test) and all.tcl to
+ use the new tcltest package and removed references to the defs.tcl
+ file. Modified the README file to point to the man page for tcltest.
+
+1999-06-25 Scott Stanton <stanton@scriptics.com>
+
+ * tests/reg.test:
* generic/regexec.c: Fixed bugs in non-greedy quantifiers.
-1999-06-23 <jpeek@scriptics.com>
+1999-06-23 Jerry Peek <jpeek@scriptics.com>
* doc/re_syntax.n:
* doc/switch.n:
@@ -1162,59 +1138,59 @@
* doc/RegExp.3:
* doc/regexp.n:
* doc/regsub.n: Moved information about syntax of 8.1 regular
- expressions from regexp(n) manpage into new re_syntax(n) page.
- Added pointers from other manpages to new re_syntax(n) page.
+ expressions from regexp(n) manpage into new re_syntax(n) page. Added
+ pointers from other manpages to new re_syntax(n) page.
-1999-06-23 <stanton@scriptics.com>
+1999-06-23 Scott Stanton <stanton@scriptics.com>
* unix/Makefile.in: Changed install-doc to install-man.
- * tools/uniParse.tcl:
- * tools/uniClass.tcl:
- * tools/README:
- * tests/string.test:
- * generic/regc_locale.c:
- * generic/tclUniData.c:
- * generic/tclUtf.c:
+ * tools/uniParse.tcl:
+ * tools/uniClass.tcl:
+ * tools/README:
+ * tests/string.test:
+ * generic/regc_locale.c:
+ * generic/tclUniData.c:
+ * generic/tclUtf.c:
* doc/string.n: Updated Unicode character tables to reflect latest
- Unicode 2.1 data. Also rationalized "regexp" and "string is"
+ Unicode 2.1 data. Also rationalized "regexp" and "string is"
definitions of character classes.
-1999-06-21 <stanton@scriptics.com>
+1999-06-21 Scott Stanton <stanton@scriptics.com>
* unix/tclUnixThrd.c (TclpThreadCreate): Fixed memory leak where
- thread attributes were not being released. [Bug: 2254]
+ thread attributes were not being released. [Bug 2254]
-1999-06-17 <stanton@scriptics.com>
+1999-06-17 Scott Stanton <stanton@scriptics.com>
- * tests/regexp.test:
- * generic/tclCmdMZ.c:
- * generic/tclCmdIL.c: Changed to use new regexp interfaces. Added
+ * tests/regexp.test:
+ * generic/tclCmdMZ.c:
+ * generic/tclCmdIL.c: Changed to use new regexp interfaces. Added
-expanded, -line, -linestop, and -lineanchor switches to regsub.
- * doc/RegExp.3: Documented the new regexp interfaces and
- the compile/execute flags.
-
- * generic/tclTest.c:
+ * doc/RegExp.3: Documented the new regexp interfaces and the
+ compile/execute flags.
+
+ * generic/tclTest.c:
* generic/tclRegexp.h:
- * generic/tclRegexp.c:
- * generic/tcl.h:
- * generic/tcl.decls: Renamed Tcl_RegExpMatchObj to
- Tcl_RegExpExecObj and added a new Tcl_RegExpMatchObj that is
- equivalent to Tcl_RegExpMatch. Added public macros for the regexp
- compile/execute flags. Changed to store either an object pointer
- or a string pointer in the TclRegexp structure. Changed to avoid
- adding a reference to the object or copying the string.
+ * generic/tclRegexp.c:
+ * generic/tcl.h:
+ * generic/tcl.decls: Renamed Tcl_RegExpMatchObj to Tcl_RegExpExecObj
+ and added a new Tcl_RegExpMatchObj that is equivalent to
+ Tcl_RegExpMatch. Added public macros for the regexp compile/execute
+ flags. Changed to store either an object pointer or a string pointer
+ in the TclRegexp structure. Changed to avoid adding a reference to the
+ object or copying the string.
* generic/regcomp.c: lint
- * tests/reg.test:
- * generic/regex.h:
+ * tests/reg.test:
+ * generic/regex.h:
* generic/regc_lex.c: Added REG_BOSONLY flag to allow Expect to
iterate through a string an only find matches that start at the
current position within the string.
-1999-06-16 <wart@scriptics.com>
+1999-06-16 Michael Thomas <wart@scriptics.com>
* unix/configure.in:
* unix/Makefile.in:
@@ -1224,15 +1200,15 @@
1999-06-16 Melissa Hirschl <hershey@matisse.scriptics.com>
- * generic/tclVar.c (Tcl_VariableObjCmd): fixed premature increment
- in loop that was causing out-of-bounds reads on array "varName".
+ * generic/tclVar.c (Tcl_VariableObjCmd): fixed premature increment in
+ loop that was causing out-of-bounds reads on array "varName".
-1999-06-16 <stanton@scriptics.com>
+1999-06-16 Scott Stanton <stanton@scriptics.com>
* tests/execute.test:
- * generic/tclExecute.c (TclExecuteByteCode): Fixed crash caused by
- a bug in INST_LOAD_SCALAR1 where the scalar index was read as
- a signed 1 byte value instead of unsigned. [Bug: 2243]
+ * generic/tclExecute.c (TclExecuteByteCode): Fixed crash caused by a
+ bug in INST_LOAD_SCALAR1 where the scalar index was read as a signed 1
+ byte value instead of unsigned. [Bug 2243]
1999-06-14 Melissa Hirschl <hershey@matisse.scriptics.com>
@@ -1242,118 +1218,116 @@
* win/Makefile.in
* win/makefile.vc
* generic/tclStringObj.c:
- Merged String and Unicode object types. Added new functions to
- the puplic API: Tcl_NewUnicodeObj, Tcl_SetUnicodeObj,
- Tcl_GetUnicode, Tcl_GetUniChar, Tcl_GetCharLength, Tcl_GetRange,
+ Merged String and Unicode object types. Added new functions to the
+ puplic API: Tcl_NewUnicodeObj, Tcl_SetUnicodeObj, Tcl_GetUnicode,
+ Tcl_GetUniChar, Tcl_GetCharLength, Tcl_GetRange,
Tcl_AppendUnicodeToObj.
-1999-06-09 <stanton@scriptics.com>
+1999-06-09 Scott Stanton <stanton@scriptics.com>
- * generic/tclUnicodeObj.c: Lots of cleanup and simplification.
- Fixed several memory bugs. Added TclAppendUnicodeToObj.
+ * generic/tclUnicodeObj.c: Lots of cleanup and simplification. Fixed
+ several memory bugs. Added TclAppendUnicodeToObj.
* generic/tclInt.h: Added declarations for various Unicode string
- functions.
-
- * generic/tclRegexp.c:
- * generic/tclCmdMZ.c: Changed to use new Unicode string interfaces
- for better performance.
-
- * generic/tclRegexp.h:
- * generic/tclRegexp.c:
- * generic/tcl.h:
- * generic/tcl.decls: Added Tcl_RegExpMatchObj and
- Tcl_RegExpGetInfo calls to access lower level regexp API. These
- features are needed by Expect. This is a preliminary
- implementation pending final review and cleanup.
+ functions.
+
+ * generic/tclRegexp.c:
+ * generic/tclCmdMZ.c: Changed to use new Unicode string interfaces for
+ better performance.
+
+ * generic/tclRegexp.h:
+ * generic/tclRegexp.c:
+ * generic/tcl.h:
+ * generic/tcl.decls: Added Tcl_RegExpMatchObj and Tcl_RegExpGetInfo
+ calls to access lower level regexp API. These features are needed by
+ Expect. This is a preliminary implementation pending final review and
+ cleanup.
* generic/tclCmdMZ.c:
- * tests/string.test: Fixed bug where string map failed on null
- strings.
+ * tests/string.test: Fixed bug where string map failed on null strings
- * generic/regexec.c:
+ * generic/regexec.c:
* unix/tclUnixNotfy.c: lint
* tools/genStubs.tcl: Changed to always write output in LF mode.
-1999-06-08 <stanton@scriptics.com>
+1999-06-08 Scott Stanton <stanton@scriptics.com>
- * win/tclWinSock.c: Rolled back to the 8.1.0 implementation
- because of serious problems with the new driver. Basically no
- incoming socket connections would be reported to a server port.
- The 8.1.1 code needs to be redesigned and fixed correctly.
+ * win/tclWinSock.c: Rolled back to the 8.1.0 implementation because of
+ serious problems with the new driver. Basically no incoming socket
+ connections would be reported to a server port. The 8.1.1 code needs
+ to be redesigned and fixed correctly.
1999-06-07 Melissa Hirschl <hershey@matisse.scriptics.com>
- * tests/string.test:
+ * tests/string.test:
* generic/tclVar.c (Tcl_SetVar2Ex):
* generic/tclStringObj.c (Tcl_AppendObjToObj):
- * generic/tclCmdMZ.c (Tcl_StringObjCmd): optimized the string
- index, string length, string range, and append command in cases
- where the object's internal rep is a bytearray. Objects with
- other internal reps are converted to have the new unicode internal
- rep.
-
- * unix/Makefile.in:
- * win/Makefile.in:
- * win/Makefile.vc:
- * tests/unicode.test:
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd): optimized the string index,
+ string length, string range, and append command in cases where the
+ object's internal rep is a bytearray. Objects with other internal reps
+ are converted to have the new unicode internal rep.
+
+ * unix/Makefile.in:
+ * win/Makefile.in:
+ * win/Makefile.vc:
+ * tests/unicode.test:
* generic/tclInt.h:
* generic/tclObj.c:
* generic/tclUnicodeObj.c: added a new object type to store the
unicode representation of a string.
* generic/tclTestObj.c: added the objtype option to the testobj
- command. This option returns the name of the type of internal rep
- an object has.
+ command. This option returns the name of the type of internal rep an
+ object has.
-1999-06-04 <stanton@scriptics.com>
+1999-06-04 Scott Stanton <stanton@scriptics.com>
- * win/configure.in:
+ * win/configure.in:
* win/Makefile.in: Windows build now handles static/dynamic
- debug/nodebug builds and supports the standard targets using
- Cygwin user tools plus GNU make and autoconf.
+ debug/nodebug builds and supports the standard targets using Cygwin
+ user tools plus GNU make and autoconf.
-1999-06-03 <stanton@scriptics.com>
+1999-06-03 Scott Stanton <stanton@scriptics.com>
- * generic/tclCmdMZ.c (Tcl_StringObjCmd):
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd):
* tests/string.test: Fixed bug where string equal/compare -nocase
- reported wrong result on null strings. [Bug: 2138]
+ reported wrong result on null strings. [Bug 2138]
-1999-06-02 <stanton@scriptics.com>
+1999-06-02 Scott Stanton <stanton@scriptics.com>
- * generic/tclUtf.c (Tcl_UtfNcasecmp): Fixed incorrect computation
- of relative ordering. [Bug: 2135]
+ * generic/tclUtf.c (Tcl_UtfNcasecmp): Fixed incorrect computation of
+ relative ordering. [Bug 2135]
-1999-06-01 <stanton@scriptics.com>
+1999-06-01 Scott Stanton <stanton@scriptics.com>
* unix/configure.in: Fixed various small configure.in patches
- submitted by Jan Nijtmans. [Bug: 2121]
-
- * tests/reg.test:
- * generic/regc_color.c:
- * generic/regc_cvec.c:
- * generic/regc_lex.c:
- * generic/regc_locale.c:
- * generic/regc_nfa.c:
- * generic/regcomp.c:
- * generic/regcustom.h:
- * generic/rege_dfa.c:
- * generic/regerror.c:
- * generic/regerrs.h:
- * generic/regex.h:
- * generic/regexec.c:
- * generic/regfree.c:
- * generic/regfronts.c:
- * generic/regguts.h:
- * generic/tclCmdMZ.c:
- * generic/tclRegexp.c:
- * generic/tclRegexp.h:
+ submitted by Jan Nijtmans. [Bug 2121]
+
+ * tests/reg.test:
+ * generic/regc_color.c:
+ * generic/regc_cvec.c:
+ * generic/regc_lex.c:
+ * generic/regc_locale.c:
+ * generic/regc_nfa.c:
+ * generic/regcomp.c:
+ * generic/regcustom.h:
+ * generic/rege_dfa.c:
+ * generic/regerror.c:
+ * generic/regerrs.h:
+ * generic/regex.h:
+ * generic/regexec.c:
+ * generic/regfree.c:
+ * generic/regfronts.c:
+ * generic/regguts.h:
+ * generic/tclCmdMZ.c:
+ * generic/tclRegexp.c:
+ * generic/tclRegexp.h:
* generic/tclTest.c: Applied Henry Spencer's latest regexp patches
- that fix an infinite loop bug and add support for testing whether
- a string could match with additional input. [Bug: 2117]
+ that fix an infinite loop bug and add support for testing whether a
+ string could match with additional input. [Bug 2117]
-1999-05-28 <stanton@scriptics.com>
+1999-05-28 Scott Stanton <stanton@scriptics.com>
* generic/tclObj.c: Changed to eliminate use of isupper/tolower in
favor of the Unicode versions.
@@ -1362,427 +1336,409 @@
* win/configure.in: Added preliminary TEA implementation.
* win/tclWinDde.c: Fixed bug where dde calls were being passed an
- invalid dde handle because Initialize had not been called.
- [Bug: 2124]
+ invalid dde handle because Initialize had not been called. [Bug 2124]
-1999-05-26 <redman@scriptic.com>
+1999-05-26 Scott Redman <redman@scriptic.com>
- * generic/tclThreadTest.c: Fixed race condition in testthread
- code that showed up in the WinNT test suite intermittently.
+ * generic/tclThreadTest.c: Fixed race condition in testthread code
+ that showed up in the WinNT test suite intermittently.
- * win/tclWinSock.c: Fixed a hang in the WinNT socket driver, wake
- up the socket thread every 100ms to check for events on the
- sockets that did not wake up the thread (race condition).
+ * win/tclWinSock.c: Fixed a hang in the WinNT socket driver, wake up
+ the socket thread every 100ms to check for events on the sockets that
+ did not wake up the thread (race condition).
-1999-05-24 <stanton@scriptics.com>
+1999-05-24 Scott Stanton <stanton@scriptics.com>
- * tools/genStubs.tcl: Changed to allow a list of platforms instead
- of just one at a time.
+ * tools/genStubs.tcl: Changed to allow a list of platforms instead of
+ just one at a time.
- * generic/tcl.decls:
- * generic/tclCmdMZ.c:
- * generic/tclDecls.h:
- * generic/tclInt.decls:
- * generic/tclIntDecls.h:
- * generic/tclPort.h:
- * generic/tclStubInit.c:
+ * generic/tcl.decls:
+ * generic/tclCmdMZ.c:
+ * generic/tclDecls.h:
+ * generic/tclInt.decls:
+ * generic/tclIntDecls.h:
+ * generic/tclPort.h:
+ * generic/tclStubInit.c:
* generic/tclStubLib.c: Various header file related changes and other
lint to try to get the Mac builds working.
-1999-05-21 <redman@scriptics.com>
+1999-05-21 Scott Redman <redman@scriptics.com>
- * win/tclWinPipe.c: Fix bug when launching command.com on
- Win95/98. Need to wait for the procInfo.hProcess of the process that
- was created, not the hProcess of the current process. [Bug: 2105]
+ * win/tclWinPipe.c: Fix bug when launching command.com on Win95/98.
+ Need to wait for the procInfo.hProcess of the process that was
+ created, not the hProcess of the current process. [Bug 2105]
-1999-05-20 <redman@scriptics.com>
+1999-05-20 Scott Redman <redman@scriptics.com>
- * library/init.tcl: Add the directory where the executable is, and
- the ../lib directory relative to that, to the auto_path variable.
-
-1999-05-19 <stanton@scriptics.com>
+ * library/init.tcl: Add the directory where the executable is, and the
+ ../lib directory relative to that, to the auto_path variable.
+
+1999-05-19 Scott Stanton <stanton@scriptics.com>
Merged in various changes submitted by Jeff Hobbs:
-
- * generic/tcl.decls:
- * generic/tclUtf.c: Added Tcl_UniCharIs* functions for control,
- graph, print, and punct classes.
+
+ * generic/tcl.decls:
+ * generic/tclUtf.c: Added Tcl_UniCharIs* functions for control, graph,
+ print, and punct classes.
* generic/tclUtil.c:
* doc/StrMatch.3: Added Tcl_StringCaseMatch() implementation to
support case-insensitive globbing.
-
- * doc/string.n:
- * unix/mkLinks:
- * tests/string.test:
- * generic/tclCmdMZ.c: Added additional character class tests,
- added -nocase switch to "string match", changed string first/last
- to use offsets.
-1999-05-19 <redman@scriptics.com>
+ * doc/string.n:
+ * unix/mkLinks:
+ * tests/string.test:
+ * generic/tclCmdMZ.c: Added additional character class tests, added
+ -nocase switch to "string match", changed string first/last to use
+ offsets.
+
+1999-05-19 Scott Redman <redman@scriptics.com>
* generic/tcl.h: Add extern "C" block around entire header file for
- C++ compilers to fix linkage issues. Submitted by Don Porter and
- Paul Duffin.
+ C++ compilers to fix linkage issues. Submitted by Don Porter and Paul
+ Duffin.
- * generic/tclRegexp.c: Fix bug when the regexp cache is empty
- and an empty pattern is used in regexp ( such as {} or "" ).
+ * generic/tclRegexp.c: Fix bug when the regexp cache is empty and an
+ empty pattern is used in regexp ( such as {} or "" ).
-1999-05-18 <stanton@scriptics.com>
+1999-05-18 Scott Stanton <stanton@scriptics.com>
- * win/tclWinChan.c: Modified initialization code to avoid
- inherenting closed or invalid channels. If the standard input is
- anything other than a console, file, serial port, or pipe, then we
- fall back to the standard Tk window console.
+ * win/tclWinChan.c: Modified initialization code to avoid inherenting
+ closed or invalid channels. If the standard input is anything other
+ than a console, file, serial port, or pipe, then we fall back to the
+ standard Tk window console.
-1999-05-14 <stanton@scriptics.com>
+1999-05-14 Scott Stanton <stanton@scriptics.com>
- * generic/tclCmdAH.c (Tcl_ForObjCmd): Fixed crash caused by
- failure to reset the result before evaluating the test
- expression.
+ * generic/tclCmdAH.c (Tcl_ForObjCmd): Fixed crash caused by failure to
+ reset the result before evaluating the test expression.
-1999-05-14 <surles@scriptics.com>
+1999-05-14 Bryan Surles <surles@scriptics.com>
- * generic/tclBasic.c (Tcl_CreateInterp): Added introspection
- variable for threaded interps. If the interp was compiled with
- threads enabled, the tcl_platform(threaded) variable will exist.
+ * generic/tclBasic.c (Tcl_CreateInterp): Added introspection variable
+ for threaded interps. If the interp was compiled with threads enabled,
+ the tcl_platform(threaded) variable will exist.
-1999-05-14 <redman@scriptics.com>
+1999-05-14 Scott Redman <redman@scriptics.com>
* generic/tclDate.c: Applied patch to fix 100-year and 400-year
- boundaries in leap year code, from Isaac Hollander. [Bug: 2066]
+ boundaries in leap year code, from Isaac Hollander. [Bug 2066]
-1999-05-13 <stanton@scriptics.com>
+1999-05-13 Scott Stanton <stanton@scriptics.com>
* unix/Makefile.in:
* unix/tclAppInit.c: Minor cleanup related to Xt notifier.
-
- * unix/tclUnixInit.c (TclpSetInitialEncodings): Tcl now looks for
- an encoding subfield in the LANG/LC_ALL variables in cases where
- the locale is not found in the locale table. Ensure that
- setlocale() is called at least once so X11 will initialize
- properly. Also, forces the LC_NUMERIC locale to be "C" so numeric
- processing in scripts is not affected by the current locale
- setting. [Bug: 1989]
- * generic/tclRegexp.c: Increased per-thread regexp cache to 30
- slots. This seems to be about the right number for larger
- applications like exmh. [Bug: 1063]
+ * unix/tclUnixInit.c (TclpSetInitialEncodings): Tcl now looks for an
+ encoding subfield in the LANG/LC_ALL variables in cases where the
+ locale is not found in the locale table. Ensure that setlocale() is
+ called at least once so X11 will initialize properly. Also, forces the
+ LC_NUMERIC locale to be "C" so numeric processing in scripts is not
+ affected by the current locale setting. [Bug 1989]
+
+ * generic/tclRegexp.c: Increased per-thread regexp cache to 30 slots.
+ This seems to be about the right number for larger applications like
+ exmh. [Bug 1063]
-1999-05-12 <stanton@scriptics.com>
+1999-05-12 Scott Stanton <stanton@scriptics.com>
* doc/tclsh.1: Updated references to rc script names to accurately
reflect the platform differences on Windows.
- * tests/regexp.test:
- * generic/tclInt.h:
- * generic/tclBasic.c:
+ * tests/regexp.test:
+ * generic/tclInt.h:
+ * generic/tclBasic.c:
* generic/tclRegexp.h:
- * generic/tclRegexp.c: Replaced the per-interpreter regexp cache
- with a per-thread cache. Changed the Regexp object to take
- advantage of this extra cache. Added a reference count to the
- TclRegexp type so regexps can be shared by multiple objects.
- Removed the per-interp regexp cache from the interpreter. Now
- regexps can be used with no need for an interpreter. [Bug: 1063]
-
- * win/tclWinInit.c (TclpSetVariables): Avoid calling GetUserName
- if the value can be determined from the USERNAME environment
- variable. GetUserName is very slow.
-
-1999-05-07 <stanton@scriptics.com>
-
- * win/winDumpExts.c:
- * win/makefile.vc: Removed incorrect patch. [Bug: 1998]
-
+ * generic/tclRegexp.c: Replaced the per-interpreter regexp cache with
+ a per-thread cache. Changed the Regexp object to take advantage of
+ this extra cache. Added a reference count to the TclRegexp type so
+ regexps can be shared by multiple objects. Removed the per-interp
+ regexp cache from the interpreter. Now regexps can be used with no
+ need for an interpreter. [Bug 1063]
+
+ * win/tclWinInit.c (TclpSetVariables): Avoid calling GetUserName if
+ the value can be determined from the USERNAME environment variable.
+ GetUserName is very slow.
+
+1999-05-07 Scott Stanton <stanton@scriptics.com>
+
+ * win/winDumpExts.c:
+ * win/makefile.vc: Removed incorrect patch. [Bug 1998]
+
* generic/tcl.decls: Replaced const with CONST.
- * generic/tclResult.c (Tcl_AppendResultVA):
+ * generic/tclResult.c (Tcl_AppendResultVA):
* generic/tclStringObj.c (Tcl_AppendStringsToObjVA): Fixed to copy
arglist using memcpy instead of assignment so it works properly on
- OS/390. [Bug: 1997]
+ OS/390. [Bug 1997]
* generic/tclLoadNone.c: Updated to use current interfaces, added
- TclpUnloadFile. [Bug: 2003]
+ TclpUnloadFile. [Bug 2003]
- * win/winDumpExts.c:
- * win/makefile.vc: Changed to emit library name in defs
- file. [Bug: 1998]
+ * win/winDumpExts.c:
+ * win/makefile.vc: Changed to emit library name in defs file. [Bug
+ 1998]
- * unix/configure.in: Added fix for OS/390. [Bug: 1976]
+ * unix/configure.in: Added fix for OS/390. [Bug 1976]
-1999-05-06 <stanton@scriptics.com>
+1999-05-06 Scott Stanton <stanton@scriptics.com>
- * tests/string.test:
- * generic/tclCmdMZ.c:
+ * tests/string.test:
+ * generic/tclCmdMZ.c:
* doc/string.n: Fixed bug in string equal/compare code when using
- -length option. Cleaned up docs a bit more.
-
- * tests/http.test: Unset "data" array before running tests to
- avoid failures due to previous tests.
-
- * doc/string.n:
- * tests/cmdIL.test:
- * tests/cmdMZ.test:
- * tests/error.test:
- * tests/ioCmd.test:
- * tests/lindex.test:
- * tests/linsert.test:
- * tests/lrange.test:
- * tests/lreplace.test:
- * tests/string.test:
- * tests/cmdIL.test:
- * generic/tclUtil.c:
- * generic/tclCmdMZ.c: Replaced "string icompare/iequal" with
- -nocase and -length switches to "string compare/equal". Added a
- -nocase option to "string map". Changed index syntax to allow
- integer or end?-integer? instead of a full expression. This is
- much simpler with safeTcl scripts since it avoids double
- substitution issues.
-
- * doc/Utf.3:
- * generic/tclStubInit.c:
- * generic/tclDecls.h:
+ -length option. Cleaned up docs a bit more.
+
+ * tests/http.test: Unset "data" array before running tests to avoid
+ failures due to previous tests.
+
+ * doc/string.n:
+ * tests/cmdIL.test:
+ * tests/cmdMZ.test:
+ * tests/error.test:
+ * tests/ioCmd.test:
+ * tests/lindex.test:
+ * tests/linsert.test:
+ * tests/lrange.test:
+ * tests/lreplace.test:
+ * tests/string.test:
+ * tests/cmdIL.test:
+ * generic/tclUtil.c:
+ * generic/tclCmdMZ.c: Replaced "string icompare/iequal" with -nocase
+ and -length switches to "string compare/equal". Added a -nocase option
+ to "string map". Changed index syntax to allow integer or
+ end?-integer? instead of a full expression. This is much simpler with
+ safeTcl scripts since it avoids double substitution issues.
+
+ * doc/Utf.3:
+ * generic/tclStubInit.c:
+ * generic/tclDecls.h:
* generic/tclUtf.c:
* generic/tcl.decls: Added Tcl_UtfNcmp and Tcl_UtfNcasecmp.
-1999-05-05 <stanton@scriptics.com>
+1999-05-05 Scott Stanton <stanton@scriptics.com>
* win/makefile.vc: Added encoding directory to install-libraries
target.
-1999-05-03 <stanton@scriptics.com>
-
- * doc/string.n:
- * tests/cmdMZ.test:
- * tests/string.test:
- * generic/tclCmdMZ.c (Tcl_StringObjCmd): Changed "string length"
- to avoid regenerating the string rep of a ByteArray object.
-
- * tests/cmdIL.test:
- * tests/cmdMZ.test:
- * tests/error.test:
+1999-05-03 Scott Stanton <stanton@scriptics.com>
+
+ * doc/string.n:
+ * tests/cmdMZ.test:
+ * tests/string.test:
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd): Changed "string length" to
+ avoid regenerating the string rep of a ByteArray object.
+
+ * tests/cmdIL.test:
+ * tests/cmdMZ.test:
+ * tests/error.test:
* tests/lindex.test:
- * tests/linsert.test:
- * tests/lrange.test:
- * tests/lreplace.test:
- * tests/string.test:
- * generic/tclCmdMZ.c (Tcl_StringObjCmd):
- * generic/tclUtil.c (TclGetIntForIndex): Applied Jeff Hobbs's
- string patch which includes the following changes [Bug: 1845]:
-
- - string compare now takes optional length arg (for strncmp
- behavior)
-
- - added string equal (just a few lines of code blended
- in with string compare)
-
- - added string icompare/iequal for case-insensitive comparisons
-
- - string index's index can now be ?end[+-]?expression
- I made this change in the private TclGetIntForIndex,
- which means that the list commands also benefit, as
- well as string range, et al.
-
- - added [string repeat string count]
- Repeats given string number of times
-
- - added string replace, string equiv to lreplace
- (quasi opposite of string range):
- string replace first last ?string?
- Example of use, replacing end of string with ...
- should the string be more than 16 chars long:
- string replace $string 16 end "..."
- This just returns the string len < 16, so it
- will only affect the long strings.
-
- - added optional first and last args to string to*
- This allows you to just affect certain regions of
- a string with the command (like just capping the
- first letter). I found the original totitle to
- be too draconian to be useful.
-
- - added [string map charMap string]
- where charMap is a {from to from to} list that equates to
- what one might get from [array get]. Each and
- can be multiple chars (or none at all). For Tcl/CGI users,
- this is a MAJOR speed booster.
-
- * generic/tclParse.c (Tcl_ParseCommand): Changed to avoid
- modifying eval'ed strings that are already null terminated.
- [Bug: 1793]
-
- * tests/binary.test:
- * generic/tclBinary.c (DupByteArrayInternalRep): Fixed bug where
- type was not being set in duplicated object. [Bug: 1975, 2047]
-
-1999-04-30 <stanton@scriptics.com>
-
+ * tests/linsert.test:
+ * tests/lrange.test:
+ * tests/lreplace.test:
+ * tests/string.test:
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd):
+ * generic/tclUtil.c (TclGetIntForIndex): Applied Jeff Hobbs's string
+ patch which includes the following changes [Bug 1845]:
+ - string compare now takes optional length arg (for strncmp behavior)
+ - added string equal (just a few lines of code blended in with string
+ compare)
+ - added string icompare/iequal for case-insensitive comparisons
+ - string index's index can now be ?end[+-]?expression
+ I made this change in the private TclGetIntForIndex, which means
+ that the list commands also benefit, as well as string range, et al.
+ - added [string repeat string count]
+ Repeats given string number of times
+ - added string replace, string equiv to lreplace
+ (quasi opposite of string range):
+ string replace first last ?string?
+ Example of use, replacing end of string with ... should the string
+ be more than 16 chars long:
+ string replace $string 16 end "..."
+ This just returns the string len < 16, so it will only affect the
+ long strings.
+ - added optional first and last args to string to*
+ This allows you to just affect certain regions of a string with the
+ command (like just capping the first letter). I found the original
+ totitle to be too draconian to be useful.
+ - added [string map charMap string]
+ where charMap is a {from to from to} list that equates to what one
+ might get from [array get]. Each and can be multiple chars (or none
+ at all). For Tcl/CGI users, this is a MAJOR speed booster.
+
+ * generic/tclParse.c (Tcl_ParseCommand): Changed to avoid modifying
+ eval'ed strings that are already null terminated. [Bug 1793]
+
+ * tests/binary.test:
+ * generic/tclBinary.c (DupByteArrayInternalRep): Fixed bug where type
+ was not being set in duplicated object. [Bug 1975, 2047]
+
+1999-04-30 Scott Stanton <stanton@scriptics.com>
+
* Changed version to 8.1.1.
-
-1999-04-30 <stanton@scriptics.com>
+
+1999-04-30 Scott Stanton <stanton@scriptics.com>
* Merged changes from 8.1.0 branch:
* generic/tclParse.c: Fixed memory leak in CommandComplete.
- * generic/tclPlatDecls.h:
- * generic/tclIntPlatDecls.h:
- * generic/tclIntDecls.h:
- * generic/tclDecls.h:
+ * generic/tclPlatDecls.h:
+ * generic/tclIntPlatDecls.h:
+ * generic/tclIntDecls.h:
+ * generic/tclDecls.h:
* tools/genStubs.tcl: Added 'extern "C" {}' block around the stub
- table pointer declaration so the stub library can be used from
- C++. [Bug: 1934]
+ table pointer declaration so the stub library can be used from C++.
+ [Bug 1934]
* Lots of documentation and other release engineering fixes.
-1999-04-28 <stanton@scriptics.com>
+1999-04-28 Scott Stanton <stanton@scriptics.com>
- * mac/tclMacResource.c:
- * generic/tclListObj.c:
- * generic/tclObj.c:
+ * mac/tclMacResource.c:
+ * generic/tclListObj.c:
+ * generic/tclObj.c:
* generic/tclStringObj.c: Changed to avoid freeing the string
- representation before freeing the internal rep. This helps with
- debugging since the string rep will still be valid when the free
- proc is invoked.
+ representation before freeing the internal rep. This helps with
+ debugging since the string rep will still be valid when the free proc
+ is invoked.
-1999-04-27 <stanton@scriptics.com>
+1999-04-27 Scott Stanton <stanton@scriptics.com>
- * generic/tclLiteral.c (TclHideLiteral): Fixed so hidden literals
- get duplicated to avoid accidental sharing in the global object
- table.
+ * generic/tclLiteral.c (TclHideLiteral): Fixed so hidden literals get
+ duplicated to avoid accidental sharing in the global object table.
-1999-04-23 <stanton@scriptics.com>
+1999-04-23 Scott Stanton <stanton@scriptics.com>
- * generic/tclStubInit.c:
+ * generic/tclStubInit.c:
* tools/genStubs.tcl: Changed to avoid the need for forward
declarations in stub initializers.
-1999-04-23 <stanton@scriptics.com>
+1999-04-23 Scott Stanton <stanton@scriptics.com>
* library/encoding/koi8-r.enc:
* tools/encoding/koi8-r.txt: Added support for the koi8-r Cyrillic
- encoding. [Bug: 1771]
+ encoding. [Bug 1771]
-1999-04-22 <stanton@scriptics.com>
+1999-04-22 Scott Stanton <stanton@scriptics.com>
* win/tclWinFCmd.c:
- * win/tclWin32Dll.c: Changed uses of "try" to "__try", since that
- is the actual keyword. This eliminates the need for some -D flags
- from the makefile.
+ * win/tclWin32Dll.c: Changed uses of "try" to "__try", since that is
+ the actual keyword. This eliminates the need for some -D flags from
+ the makefile.
- * generic/tclPort.h: Added include of tcl.h since it defines
- various Windows macros that are needed before deciding which
- platform porting file to use.
+ * generic/tclPort.h: Added include of tcl.h since it defines various
+ Windows macros that are needed before deciding which platform porting
+ file to use.
* generic/tclEvent.c: lint
- * win/tclWinInit.c (TclpInitPlatform): Added call to TclWinInit
- when building a static library since DllMain will not be invoked.
- This could break old code that explicitly called TclWinInit, but
- should be simpler in the long run.
+ * win/tclWinInit.c (TclpInitPlatform): Added call to TclWinInit when
+ building a static library since DllMain will not be invoked. This
+ could break old code that explicitly called TclWinInit, but should be
+ simpler in the long run.
1999-04-22 Scott Stanton <stanton@scriptics.com>
- * generic/tclInt.h:
- * generic/tclInt.decls:
- * generic/tclCompile.c: Added TclSetByteCodeFromAny that takes a
- hook procedure to invoke after compilation but before the byte
- codes are emitted. This makes it possible to do postprocessing on
- the compiled byte codes before the ByteCode is generated.
+ * generic/tclInt.h:
+ * generic/tclInt.decls:
+ * generic/tclCompile.c: Added TclSetByteCodeFromAny that takes a hook
+ procedure to invoke after compilation but before the byte codes are
+ emitted. This makes it possible to do postprocessing on the compiled
+ byte codes before the ByteCode is generated.
+
+ * generic/tclLiteral.c: Added TclHideLiteral and TclAddLiteralObj to
+ make it possible to create local unshared literal objects.
- * generic/tclLiteral.c: Added TclHideLiteral and TclAddLiteralObj
- to make it possible to create local unshared literal objects.
-
* win/tclWinInit.c:
* unix/tclUnixInit.c: Changed initial search path to match that
found used by tcl_findLibrary.
-1999-04-22 <redman@scriptics.com>
+1999-04-22 Scott Redman <redman@scriptics.com>
* win/tclWinPort.h:
- * win/tclWinSock.c: Added code to use WinSock 2.0 API on NT to
- avoid creating a window to handle sockets. API not available on
- Win95 and needs to be fixed on Win98, until then continue to use
- the older (window-based) scheme on those two OSes.
-
-1999-04-15 <stanton@scriptics.com>
+ * win/tclWinSock.c: Added code to use WinSock 2.0 API on NT to avoid
+ creating a window to handle sockets. API not available on Win95 and
+ needs to be fixed on Win98, until then continue to use the older
+ (window-based) scheme on those two OSes.
+
+1999-04-15 Scott Stanton <stanton@scriptics.com>
* Merged 8.1 back into the main trunk
-1999-04-13 <stanton@scriptics.com>
+1999-04-13 Scott Stanton <stanton@scriptics.com>
* library/encoding/gb2312.enc:
* library/encoding/euc-cn.enc:
* tools/encoding/gb2312.txt:
* tools/encoding/cp950.txt:
* tools/encoding/Makefile: Restored the double byte definition of
- GB2312 and added the EUC-CN encoding. EUC-CN is a variant of
- GB2312 that shifts the characters into bytes with the high bit set
- and includes ASCII as a subset. [Bug: 632]
+ GB2312 and added the EUC-CN encoding. EUC-CN is a variant of GB2312
+ that shifts the characters into bytes with the high bit set and
+ includes ASCII as a subset. [Bug 632]
-1999-04-13 <redman@scriptics.com>
+1999-04-13 Scott Redman <redman@scriptics.com>
- * win/tclWinSock.c: Apply patch to allow write access to a socket
- if FD_WRITE is sent but FD_CONNECT is not. Some strange problem
- with either Win32 or a socket driver. [Bug: 1664 1776]
+ * win/tclWinSock.c: Apply patch to allow write access to a socket if
+ FD_WRITE is sent but FD_CONNECT is not. Some strange problem with
+ either Win32 or a socket driver. [Bug 1664 1776]
-1999-04-09 <redman@scriptics.com>
+1999-04-09 Scott Redman <redman@scriptics.com>
- * unix/tclUnixNotfy.c: Fixed notifier deadlock situation when the
- pipe used to talk back notifier thread is filled with data. When
- calling the write() function to feed data down that pipe, unlock
- the notifierMutex to allow the notifier to wake up again. Found
- as a result of the focus.test for Tk hanging. [Bug: 1700]
+ * unix/tclUnixNotfy.c: Fixed notifier deadlock situation when the pipe
+ used to talk back notifier thread is filled with data. When calling
+ the write() function to feed data down that pipe, unlock the
+ notifierMutex to allow the notifier to wake up again. Found as a
+ result of the focus.test for Tk hanging. [Bug 1700]
-1999-04-06 <stanton@scriptics.com>
+1999-04-06 Scott Stanton <stanton@scriptics.com>
* tests/unixNotfy.test: Fixed hang in tests when built with thread
- support.
+ support.
- * tests/httpold.test: Fixed broken test that didn't wait long
- enough for events to arrive.
+ * tests/httpold.test: Fixed broken test that didn't wait long enough
+ for events to arrive.
* tests/unixInit.test: Fixed race condition in test.
-
- * tests/unixInit.test:
+
+ * tests/unixInit.test:
* tests/fileName.test: Minor test nits.
* unix/tclUnixInit.c (TclpSetInitialEncodings): Fixed bad initial
encoding string.
-1999-04-06 <surles@scriptics.com>
+1999-04-06 Bryan Surles <surles@scriptics.com>
- * generic/tclVar.c:
- * generic/tclEnv.c: Moved the "array set" C level code into a
- common routine (TclArraySet). The TclSetupEnv routine now uses
- this API to create an env array w/ no elements.
+ * generic/tclVar.c:
+ * generic/tclEnv.c: Moved the "array set" C level code into a common
+ routine (TclArraySet). The TclSetupEnv routine now uses this API to
+ create an env array w/ no elements.
* generic/tclEnv.c:
* generic/tclWinInit.h:
* generic/tclUnixInit.h:
- * generic/tclInt.h: Made the Env module I18N compliant. Changed the
+ * generic/tclInt.h: Made the Env module I18N compliant. Changed the
FindVariable routine to TclpFindVariable, that now does a case
- insensitive string comparison on Windows, and not on UNIX. [Bug:
- 1299, 1500]
+ insensitive string comparison on Windows, and not on UNIX. [Bug 1299,
+ 1500]
-1999-04-05 <stanton@scriptics.com>
+1999-04-05 Scott Stanton <stanton@scriptics.com>
* tests/io.test: Minor test cleanup.
- * generic/tclEncoding.c (Tcl_CreateEncoding): Minor lint to make
- it easier to compile on Digital-unix. [Bug: 1659]
+ * generic/tclEncoding.c (Tcl_CreateEncoding): Minor lint to make it
+ easier to compile on Digital-unix. [Bug 1659]
- * unix/configure.in:
+ * unix/configure.in:
* unix/tclUnixPort.h: Applied patch for OS/390 to handle lack of
- sys/param.h. [Bug: 1725]
+ sys/param.h. [Bug 1725]
+
+ * unix/configure.in: Fixed BSD/OS 4.* configuration to support shared
+ libraries properly. [Bug 1730]
- * unix/configure.in: Fixed BSD/OS 4.* configuration to support
- shared libraries properly. [Bug: 1730]
-
-1999-04-05 <redman@scriptics.com>
+1999-04-05 Scott Redman <redman@scriptics.com>
- * win/tclWinDde.c: decrease timeout value for DDE calls to 30k
- [Bug: 1639]
+ * win/tclWinDde.c: decrease timeout value for DDE calls to 30k. [Bug
+ 1639]
* generic/tcl.decls:
* generic/tcl.h:
@@ -1792,109 +1748,106 @@
* generic/tclIntDecls.h:
* generic/tclStubInit.c:
* generic/tclUtil.c: Added more functions to the Tcl stubs table,
- including all Tcl_ functions not already in it (except Cmd
- functions) and Tcl_GetCwd() and Tcl_Chdir() (new functions).
-
+ including all Tcl_ functions not already in it (except Cmd functions)
+ and Tcl_GetCwd() and Tcl_Chdir() (new functions).
+
* tests/safe.test:
* doc/safe.n:
* generic/tclBasic.c:
- * library/safe.tcl: The encoding command is not safe as-is, so
- create a safe alias to mask out the "encoding system <name>" but
- allow all other uses including "encoding system". Added test cases
- and updated the man page for Safe Tcl.
-
-1999-04-05 <stanton@scriptics.com>
-
- * tests/winTime.test:
- * win/tclWinTime.c: Fixed crash in clock command that occurred
- when manipulating negative time values in timezones east of
- GMT. [Bug: 1142, 1458]
-
- * tests/platform.test:
+ * library/safe.tcl: The encoding command is not safe as-is, so create
+ a safe alias to mask out the "encoding system <name>" but allow all
+ other uses including "encoding system". Added test cases and updated
+ the man page for Safe Tcl.
+
+1999-04-05 Scott Stanton <stanton@scriptics.com>
+
+ * tests/winTime.test:
+ * win/tclWinTime.c: Fixed crash in clock command that occurred when
+ manipulating negative time values in timezones east of GMT. [Bug
+ 1142, 1458]
+
+ * tests/platform.test:
* tests/fileName.test: Fixed broken tests.
-
+
* generic/tclFileName.c: Moved global regexps into thread local
storage.
- * tests/socket.test: Changed so tests don't reuse sockets,
- since Windows is slow to release sockets.
+ * tests/socket.test: Changed so tests don't reuse sockets, since
+ Windows is slow to release sockets.
- * win/tclWinConsole.c:
- * win/tclWinPipe.c:
- * win/tclWinSerial.c: Fixed race condition where background
- threads were terminated while they still held a lock in the
- notifier.
+ * win/tclWinConsole.c:
+ * win/tclWinPipe.c:
+ * win/tclWinSerial.c: Fixed race condition where background threads
+ were terminated while they still held a lock in the notifier.
-1999-04-02 <stanton@scriptics.com>
+1999-04-02 Scott Stanton <stanton@scriptics.com>
* tests/http.test: Fixed bad test initialization code.
* generic/tclThreadTest.c (ThreadExitProc): Fixed bug where static
- memory was being returned instead of a dynamically allocated
- result in error cases.
+ memory was being returned instead of a dynamically allocated result in
+ error cases.
-1999-04-02 <redman@scriptics.com>
+1999-04-02 Scott Redman <redman@scriptics.com>
* doc/dde.n:
* tools/tcl.wse.in:
* win/makefile.vc:
* win/pkgIndex.tcl:
- * win/tclWinDde.c: Add new DDE package, code removed from Tk now
- separated into its own package. Changed DDE-based send code into
- "dde eval" command. Can be loaded into tclsh (not just wish).
- Windows only.
-
-1999-04-02 <stanton@scriptics.com>
-
- * tests/expr.test:
- * tests/for-old.test:
- * tests/for.test:
- * tests/foreach.test:
- * tests/format.test:
- * tests/httpold.test:
- * tests/if.test:
- * tests/init.test:
- * tests/interp.test:
- * tests/while.test: Added some tests for known bugs (marked with
+ * win/tclWinDde.c: Add new DDE package, code removed from Tk now
+ separated into its own package. Changed DDE-based send code into "dde
+ eval" command. Can be loaded into tclsh (not just wish). Windows only.
+
+1999-04-02 Scott Stanton <stanton@scriptics.com>
+
+ * tests/expr.test:
+ * tests/for-old.test:
+ * tests/for.test:
+ * tests/foreach.test:
+ * tests/format.test:
+ * tests/httpold.test:
+ * tests/if.test:
+ * tests/init.test:
+ * tests/interp.test:
+ * tests/while.test: Added some tests for known bugs (marked with
knownBug constraint), and cleaned up a few bad tests.
- * generic/regc_locale.c:
- * generic/regcustom.h:
- * generic/tcl.decls:
- * generic/tclCmdIL.c:
- * generic/tclCmdMZ.c:
- * generic/tclInt.h:
- * generic/tclRegexp.c:
- * generic/tclScan.c:
+ * generic/regc_locale.c:
+ * generic/regcustom.h:
+ * generic/tcl.decls:
+ * generic/tclCmdIL.c:
+ * generic/tclCmdMZ.c:
+ * generic/tclInt.h:
+ * generic/tclRegexp.c:
+ * generic/tclScan.c:
* generic/tclTest.c:
- * generic/tclUtf.c:
- * win/tclWinFCmd.c:
- * win/tclWinFile.c: Made various Unicode utility functions
- public. The following functions were made public and added to the
- stubs table:
+ * generic/tclUtf.c:
+ * win/tclWinFCmd.c:
+ * win/tclWinFile.c: Made various Unicode utility functions public. The
+ following functions were made public and added to the stubs table:
Tcl_UtfToUniCharDString, Tcl_UniCharToUtfDString,
Tcl_UniCharLen, Tcl_UniCharNcmp, Tcl_UniCharIsAlnum,
Tcl_UniCharIsAlpha, Tcl_UniCharIsDigit, Tcl_UniCharIsLower,
Tcl_UniCharIsSpace, Tcl_UniCharIsUpper, Tcl_UniCharIsWordChar
-1999-04-01 <stanton@scriptics.com>
+1999-04-01 Scott Stanton <stanton@scriptics.com>
- * tests/registry.test:
- * win/tclWinReg.c: Internationalized the registry code. It now
- uses Unicode interfaces on NT. [Bug: 1197]
+ * tests/registry.test:
+ * win/tclWinReg.c: Internationalized the registry code. It now uses
+ Unicode interfaces on NT. [Bug 1197]
- * tests/parse.test:
+ * tests/parse.test:
* generic/tclParse.c: Fixed crash due to multiple frees in parser
- during error cleanup when parsing commands with more tokens than
- will fit in the static area of the parse structure. [Bug: 1681]
+ during error cleanup when parsing commands with more tokens than will
+ fit in the static area of the parse structure. [Bug 1681]
* generic/tclInt.h: Removed duplicate declarations.
- * generic/tclInt.decls:
- * generic/tcl.decls: Added Tcl_WinUtfToTChar and Tcl_WinTCharToUtf
- to the tclPlat table.
+ * generic/tclInt.decls:
+ * generic/tcl.decls: Added Tcl_WinUtfToTChar and Tcl_WinTCharToUtf to
+ the tclPlat table.
-1999-04-01 <redman@scriptics.com>
+1999-04-01 Scott Redman <redman@scriptics.com>
* generic/tcl.decls:
* generic/tcl.h:
@@ -1904,44 +1857,44 @@
* tools/genStubs.tcl:
* unix/Makefile.in:
* win/makefile.vc: Applied patch from Jan Nijtmans to fix Ultrix
- multiple symbol definition problem. Now, even Tcl includes a copy
- of the Tcl stub library. Also fixed TCL_MEM_DEBUG mode (for Tk).
+ multiple symbol definition problem. Now, even Tcl includes a copy of
+ the Tcl stub library. Also fixed TCL_MEM_DEBUG mode (for Tk).
-1999-03-31 <redman@scriptics.com>
+1999-03-31 Scott Redman <redman@scriptics.com>
- * win/tclWinConsole.c: WinNT has a bug when reading a single
- character from the console. Rewrote the code for the console to
- read an entire line at a time using the reader thread.
+ * win/tclWinConsole.c: WinNT has a bug when reading a single character
+ from the console. Rewrote the code for the console to read an entire
+ line at a time using the reader thread.
-1999-03-30 <stanton@scriptics.com>
+1999-03-30 Scott Stanton <stanton@scriptics.com>
- * unix/Makefile.in: Removed trailing backslash that broke the
- "depend" target.
+ * unix/Makefile.in: Removed trailing backslash that broke the "depend"
+ target.
* unix/tclUnixInit.c (TclpSetInitialEncodings): Changed to avoid
- calling setlocale(). We now look directly at env(LANG) and
- env(LC_CTYPE) instead. [Bug: 1636]
+ calling setlocale(). We now look directly at env(LANG) and
+ env(LC_CTYPE) instead. [Bug 1636]
- * generic/tclFileName.c:
- * generic/tclDecls.h:
+ * generic/tclFileName.c:
+ * generic/tclDecls.h:
* generic/tcl.decls: Removed CONST from Tcl_JoinPath and
- Tcl_TranslateFileName because it changes the signature of
- Tcl_JoinPath in an incompatible manner.
+ Tcl_TranslateFileName because it changes the signature of Tcl_JoinPath
+ in an incompatible manner.
- * generic/tclInt.h:
- * generic/tclLoad.c (TclFinalizeLoad):
+ * generic/tclInt.h:
+ * generic/tclLoad.c (TclFinalizeLoad):
* generic/tclEvent.c (Tcl_Finalize): Defer unloading of loadable
- modules until all exit handlers have been invoked.
- [Bug: 998, 1273, 1573, 1593]
+ modules until all exit handlers have been invoked. [Bug 998, 1273,
+ 1573, 1593]
-1999-03-29 <stanton@scriptics.com>
+1999-03-29 Scott Stanton <stanton@scriptics.com>
- * generic/tclFileName.c:
- * generic/tclDecls.h:
+ * generic/tclFileName.c:
+ * generic/tclDecls.h:
* generic/tcl.decls: Added CONST to Tcl_JoinPath and
Tcl_TranslateFileName.
-1999-03-29 <redman@scriptics.com>
+1999-03-29 Scott Redman <redman@scriptics.com>
* tools/genStubs.tcl:
* unix/configure.in:
@@ -1952,207 +1905,203 @@
* generic/tclDecls.h:
* generic/tclIntDecls.h:
* generic/tclPlatDecls.h:
- * generic/tclIntPlatDecls.h: Removed the stub functions and
- changed the stub macros to just use the name without params. Pass
- &tclStubs into the interp (don't use tclStubsPtr because of
- collisions with the stubs on Solaris).
-
-1999-03-27 <redman@scriptics.com>
+ * generic/tclIntPlatDecls.h: Removed the stub functions and changed
+ the stub macros to just use the name without params. Pass &tclStubs
+ into the interp (don't use tclStubsPtr because of collisions with the
+ stubs on Solaris).
- * win/makefile.bc: Removed makefile for Borland compiler, no
- longer supported.
+1999-03-27 Scott Redman <redman@scriptics.com>
-1999-03-26 <redman@scriptics.com>
+ * win/makefile.bc: Removed makefile for Borland compiler, no longer
+ supported.
+
+1999-03-26 Scott Redman <redman@scriptics.com>
* win/tclWinSerial.c:
* win/tclWinConsole.c:
- * win/tclWinPipe.c: Don't close the Win32 handle for a channel if
- it's a stdio handle (GetStdHandle()) during shutdown of a thread
- to prevent it from destroying the stdio of other threads.
+ * win/tclWinPipe.c: Don't close the Win32 handle for a channel if it's
+ a stdio handle (GetStdHandle()) during shutdown of a thread to prevent
+ it from destroying the stdio of other threads.
+
+1999-03-26 Suresh Ankolekar <suresh@scriptics.com>
-1999-03-26 <suresh@scriptics.com>
+ * unix/configure.in: --nameble-shared is now the default and build Tcl
+ as a shared library; specify --disable-shared to build a static Tcl
+ library and shell.
- * unix/configure.in
- --nameble-shared is now the default and build Tcl as a shared
- library; specify --disable-shared to build a static Tcl library
- and shell.
+1999-03-25 Scott Stanton <stanton@scriptics.com>
-1999-03-25 <stanton@scriptics.com>
+ * tests/interp.test:
+ * generic/tclInterp.c (AliasObjCmd): Changed so aliases are invoked at
+ current scope in the target interpreter instead of at the global
+ scope. This was an incompatibility introduced in 8.1 that is being
+ removed. [Bug 1153, 1556]
- * tests/interp.test:
- * generic/tclInterp.c (AliasObjCmd): Changed so aliases are
- invoked at current scope in the target interpreter instead of at
- the global scope. This was an incompatibility introduced in 8.1
- that is being removed. [Bug: 1153, 1556]
-
* library/encoding/big5.enc:
* library/encoding/gb2312.enc:
* tools/encoding/big5.enc:
- * tools/encoding/gb2312.enc: Added ASCII to big5 and gb2312
- encodings. [Bug: 632]
-
+ * tools/encoding/gb2312.enc: Added ASCII to big5 and gb2312 encodings.
+ [Bug 632]
+
* generic/tclPkg.c (Tcl_PkgRequireEx): Fixed broken clientData
initialization in package code.
- * unix/Makefile.in (dist): Added tcl.decls and tclInt.decls to
- source distribution. [Bug: 1571]
+ * unix/Makefile.in (dist): Added tcl.decls and tclInt.decls to source
+ distribution. [Bug 1571]
* doc/Thread.3: Updated documentation of Tcl_MutexLock to indicate
- that the recursive locking behavior is undefined. On Windows, it
- does not block, on Unix it deadlocks. [Bug: 1275]
+ that the recursive locking behavior is undefined. On Windows, it does
+ not block, on Unix it deadlocks. [Bug 1275]
-1999-03-24 <stanton@scriptics.com>
+1999-03-24 Scott Stanton <stanton@scriptics.com>
- * tests/execute.test:
+ * tests/execute.test:
* generic/tclExecute.c (TclExecuteByteCode): Fixed expression code
- that incorrectly returned floating point values for integers if
- the internal rep happened to be a double. Now we check to see if
- the object has a string rep that looks like an integer before
- using the double internal rep. [Bug: 1516]
+ that incorrectly returned floating point values for integers if the
+ internal rep happened to be a double. Now we check to see if the
+ object has a string rep that looks like an integer before using the
+ double internal rep. [Bug 1516]
-1999-03-24 <redman@scriptics.com>
+1999-03-24 Scott Redman <redman@scriptics.com>
* generic/tclAlloc.c:
* generic/tclEncoding.c:
* generic/tclProc.c:
* unix/tclUnixTime.c:
- * win/tclWinSerial.c: Fixed compilation warnings/errors for VC++
- 5.0 and 6.0 and HP-UX native compiler without -Aa or -Ae.
- [Bug: 1323 1518 1324 1583 1585 1586]
+ * win/tclWinSerial.c: Fixed compilation warnings/errors for VC++ 5.0
+ and 6.0 and HP-UX native compiler without -Aa or -Ae. [Bug 1323 1518
+ 1324 1583 1585 1586]
- * win/tclWinSock.c: Make sockets thread-safe on Windows. The
- current implementation uses windows to handle events on the
- socket, one for each thread (thread local storage). Previously,
- there was only one window shared between threads, which didn't
- work. [Bug: 1326]
+ * win/tclWinSock.c: Make sockets thread-safe on Windows. The current
+ implementation uses windows to handle events on the socket, one for
+ each thread (thread local storage). Previously, there was only one
+ window shared between threads, which didn't work. [Bug 1326]
-1999-03-23 <stanton@scriptics.com>
+1999-03-23 Scott Stanton <stanton@scriptics.com>
- * tools/tcl.wse: Fixed file association to look in the right place
- for the wish icon. [Bug: 1544]
+ * tools/tcl.wse: Fixed file association to look in the right place for
+ the wish icon. [Bug 1544]
- * tests/winNotify.test:
- * tests/ioCmd.test:
+ * tests/winNotify.test:
+ * tests/ioCmd.test:
* tests/event.test: Changed to use new style conditionals.
* tests/encoding.test: Fixed nonportable test.
- * unix/dltest/configure.in:
- * unix/dltest/Makefile.in: Added missing DBGX macros. [Bug: 1564]
+ * unix/dltest/configure.in:
+ * unix/dltest/Makefile.in: Added missing DBGX macros. [Bug 1564]
- * tests/winNotify.test:
- * mac/tclMacNotify.c:
- * win/tclWinNotify.c:
+ * tests/winNotify.test:
+ * mac/tclMacNotify.c:
+ * win/tclWinNotify.c:
* unix/tclUnixNotfy.c:
- * generic/tclNotify.c: Added a new Tcl_ServiceModeHook interface
- that is invoked whenever the service mode changes. This is needed
- to allow the Windows notifier to create a communication window the
- first time Tcl is about to enter an external modal event loop
- instead of at startup time. This will avoid the various problems
- that people have been seeing where the system hangs when tclsh
- is running outside of the event loop. [Bug: 783]
-
- * generic/tclInt.h:
+ * generic/tclNotify.c: Added a new Tcl_ServiceModeHook interface that
+ is invoked whenever the service mode changes. This is needed to allow
+ the Windows notifier to create a communication window the first time
+ Tcl is about to enter an external modal event loop instead of at
+ startup time. This will avoid the various problems that people have
+ been seeing where the system hangs when tclsh is running outside of
+ the event loop. [Bug 783]
+
+ * generic/tclInt.h:
* generic/tcl.decls: Renamed TclpAlertNotifier back to
- Tcl_AlertNotifier since it is part of the public notifier driver
- API.
+ Tcl_AlertNotifier since it is part of the public notifier driver API.
+
+1999-03-23 Scott Redman <redman@scriptics.com>
-1999-03-23 <redman@scriptics.com>
+ * win/tclWinSerial.c: Fixed problem with fileevent on the serial port
+ and nonblocking mode. Gets no longer hangs, fileevents fire whenever
+ there is any character data on the port.
- * win/tclWinSerial.c: Fixed problem with fileevent on the serial
- port and nonblocking mode. Gets no longer hangs, fileevents fire
- whenever there is any character data on the port.
-
* tests/winConsole.test:
- * win/tclWinConsole.c: Fixed problem with fileevents and gets from
- a console stdin. Previously, fileevents were firing before an
- entire line was available for reading, which meant that when you
- did a gets or read, it blocked (even in nonblocking mode). Now, it
- should work the same as Unix: fileevents fire when an entire line
- is ready, and gets and read do not block in non-blocking mode.
- Added an interactive test case to check for this.
+ * win/tclWinConsole.c: Fixed problem with fileevents and gets from a
+ console stdin. Previously, fileevents were firing before an entire
+ line was available for reading, which meant that when you did a gets
+ or read, it blocked (even in nonblocking mode). Now, it should work
+ the same as Unix: fileevents fire when an entire line is ready, and
+ gets and read do not block in non-blocking mode. Added an interactive
+ test case to check for this.
-1999-03-22 <stanton@scriptics.com>
+1999-03-22 Scott Stanton <stanton@scriptics.com>
- * tests/reg.test:
+ * tests/reg.test:
* generic/regc_color.c: Applied regexp bug fix from Henry Spencer.
-1999-03-19 <redman@scriptics.com>
+1999-03-19 Scott Redman <redman@scriptics.com>
- * generic/tclCmdIL.c: Fixed the initialization of an array so that
- the Sun 5.0 C compiler wouldn't complain.
+ * generic/tclCmdIL.c: Fixed the initialization of an array so that the
+ Sun 5.0 C compiler wouldn't complain.
- * unix/configure.in: Added support for --enable-64bit. For now,
- this is only supported on Solaris 7 64bit (SunOS 5.7) using the Sun
+ * unix/configure.in: Added support for --enable-64bit. For now, this
+ is only supported on Solaris 7 64bit (SunOS 5.7) using the Sun
compiler (not gcc).
-
-1999-03-18 <stanton@scriptics.com>
- * win/tclWinChan.c (TclpOpenFileChannel, Tcl_MakeFileChannel):
- Changed to only test for console or comm handles when the type is
- FILE_TYPE_CHAR to avoid useless tests on simple files. Also
- reordered tests so consoles are tested first as this is more
- common.
+1999-03-18 Scott Stanton <stanton@scriptics.com>
+
+ * win/tclWinChan.c (TclpOpenFileChannel, Tcl_MakeFileChannel): Changed
+ to only test for console or comm handles when the type is
+ FILE_TYPE_CHAR to avoid useless tests on simple files. Also reordered
+ tests so consoles are tested first as this is more common.
* win/makefile.vc: Regularized usage of mkd and rmd and rm.
- * library/encoding/shiftjis.enc:
+ * library/encoding/shiftjis.enc:
* tools/encoding/shiftjis.txt: Missing/incorrect characters in
- shift-jis table. [Bug: 1008, 1526]
+ shift-jis table. [Bug 1008, 1526]
* generic/tclInt.decls:
* generic/tcl.decls: Eliminated use of "string" and "list" from
- argument lists to avoid conflicts with C++ STL. [Bug: 1181]
+ argument lists to avoid conflicts with C++ STL. [Bug 1181]
* win/tclWinFile.c (TclpMatchFiles): Changed to ignore the
- FS_CASE_IS_PRESERVED bit and always return exactly what we get
- from the system.
+ FS_CASE_IS_PRESERVED bit and always return exactly what we get from
+ the system.
-1999-03-17 <stanton@GASPODE>
+1999-03-17 Scott Stanton <stanton@GASPODE>
- * win/README.binary:
- * win/README:
- * unix/configure.in:
- * generic/tcl.h:
+ * win/README.binary:
+ * win/README:
+ * unix/configure.in:
+ * generic/tcl.h:
* README: Updated version to 8.1b3.
-1999-03-14 <stanton@GASPODE>
+1999-03-14 Scott Stanton <stanton@GASPODE>
- * win/tclWinConsole.c:
- * win/tclWinPipe.c:
+ * win/tclWinConsole.c:
+ * win/tclWinPipe.c:
* win/tclWinSerial.c: Changed so channel drivers wait for the
reader/writer threads to exit before returning during a close
- operation. This ensures that the main thread is the last thread
- to exit, so the process return value is set properly.
-
- * generic/tclIntDecls.h:
- * generic/tclIntPlatDecls.h:
- * generic/tclIntPlatStubs.c:
- * generic/tclIntStubs.c:
- * generic/tclPlatDecls.h:
- * generic/tclPlatStubs.c:
- * generic/tclStubInit.c:
+ operation. This ensures that the main thread is the last thread to
+ exit, so the process return value is set properly.
+
+ * generic/tclIntDecls.h:
+ * generic/tclIntPlatDecls.h:
+ * generic/tclIntPlatStubs.c:
+ * generic/tclIntStubs.c:
+ * generic/tclPlatDecls.h:
+ * generic/tclPlatStubs.c:
+ * generic/tclStubInit.c:
* generic/tclStubs.c: Fixed bad eol characters.
-
- * generic/tclInt.decls: Changed "const" to "CONST" in
- declarations for better portability.
+
+ * generic/tclInt.decls: Changed "const" to "CONST" in declarations for
+ better portability.
* generic/tcl.decls: Renamed panic and panicVA to Tcl_Panic and
Tcl_PanicVA in the stub files.
- * generic/tclInterp.c (Tcl_MakeSafe): Remove tcl_platform(user)
- from safe interps.
+ * generic/tclInterp.c (Tcl_MakeSafe): Remove tcl_platform(user) from
+ safe interps.
-1999-03-11 <stanton@GASPODE>
+1999-03-11 Scott Stanton <stanton@GASPODE>
* unix/Makefile.in:
* unix/configure.in: Include compat files in the stub library in
- addition to the main library. Compat files are now built for
- dynamic use in all cases.
-
+ addition to the main library. Compat files are now built for dynamic
+ use in all cases.
+
* generic/tcl.h: Changed magic number so it doesn't match the plus
patch, at Jan's request.
-
+
* unix/tclConfig.sh.in:
* unix/dltest/Makefile.in:
* unix/dltest/configure.in:
@@ -2161,65 +2110,62 @@
* unix/dltest/pkgc.c:
* unix/dltest/pkgd.c:
* unix/dltest/pkge.c:
- * unix/dltest/pkgf.c: Changed package tests to build against the
- stubs library.
+ * unix/dltest/pkgf.c: Changed package tests to build against the stubs
+ library.
-1999-03-10 <stanton@GASPODE>
+1999-03-10 Scott Stanton <stanton@GASPODE>
- * generic/tcl.h:
- * generic/tcl.decls: Changed Tcl_ReleaseType from an enum to
- macros so it can be used in .rc files.
- Added Tcl_GetString.
+ * generic/tcl.h:
+ * generic/tcl.decls: Changed Tcl_ReleaseType from an enum to macros so
+ it can be used in .rc files. Added Tcl_GetString.
* mac/tclMacNotify.c:
* generic/tclNotify.c:
- * generic/tclInt.h:
- * win/tclWinNotify.c:
+ * generic/tclInt.h:
+ * win/tclWinNotify.c:
* generic/tcl.h: Renamed Tcl_AlertNotifier to TclpAlertNotifier.
- * generic/tclInt.decls: Added TclWinAddProcess to make it possible
- for expect to use Tcl_WaitForPid(). This patch is from Gordon
- Chaffee.
+ * generic/tclInt.decls: Added TclWinAddProcess to make it possible for
+ expect to use Tcl_WaitForPid(). This patch is from Gordon Chaffee.
- * mac/tclMacPort.h:
- * win/tclWinInit.c:
- * unix/tclUnixPort.h:
- * generic/tclAsync.c: Added TclpAsyncMark to fix bug in async
- handling on Windows where async events don't wake up the event
- loop. This patch comes from Gordon Chaffee.
+ * mac/tclMacPort.h:
+ * win/tclWinInit.c:
+ * unix/tclUnixPort.h:
+ * generic/tclAsync.c: Added TclpAsyncMark to fix bug in async handling
+ on Windows where async events don't wake up the event loop. This patch
+ comes from Gordon Chaffee.
* generic/tcl.decls: Fixed declarations of reserved slots.
-
-1999-03-10 <redman@scriptic.com>
+
+1999-03-10 Scott Redman <redman@scriptic.com>
* generic/tclCompile.h: Ensure that the ByteCode struct is binary
compatible with the version in 8.0.6.
* generic/tcl.h:
- * generic/tclBasic.c: Add Tcl_GetVersion() function to the public
- C API to allow programs to check the version number of the Tcl
- library at runtime. Also added an enum to clarify the release
- level (alpha, beta, final).
+ * generic/tclBasic.c: Add Tcl_GetVersion() function to the public C
+ API to allow programs to check the version number of the Tcl library
+ at runtime. Also added an enum to clarify the release level (alpha,
+ beta, final).
-1999-03-09 <stanton@GASPODE>
+1999-03-09 Scott Stanton <stanton@GASPODE>
* Integrated changes from Tcl 8.0 including:
stubs mechanism
configure patches from Jan Nijtmans
rename of panic to Tcl_Panic
-
-1999-03-08 <lfb@scriptics.com>
- * win/tclWin32Dll.c: Removed Dll instance from thread-local
- storage.
+1999-03-08 Lee Bernhard <lfb@scriptics.com>
+
+ * win/tclWin32Dll.c: Removed Dll instance from thread-local storage.
-1999-03-08 <stanton@GASPODE>
-
- * generic/tcl.h: Moved Tcl_Mutex, etc. macros above the inclusion
- of tclDecls.h to avoid macro conflicts.
+1999-03-08 Scott Stanton <stanton@GASPODE>
+
+ * generic/tcl.h: Moved Tcl_Mutex, etc. macros above the inclusion of
+ tclDecls.h to avoid macro conflicts.
* generic/tclInt.h:
- * generic/regc_color.c:
+ * generic/regc_color.c:
* generic/regcomp.c:
* generic/tclCmdIL.c:
* generic/tclCmdAH.c:
@@ -2228,20 +2174,20 @@
* generic/tclStringObj.c:
* unix/tclUnixNotfy.c: Cleaned up various compiler warnings,
eliminated UCHAR bugs.
-
+
* unix/tclUnixNotfy.c:
* unix/tclUnixThrd.c:
* generic/tclThreadTest.c:
* mac/tclMacThrd.c: Changed TclpCondition*() to Tcl_Condition*().
-
+
* INTEGRATED PATCHES FROM 8.0.6:
* generic/tcl.decls:
* generic/tcl.h:
- * generic/tclBasic.c:
+ * generic/tclBasic.c:
* generic/tclDecls.h:
* generic/tclInt.decls:
- * generic/tclInt.h:
+ * generic/tclInt.h:
* generic/tclIntDecls.h:
* generic/tclIntPlatDecls.h:
* generic/tclIntPlatStubs.c:
@@ -2255,199 +2201,194 @@
* unix/configure.in:
* unix/Makefile.in:
* unix/tclConfig.sh.in:
- * win/makefile.vc:
- * win/tclWinPort.h: Added Tcl stubs implementation. There are
- now two new macros USE_TCL_STUBS and USE_TCL_STUB_PROCS that
- enable use of stubs and disable stub macros respectively. All of
- the public and private function declarations from tcl.h and
- tclInt.h have moved into the *.decls files and the *Stubs.c and
- *Decls.h files are generated using the genStubs.tcl script.
+ * win/makefile.vc:
+ * win/tclWinPort.h: Added Tcl stubs implementation. There are now two
+ new macros USE_TCL_STUBS and USE_TCL_STUB_PROCS that enable use of
+ stubs and disable stub macros respectively. All of the public and
+ private function declarations from tcl.h and tclInt.h have moved into
+ the *.decls files and the *Stubs.c and *Decls.h files are generated
+ using the genStubs.tcl script.
* unix/Makefile.in:
- * unix/configure.in:
+ * unix/configure.in:
* unix/ldAix: Enhanced AIX shared library support.
* win/tclWinSock.c: Removed a bunch of extraneous PASCAL FAR
attributes from internal functions.
- * win/tclWinReg.c: Changed registry package to use stubs mechanism
- so it no longer depends on the specific version of Tcl.
+ * win/tclWinReg.c: Changed registry package to use stubs mechanism so
+ it no longer depends on the specific version of Tcl.
- * doc/AddErrInfo.3:
- * doc/Eval.3:
- * doc/PkgRequire.3:
- * doc/SetResult.3:
- * doc/StringObj.3:
+ * doc/AddErrInfo.3:
+ * doc/Eval.3:
+ * doc/PkgRequire.3:
+ * doc/SetResult.3:
+ * doc/StringObj.3:
* generic/tcl.h:
- * generic/tclBasic.c:
+ * generic/tclBasic.c:
* generic/tclPanic.c:
* generic/tclStringObj.c:
* generic/tclUtil.c:
- * unix/mkLinks: Added va_list versions of all VARARGS
- functions so they can be invoked from the stub functions.
+ * unix/mkLinks: Added va_list versions of all VARARGS functions so
+ they can be invoked from the stub functions.
- * doc/package.n:
- * doc/PkgRequire.3:
+ * doc/package.n:
+ * doc/PkgRequire.3:
* generic/tclPkg.c: Added Tcl_PkgProvideEx, Tcl_RequireEx,
- Tcl_PresentEx, and Tcl_PkgPresent. Added "package present"
- command.
+ Tcl_PresentEx, and Tcl_PkgPresent. Added "package present" command.
- * generic/tclFileName.c:
- * mac/tclMacFile.c:
- * mac/tclMacShLib.exp:
- * unix/tclUnixFile.c:
- * win/tclWinFile.c: Changed so TclGetUserHome is defined on
- all platforms, even though it is currently a noop on mac and
- windows, and renamed it to TclpGetUserHome.
+ * generic/tclFileName.c:
+ * mac/tclMacFile.c:
+ * mac/tclMacShLib.exp:
+ * unix/tclUnixFile.c:
+ * win/tclWinFile.c: Changed so TclGetUserHome is defined on all
+ platforms, even though it is currently a noop on mac and windows, and
+ renamed it to TclpGetUserHome.
* generic/tclPanic.c:
* generic/panic.c: Renamed panic to Tcl_Panic.
-
-1999-02-25 <redman@scriptics.com>
+
+1999-02-25 Scott Redman <redman@scriptics.com>
* win/makefile.vc: Added tclWinConsole.c and tclWinSerial.c
-
- * win/tclWinConsole.c: New code to properly deal with fileevents
- and nonblocking mode on consoles.
-
- * win/tclWinSerial.c: New code to properly deal with fileevents
- and nonblocking mode on serial ports.
-
- * win/tclWinPipe.c:
+
+ * win/tclWinConsole.c: New code to properly deal with fileevents and
+ nonblocking mode on consoles.
+
+ * win/tclWinSerial.c: New code to properly deal with fileevents and
+ nonblocking mode on serial ports.
+
+ * win/tclWinPipe.c:
* win/tclWinPort.h: Exported functions to allow creation of pipe
channels from tclWinChan.c
* win/tclWinChan.c: Check the type of a channel, including for the
- standard (stdin/stdout/stderr), and use the correct channel type
- to create the channel (file, serial, console, or pipe).
+ standard (stdin/stdout/stderr), and use the correct channel type to
+ create the channel (file, serial, console, or pipe).
-1999-02-11 <stanton@GASPODE>
+1999-02-11 Scott Stanton <stanton@GASPODE>
- * README:
- * generic/tcl.h:
- * win/README.binary:
- * win/README:
- * unix/configure.in:
+ * README:
+ * generic/tcl.h:
+ * win/README.binary:
+ * win/README:
+ * unix/configure.in:
* mac/README: Updated version numbers to 8.1b2.
-1999-02-10 <stanton@GASPODE>
+1999-02-10 Scott Stanton <stanton@GASPODE>
- * library/auto.tcl: Fixed auto_mkindex so it handles .tbc files.
- Did some general cleanup to handle bad eval statements that didn't
- use "list".
+ * library/auto.tcl: Fixed auto_mkindex so it handles .tbc files. Did
+ some general cleanup to handle bad eval statements that didn't use
+ "list".
* unix/mkLinks:
* doc/SetVar.3:
* generic/tcl.h:
- * generic/tclVar.c: Restored Tcl_ObjGetVar2 and Tcl_ObjSetVar2
- from 8.0. Renamed Tcl_Get/SetObjVar2 to Tcl_GetVar2Ex and
- Tcl_SetVar2Ex.
+ * generic/tclVar.c: Restored Tcl_ObjGetVar2 and Tcl_ObjSetVar2 from
+ 8.0. Renamed Tcl_Get/SetObjVar2 to Tcl_GetVar2Ex and Tcl_SetVar2Ex.
-1999-02-10 <stanton@GASPODE>
+1999-02-10 Scott Stanton <stanton@GASPODE>
- INTEGRATED PATCHES FROM 8.0.5b2:
+ INTEGRATED PATCHES FROM 8.0.5b2:
* test/winPipe.test: Changed to remove echoArgs.tcl temporary file
when done.
-
+
* tests/cmdAH.test:
* generic/tclFileName.c (TclGetExtension): Changed behavior so the
split happens at the last period in the name instead of the first
- period of the last run of periods. So, "foo..o" is split into
- "foo." and ".o" now. [Bug: 1126]
-
- * win/makefile.vc: Added better support for paths with spaces in
- the name. Added .lib and support .dlls to the install-binaries
- target. Added generate of a pkgIndex.tcl script to the
- install-libraries target.
-
- * win/tclAppInit.c:
- * unix/tclAppInit.c:
- * mac/tclMacAppInit.c:
- * generic/tclTest.c: Changed some EXTERN declarations to extern
- since they are not defining exported interfaces. This avoids
- generating useless declspec() attributes and makes the windows
- makefile simpler.
-
- * generic/tcl.h: Moved Tcl_AppInit declaration to end and cleared
- out TCL_STORAGE_CLASS so it is not declared with a declspec().
+ period of the last run of periods. So, "foo..o" is split into "foo."
+ and ".o" now. [Bug 1126]
+
+ * win/makefile.vc: Added better support for paths with spaces in the
+ name. Added .lib and support .dlls to the install-binaries target.
+ Added generate of a pkgIndex.tcl script to the install-libraries
+ target.
+
+ * win/tclAppInit.c:
+ * unix/tclAppInit.c:
+ * mac/tclMacAppInit.c:
+ * generic/tclTest.c: Changed some EXTERN declarations to extern since
+ they are not defining exported interfaces. This avoids generating
+ useless declspec() attributes and makes the windows makefile simpler.
+
+ * generic/tcl.h: Moved Tcl_AppInit declaration to end and cleared out
+ TCL_STORAGE_CLASS so it is not declared with a declspec().
* tests/interp.test:
* generic/tclInterp.c (DeleteAlias): Changed to use
- Tcl_DeleteCommandFromToken so we handle renames properly. This
- avoids senseless panic. [Bug: 736]
+ Tcl_DeleteCommandFromToken so we handle renames properly. This avoids
+ senseless panic. [Bug 736]
- * unix/tclUnixChan.c:
- * win/tclWinSock.c:
+ * unix/tclUnixChan.c:
+ * win/tclWinSock.c:
* doc/socket.n: Applied Gordon Chaffee's patch to handle failures
- during asynchronous socket connection operations. This adds a new
- "-error" fconfgure option to socket channels. [Bug: 893]
+ during asynchronous socket connection operations. This adds a new
+ "-error" fconfgure option to socket channels. [Bug 893]
* generic/tclProc.c:
* generic/tclNamesp.c:
- * generic/tclInt.h:
- * generic/tclCmdIL.c:
- * generic/tclBasic.c:
- * generic/tclVar.c: Applied patch from Viktor Dukhovni to
- rationalize TCL_LEAVE_ERR_MSG behavior when creating variables.
-
- * generic/tclVar.c: Fixed bug in namespace tail computation.
- Fixed bug where upvar could resurrect a namespace variable whose
- namespace had been deleted.
+ * generic/tclInt.h:
+ * generic/tclCmdIL.c:
+ * generic/tclBasic.c:
+ * generic/tclVar.c: Applied patch from Viktor Dukhovni to rationalize
+ TCL_LEAVE_ERR_MSG behavior when creating variables.
+
+ * generic/tclVar.c: Fixed bug in namespace tail computation. Fixed bug
+ where upvar could resurrect a namespace variable whose namespace had
+ been deleted.
* generic/tclCompile.c (TclCompileExprCmd): Eliminated yet another
bogus optimization in expression compilation.
- * unix/configure.in: Added branch for BSD/OS-4* to shared library
- case statement. [Bug: 975]
- Fixed to correctly handle IRIX 6.5 n32 library support. [Bug: 1117]
-
- * win/winDumpExts.c: Patched to be pickier about stripping
- @'s. [Bug: 920]
+ * unix/configure.in: Added branch for BSD/OS-4* to shared library case
+ statement. [Bug 975]
+ Fixed to correctly handle IRIX 6.5 n32 library support. [Bug 1117]
- * library/http2.0/http.tcl: Added catch around eof test in
- CopyDone since the user may have already called http::reset.
- [Bug: 1108]
+ * win/winDumpExts.c: Patched to be pickier about stripping @'s. [Bug
+ 920]
- * unix/configure.in: Changed Linux and IRIX to set SHLIB_LIBS to
- LIBS so shared libraries are linked with the system
- libraries. [Bug: 1018]
+ * library/http2.0/http.tcl: Added catch around eof test in CopyDone
+ since the user may have already called http::reset. [Bug 1108]
+
+ * unix/configure.in: Changed Linux and IRIX to set SHLIB_LIBS to LIBS
+ so shared libraries are linked with the system libraries. [Bug 1018]
* generic/tclCompile.c (CompileExprWord): Fixed exception stack
- overflow bug caused by missing statement. [Bug: 928]
+ overflow bug caused by missing statement. [Bug 928]
- * generic/tclIOCmd.c:
- * generic/tclBasic.c: Objectified the "open" command. [Bug: 1113]
+ * generic/tclIOCmd.c:
+ * generic/tclBasic.c: Objectified the "open" command. [Bug 1113]
- * generic/tclPosixStr.c (Tcl_ErrnoId, Tcl_ErrnoMsg): When using
- egcs, ENOTSUP and EOPNOTSUPP are the same, so now we handle that
- case. [Bug: 1137]
+ * generic/tclPosixStr.c (Tcl_ErrnoId, Tcl_ErrnoMsg): When using egcs,
+ ENOTSUP and EOPNOTSUPP are the same, so now we handle that case. [Bug
+ 1137]
* library/init.tcl: Various small changes requested by Jan Nijtmans.
- - If the variable $tcl_library contains the empty string, this
- empty string will be put in $auto_path. This is not useful at all,
- it only slows down later package processing.
- - If the variable tcl_pkgPath is not set, the "unset __dir"
- fails. Thich makes init.tcl totally unusable. Better put a "catch"
- around it.
- - In the function tcl_findLibraries, the "string match" function
- only works correctly if $tcl_patchLevel is in one of the forms
- "?.?a?", "?.?b?" or "?.?.?". Could a "regexp" be used instead,
- then it allows anything to be appended to the patchLevel
- string. And it is more efficient.
- - The tclPkgSetup function assumes that if $type != "load" then
- the type must be "source". This needn't be true. Some users want
- to add their own setup types.
- [RFE: 1138] [Bug: 978]
-
- * win/tclWinReg.c:
+ - If the variable $tcl_library contains the empty string, this empty
+ string will be put in $auto_path. This is not useful at all, it only
+ slows down later package processing.
+ - If the variable tcl_pkgPath is not set, the "unset __dir" fails.
+ Thich makes init.tcl totally unusable. Better put a "catch" around
+ it.
+ - In the function tcl_findLibraries, the "string match" function only
+ works correctly if $tcl_patchLevel is in one of the forms "?.?a?",
+ "?.?b?" or "?.?.?". Could a "regexp" be used instead, then it allows
+ anything to be appended to the patchLevel string. And it is more
+ efficient.
+ - The tclPkgSetup function assumes that if $type != "load" then the
+ type must be "source". This needn't be true. Some users want to add
+ their own setup types.
+ [RFE 1138] [Bug 978]
+
+ * win/tclWinReg.c:
* doc/registry.n: Added support for HKEY_PERFORMANCE_DATA and
- HKEY_DYN_DATA keys. [Bug: 1109]
+ HKEY_DYN_DATA keys. [Bug 1109]
- * win/tclWinInit.c (TclPlatformInit): Added code to ensure
- tcl_pkgPath is set to "" when no registry entry is found. [Bug: 978]
+ * win/tclWinInit.c (TclPlatformInit): Added code to ensure tcl_pkgPath
+ is set to "" when no registry entry is found. [Bug 978]
-1999-02-01 <stanton@GASPODE>
+1999-02-01 Scott Stanton <stanton@GASPODE>
* generic/tclBasic.c:
* generic/tclCmdAH.c:
@@ -2464,208 +2405,204 @@
* generic/tclProc.c:
* generic/tclTest.c:
* generic/tclTimer.c:
- * generic/tcl.h: Made eval interfaces compatible with 8.0 by
- renaming Tcl_EvalObj to Tcl_EvalObjEx, renaming Tcl_Eval2 to
- Tcl_EvalEx and restoring Tcl_EvalObj and Tcl_GlobalEvalObj
- interfaces so they match Tcl 8.0.
+ * generic/tcl.h: Made eval interfaces compatible with 8.0 by renaming
+ Tcl_EvalObj to Tcl_EvalObjEx, renaming Tcl_Eval2 to Tcl_EvalEx and
+ restoring Tcl_EvalObj and Tcl_GlobalEvalObj interfaces so they match
+ Tcl 8.0.
-1999-01-28 <stanton@GASPODE>
+1999-01-28 Scott Stanton <stanton@GASPODE>
* Merged Tcl 8.0.5b1 changes.
-
+
* generic/tclUtil.c (Tcl_DStringSetLength): Changed so the buffer
- overallocates in a manner similar to Tcl_DStringAppend. This
- should improve performance for TclUniCharToUtfDString.
+ overallocates in a manner similar to Tcl_DStringAppend. This should
+ improve performance for TclUniCharToUtfDString.
1998-12-11 === Tcl 8.1b1 Release ===
-
-1998-12-10 <stanton@GASPODE>
+
+1998-12-10 Scott Stanton <stanton@GASPODE>
* Fixed lots of files that used TCL_THREAD instead of TCL_THREADS.
-
+
* generic/tclEncoding.c (Tcl_FreeEncoding): Moved most of the code
into a static FreeEncoding routine that does not grab the
- encodingMutex to avoid deadlocks/races when called from other
- routines that already have the mutex.
+ encodingMutex to avoid deadlocks/races when called from other routines
+ that already have the mutex.
-1998-12-09 <stanton@GASPODE>
+1998-12-09 Scott Stanton <stanton@GASPODE>
- * library/msgcat1.0/msgcat.tcl: Fixed bad export list, fixed so
- all locale strings are converted to lower case, including file
- names.
+ * library/msgcat1.0/msgcat.tcl: Fixed bad export list, fixed so all
+ locale strings are converted to lower case, including file names.
- * generic/regcomp.c (makescan): Fixed bug in longest match case
- that caused anchored patterns to fail. [Bug: 897]
+ * generic/regcomp.c (makescan): Fixed bug in longest match case that
+ caused anchored patterns to fail. [Bug 897]
-1998-12-08 <stanton@GASPODE>
+1998-12-08 Scott Stanton <stanton@GASPODE>
- * library/msgcat1.0/msgcat.tcl: changed mc to invoke mcunknown in
- the calling context, changed locale lookups to be case insensitive
+ * library/msgcat1.0/msgcat.tcl: changed mc to invoke mcunknown in the
+ calling context, changed locale lookups to be case insensitive
-1998-12-07 <stanton@GASPODE>
+1998-12-07 Scott Stanton <stanton@GASPODE>
* generic/tclAlloc.c (TclpRealloc): Fixed a memory allocation bug
- where big blocks that were reallocated into a different heap
- location were not being placed into the bigBlocks list. [Bug: 933]
+ where big blocks that were reallocated into a different heap location
+ were not being placed into the bigBlocks list. [Bug 933]
* tests/msgcat.test: Added message catalog test suite.
* library/msgcat1.0/msgcat.tcl: minor bug fixes, integrated latest
changes from Mark Harrison.
-1998-12-04 <stanton@GASPODE>
+1998-12-04 Scott Stanton <stanton@GASPODE>
- * library/msgcat1.0/msgcat.tcl: Changed code to conform to Tcl
- coding standards. Changed to use file join for portability.
+ * library/msgcat1.0/msgcat.tcl: Changed code to conform to Tcl coding
+ standards. Changed to use file join for portability.
* library/msgcat1.0: Added initial implementaion of Tcl message
catalog package contributed by Mark Harrison.
-1998-12-03 <stanton@GASPODE>
+1998-12-03 Scott Stanton <stanton@GASPODE>
- * win/tclWinPipe.c (BuildCommandLine): Fixed bug that kept
- arguments containing spaces from being properly quoted.
+ * win/tclWinPipe.c (BuildCommandLine): Fixed bug that kept arguments
+ containing spaces from being properly quoted.
* tests/defs: Changed so auto_path is set to only contain the Tcl
- library directory. This keeps the tests from accidentally picking
- up stuff in installed packages.
+ library directory. This keeps the tests from accidentally picking up
+ stuff in installed packages.
- * generic/tclUtil.c (Tcl_StringMatch): Changed to match 8.0
- behavior in corner case where there is no closing bracket.
+ * generic/tclUtil.c (Tcl_StringMatch): Changed to match 8.0 behavior
+ in corner case where there is no closing bracket.
-1998-12-02 <stanton@GASPODE>
+1998-12-02 Scott Stanton <stanton@GASPODE>
- * win/tclWinPipe.c (TclpCreateCommandChannel): Changed
- reader/writer threads to have THREAD_PRIORITY_HIGHEST so they will
- have a chance to run whenever there is something to do.
+ * win/tclWinPipe.c (TclpCreateCommandChannel): Changed reader/writer
+ threads to have THREAD_PRIORITY_HIGHEST so they will have a chance to
+ run whenever there is something to do.
* generic/tclIO.c (WriteBytes, WriteChars): Fixed so extraneous
flushes do not happen in line mode.
- (TranslateOutputEOL): Made translation more efficient in line mode
- and fixed a buffer overflow bug in CRLF translation. [Bug: 887]
+ (TranslateOutputEOL): Made translation more efficient in line mode and
+ fixed a buffer overflow bug in CRLF translation. [Bug 887]
-1998-12-02 <welch@SAGE>
+1998-12-02 Brent Welch <welch@SAGE>
* Updated patchlevel to 8.1b1
-1998-12-02 <stanton@GASPODE>
+1998-12-02 Scott Stanton <stanton@GASPODE>
- * generic/regc_color.c (subcolor): Added check for error case to
- avoid an out of bounds array reference.
+ * generic/regc_color.c (subcolor): Added check for error case to avoid
+ an out of bounds array reference.
* generic/tclCmdAH.c (Tcl_EncodingObjCmd): Changed to avoid using
Tcl_DStringResult because it is not binary clean.
- * generic/tclParse.c (Tcl_ParseCommand): Fixed bug in comment
- parsing where a trailing comment looked like an incomplete
- command.
+ * generic/tclParse.c (Tcl_ParseCommand): Fixed bug in comment parsing
+ where a trailing comment looked like an incomplete command.
-1998-12-02 <welch@SAGE>
+1998-12-02 Brent Welch <welch@SAGE>
* Merged changes from 8.0.4, especially the new pkg_mkIndex
-1998-12-01 <stanton@GASPODE>
+1998-12-01 Scott Stanton <stanton@GASPODE>
- * generic/tclIO.c (Tcl_ReadChars): Added a call to UpdateInterest
- so we don't block when there is data sitting in the buffers.
+ * generic/tclIO.c (Tcl_ReadChars): Added a call to UpdateInterest so
+ we don't block when there is data sitting in the buffers.
- * generic/tclTest.c (TestevalobjvObjCmd): Updated for EvalObjv
- change.
+ * generic/tclTest.c (TestevalobjvObjCmd): Updated for EvalObjv change.
* tests/parse.test: Updated tests for EvalObjv change.
- * generic/tclParse.c (EvalObjv, Tcl_EvalObjv): Changed
- Tcl_EvalObjv interface to remove string and length arguments,
- preserved original interface as EvalObjv for internal use.
+ * generic/tclParse.c (EvalObjv, Tcl_EvalObjv): Changed Tcl_EvalObjv
+ interface to remove string and length arguments, preserved original
+ interface as EvalObjv for internal use.
- * generic/tcl.h: Changed Tcl_EvalObjv interface to remove string
- and length arguments.
+ * generic/tcl.h: Changed Tcl_EvalObjv interface to remove string and
+ length arguments.
- * doc/Eval.3: Updated documentation for Tcl_EvalObjv to remove
- string and length arguments.
+ * doc/Eval.3: Updated documentation for Tcl_EvalObjv to remove string
+ and length arguments.
* generic/tclCompCmds.c (TclCompileForeachCmd): Fixed code that
corrupted the exceptDepth value in the compile environment when
- foreach failed to compile inline. [Bug: 884]
+ foreach failed to compile inline. [Bug 884]
- * library/encoding/euc-kr.enc:
- * library/encoding/ksc5601.enc:
- * tools/encoding/ksc5601.txt:
- * unix/tclUnixInit.c: Added support for Korean EUC.
+ * library/encoding/euc-kr.enc:
+ * library/encoding/ksc5601.enc:
+ * tools/encoding/ksc5601.txt:
+ * unix/tclUnixInit.c: Added support for Korean EUC.
* win/tclWinChan.c (TclpGetDefaultStdChannel): added check for a
failure during Tcl_MakeFileChannel.
-1998-11-30 <stanton@GASPODE>
+1998-11-30 Scott Stanton <stanton@GASPODE>
- * unix/tclUnixNotfy.c (Tcl_WaitForEvent): Fixed hang that occurs
- when trying to close a pipe that is currently being waited on by
- the notifier thread. [Bug: 607]
+ * unix/tclUnixNotfy.c (Tcl_WaitForEvent): Fixed hang that occurs when
+ trying to close a pipe that is currently being waited on by the
+ notifier thread. [Bug 607]
* unix/tclUnixFCmd.c (GetPermissionsAttribute): Increase size of
- returnString buffer to avoid overflow. [Bug: 584]
+ returnString buffer to avoid overflow. [Bug 584]
- * generic/tclThreadTest.c (TclThreadSend): Fixed memory leak due
- to use of TCL_VOLATILE instead of TCL_DYNAMIC.
+ * generic/tclThreadTest.c (TclThreadSend): Fixed memory leak due to
+ use of TCL_VOLATILE instead of TCL_DYNAMIC.
* generic/tclThread.c (TclRememberSyncObject): Fixed memory leak
caused by failure to reuse condition variables.
- * unix/tclUnixNotfy.c: (Tcl_AlertNotifier, Tcl_WaitForEvent,
- NotifierThreadProc, Tcl_InitNotifier): Fixed race condition caused
- by incorrect use of condition variables when sending messages
- between threads.. [Bug: 607]
+ * unix/tclUnixNotfy.c (Tcl_AlertNotifier, Tcl_WaitForEvent,
+ (NotifierThreadProc, Tcl_InitNotifier): Fixed race condition caused by
+ incorrect use of condition variables when sending messages between
+ threads. [Bug 607]
* generic/tclTestObj.c (TeststringobjCmd): MAX_STRINGS was off by one
so the strings array was too small.
* generic/tclCkalloc.c (Tcl_DbCkfree): Moved mutex lock so
- ValidateMemory is done inside the mutex to avoid a race condition
- when validate_memory is enabled. [Bug: 880]
+ ValidateMemory is done inside the mutex to avoid a race condition when
+ validate_memory is enabled. [Bug 880]
-1998-11-23 <stanton@GASPODE>
+1998-11-23 Scott Stanton <stanton@GASPODE>
* regexec.c: more performance tuning from Henry Spencer.
-1998-11-17 <stanton@GASPODE>
+1998-11-17 Scott Stanton <stanton@GASPODE>
- * tclScan.c: moved "scan" implementation out of tclCmdMZ.c and
- added Unicode support. This required a complete reimplementation
- of the command to avoid using scanf(), which isn't Unicode aware.
- Two new features were added in the process: %n to return the
- current number of characters consumed, and XPG3-style %n$ argument
- order specifiers similar to those provided by the "format"
- command. [Bug: 833]
+ * tclScan.c: moved "scan" implementation out of tclCmdMZ.c and added
+ Unicode support. This required a complete reimplementation of the
+ command to avoid using scanf(), which isn't Unicode aware. Two new
+ features were added in the process: %n to return the current number of
+ characters consumed, and XPG3-style %n$ argument order specifiers
+ similar to those provided by the "format" command. [Bug 833]
- * tclAlloc.c: changed so allocated memory is always 8-byte aligned
- to improve memory performance and to ensure that it will work on
- systems that don't like accessing 4-byte aligned values
- (e.g. Solaris and HP-UX). [Bug: 834]
+ * tclAlloc.c: changed so allocated memory is always 8-byte aligned to
+ improve memory performance and to ensure that it will work on systems
+ that don't like accessing 4-byte aligned values (e.g. Solaris and
+ HP-UX). [Bug 834]
-1998-11-06 <stanton@GASPODE>
+1998-11-06 Scott Stanton <stanton@GASPODE>
- * tclVar.c (TclGetIndexedScalar): Fixed bug 796, var name was
- getting lost before being passed to CallTraces.
+ * tclVar.c (TclGetIndexedScalar): Fixed bug 796, var name was getting
+ lost before being passed to CallTraces.
-1998-10-21 <stanton@GASPODE>
+1998-10-21 Scott Stanton <stanton@GASPODE>
* added "encoding" command
-
+
* Moved internal regexp declarations from tclInt.h to tclRegexp.h
* integrated regexp updates from Henry Spencer
-1998-10-15 <stanton@GASPODE>
+1998-10-15 Scott Stanton <stanton@GASPODE>
* tclUtf.c: added Unicode character table support
* tclInt.h: added TclUniCharIsWordChar
- * tclCmdMZ.c (Tcl_StringObjCmd): added "totitle" subcommand,
- changed "wordend" and "wordstart" to properly handle Unicode word
- characters and connector punctuation
+ * tclCmdMZ.c (Tcl_StringObjCmd): added "totitle" subcommand, changed
+ "wordend" and "wordstart" to properly handle Unicode word characters
+ and connector punctuation
-1998-10-05 <stanton@GASPODE>
+1998-10-05 Scott Stanton <stanton@GASPODE>
* auto.tcl, package.tcl: fixed SCCS strings
@@ -2682,17 +2619,16 @@
* tclExecute.c: fixed off-by-one copying error, fixed merge bugs
- * tclEvent.c: changed so USE_TCLALLOC is tested for value instead
- of definition
+ * tclEvent.c: changed so USE_TCLALLOC is tested for value instead of
+ definition
* tclCompCmds.c: replaced SCCS strings, added warnings around code
that modifies strings in place
* interp.test: added test for interp deleting itself
-1998-09-30 <stanton@GASPODE>
+1998-09-30 Scott Stanton <stanton@GASPODE>
* makefile.vc: fixed so TCL_LIBRARY is set before running tcltest
* tclWin32Dll.c: removed TclpFinalize, cleanup of merges
-
diff --git a/ChangeLog.2000 b/ChangeLog.2000
index 70d491f..2ebdd23 100644
--- a/ChangeLog.2000
+++ b/ChangeLog.2000
@@ -1,12 +1,11 @@
2000-12-14 Don Porter <dgp@users.sourceforge.net>
* generic/tclExecute.c:
- * tests/expr-old.test: Re-wrote Tcl's [expr rand()] and
- [expr srand($seed)] implementations, fixing a range error
- on some 64-bit platforms. Added tests that detect the bug.
- The rewrite changes the seed -> sequence map on 64-bit
- platforms, only for seed >= 2^31, a slight incompatibility.
- [Bug 121072, Patch 102781]
+ * tests/expr-old.test: Re-wrote Tcl's [expr rand()] and [expr
+ srand($seed)] implementations, fixing a range error on some 64-bit
+ platforms. Added tests that detect the bug. The rewrite changes the
+ seed -> sequence map on 64-bit platforms, only for seed >= 2^31, a
+ slight incompatibility. [Bug 121072, Patch 102781]
2000-12-10 Don Porter <dgp@users.sourceforge.net>
@@ -14,217 +13,209 @@
* library/msgcat/msgcat.tcl:
* library/msgcat/pkgIndex.tcl:
* library/opt/optparse.tcl:
- * library/opt/pkgIndex.tcl: Where [uplevel] is used in a proc
- to evaluate a Tcl built-in command in the caller's context,
- the built-in commands are now fully namespace-qualified. This
- prevents problems when the caller context is in a namespace where
- the built-in command name has been used by a command in the
- namespace. (For example, [::ns::set] might be called instead
- of the intended [::set]). [Bug #119422, Patch #102545]
+ * library/opt/pkgIndex.tcl: Where [uplevel] is used in a proc to
+ evaluate a Tcl built-in command in the caller's context, the built-in
+ commands are now fully namespace-qualified. This prevents problems
+ when the caller context is in a namespace where the built-in command
+ name has been used by a command in the namespace. (For example,
+ [::ns::set] might be called instead of the intended [::set]). [Bug
+ 119422, Patch 102545]
-2000-12-09 jeff hobbs <jhobbs@interwoven.com>
+2000-12-09 Jeff Hobbs <jhobbs@interwoven.com>
* win/tclWinTime.c (CalibrationThread): added lint return value to
- prevent compiler warning. [Bug #125005]
+ prevent compiler warning. [Bug 125005]
* docs/scan.n:
* tests/scan.test:
- * generic/tclScan.c (Tcl_ScanObjCmd): changed %o and %x to use
- strtoul instead of strtol to correctly preserve scan<>format
- conversion of large integers. [Patch #102663, Bug #124600]
+ * generic/tclScan.c (Tcl_ScanObjCmd): changed %o and %x to use strtoul
+ instead of strtol to correctly preserve scan<>format conversion of
+ large integers. [Patch 102663, Bug 124600]
* generic/tclExecute.c (TclExecuteByteCode): Commited patch fixing
- handling of {!<boolean>} in expressions. [Patch #102702]
+ handling of {!<boolean>} in expressions. [Patch 102702]
-2000-12-08 jeff hobbs <jhobbs@interwoven.com>
+2000-12-08 Jeff Hobbs <jhobbs@interwoven.com>
- * library/init.tcl: Added support for PATHEXT variable in
- auto_execok, recognizing the proper set of executable extensions
- on Windows. [Patch #102719]
+ * library/init.tcl: Added support for PATHEXT variable in auto_execok,
+ recognizing the proper set of executable extensions on Windows. [Patch
+ 102719]
2000-12-08 Andreas Kupries <a.kupries@westend.com>
- * generic/tclEncoding.c (LoadTableEncoding): Changed dangerous
- code to something less critical. This fixes bug 119417, part A
- without affecting the speed when loading encodings.
+ * generic/tclEncoding.c (LoadTableEncoding): Changed dangerous code to
+ something less critical. This fixes [Bug 119417], part A without
+ affecting the speed when loading encodings.
2000-12-08 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * doc/open.n: Added xref to fconfigure and advice on the opening
- of binary files. Should help prevent a recurrence of bugs like
- #124558
+ * doc/open.n: Added xref to fconfigure and advice on the opening of
+ binary files. Should help prevent a recurrence of bugs like [Bug
+ 124558]
-2000-12-07 jeff hobbs <jhobbs@interwoven.com>
+2000-12-07 Jeff Hobbs <jhobbs@interwoven.com>
* generic/tcl.h: added note about need to updated
library/dde/pkgIndex.tcl with minor version increment.
- * library/dde/pkgIndex.tcl: updated to use 84 version to reflect
- the makefile. Should probably be updated to use its real version
- at some point. [Patch #102560, Bug #119421]
+ * library/dde/pkgIndex.tcl: updated to use 84 version to reflect the
+ makefile. Should probably be updated to use its real version at some
+ point. [Patch 102560, Bug 119421]
-2000-12-06 eric melski <ericm@ajubasolutions.com>
+2000-12-06 Eric Melski <ericm@ajubasolutions.com>
* generic/tcl.h (attemptckalloc): Fixed typo for #define of
- attemptckalloc (was defined to Tcl_AttempDbCkalloc, should have
- been Tcl_AttemptDbCkalloc). [Bug: 124384]
+ attemptckalloc (was defined to Tcl_AttempDbCkalloc, should have been
+ Tcl_AttemptDbCkalloc). [Bug 124384]
- * generic/tclCkalloc.c: Added
- TCL_MEM_DEBUG versions of Tcl_AttemptDbCkrealloc and
- Tcl_AttemptDbCkalloc. [Bug: 124384].
+ * generic/tclCkalloc.c: Added TCL_MEM_DEBUG versions of
+ Tcl_AttemptDbCkrealloc and Tcl_AttemptDbCkalloc. [Bug 124384].
2000-11-24 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * generic/tclExecute.c (TclExecuteByteCode): Logical negation "!"
- can now handle string booleans, provided those values are placed
- in variables.
+ * generic/tclExecute.c (TclExecuteByteCode): Logical negation "!" can
+ now handle string booleans, provided those values are placed in
+ variables.
- * tests/expr.test (expr-13.17): Check that [expr {!$var}] can
- negate the string-versions of booleans "yes", "false", etc.
+ * tests/expr.test (expr-13.17): Check that [expr {!$var}] can negate
+ the string-versions of booleans "yes", "false", etc.
* library/tcltest/tcltest.tcl (getMatchingFiles,
- getMatchingDirectories):
- * tools/man2html.tcl (doDir):
- * tools/man2help.tcl (doDir):
- * library/package.tcl (tclPkgUnknown,tclMacPkgSearch):
+ (getMatchingDirectories):
+ * tools/man2html.tcl (doDir):
+ * tools/man2help.tcl (doDir):
+ * library/package.tcl (tclPkgUnknown,tclMacPkgSearch):
* library/safe.tcl (AddSubDirs): [glob] uses -directory instead of
- unsafe [file join] to fix Bug #123313
+ unsafe [file join]. [Bug 123313]
* generic/tclIndexObj.c:
* generic/tclTestObj.c (TestindexobjCmd): Changed internal
- representation of index objects to fix Bug #119082; fix
- shouldn't be visible to outside world...
+ representation of index objects to fix [Bug 119082]; fix shouldn't be
+ visible to outside world...
- * generic/tclTest.c (TestGetIndexFromObjStructObjCmd):
- * tests/indexObj.test: (indexObj-6.*) Added to test for presence
- of Bug #119082.
+ * generic/tclTest.c (TestGetIndexFromObjStructObjCmd):
+ * tests/indexObj.test: (indexObj-6.*) Added to test for presence of
+ [Bug 119082].
2000-11-23 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * generic/tclCmdIL.c (Tcl_LsortObjCmd): Fixed memory leak from Bug
- #119398
+ * generic/tclCmdIL.c (Tcl_LsortObjCmd): Fixed memory leak from [Bug
+ 119398]
* library/init.tcl (unknown): Added specific level parameters to
- all uplevel invokations to boost performance; didn't dare touch
- the "namespace inscope" stuff though, since it looks sensitive
- to me! Should fix Bug #123217, though testing is tricky...
+ all uplevel invokations to boost performance; didn't dare touch
+ the "namespace inscope" stuff though, since it looks sensitive
+ to me! Should fix [Bug 123217], though testing is tricky...
2000-11-21 Andreas Kupries <a.kupries@westend.com>
- * All of the changes below are described in TIP #7 ~ Specification
- and result from the application of the patch contained
- therein. Creator of the patch is Kevin Kenny
- <kennykb@crd.ge.com>. The patch used here is actually a bit
- different. Two MS specific constant values (format FOOui64) were
- replaced with a more portable formatting of the values and an
- additional cast to LONGLONG. My cross-compiling gcc was unable to
- process the original form. The SF Id of the patch is 102459.
-
- * tclWinTime.c: Add to the static data a set of variables that
- manage the phase-locked techniques, including a
- ''CRITICAL_SECTION'' to guard them so that multi-threaded code
- is stable.
-
- * tclWinTime.c: Modify ''TclpGetSeconds'' to call ''TclpGetTime''
- and return the 'seconds' portion of the result. This change is
- necessary to make sure that the two times are consistent near
- the rollover from one second to another.
+ All of the changes below are described in TIP #7 ~ Specification and
+ result from the application of the patch contained therein. Creator of
+ the patch is Kevin Kenny <kennykb@crd.ge.com>. The patch used here is
+ actually a bit different. Two MS specific constant values (format
+ FOOui64) were replaced with a more portable formatting of the values
+ and an additional cast to LONGLONG. My cross-compiling gcc was unable
+ to process the original form. [Patch 102459]
+
+ * tclWinTime.c: Add to the static data a set of variables that manage
+ the phase-locked techniques, including a ''CRITICAL_SECTION'' to guard
+ them so that multi-threaded code is stable.
+
+ * tclWinTime.c: Modify ''TclpGetSeconds'' to call ''TclpGetTime'' and
+ return the 'seconds' portion of the result. This change is necessary
+ to make sure that the two times are consistent near the rollover from
+ one second to another.
* tclWinTime.c: Modify ''TclpGetClicks'' to use TclpGetTime to
- determine the click count as a number of microseconds.
-
- * tclWinTime.c: Modify ''TclpGetTime'' to return the time as
- M*Q+B, where Q is the result of ''QueryPerformanceCounter'', and
- M and B are variables maintained by the phase-locked loop to
- keep the result as close as possible to the system clock. The
- ''TclpGetTime'' call will also launch the phase-lock management
- in a separate thread the first time that it is invoked. If the
- performance counter is unavailable, or if its frequency is not
- one of the two common 8254-compatible rates, then
- ''TclpGetTime'' will return the result of ''ftime'' as it does
- in Tcl 8.3.2.
-
- * tclWinTime.c: Add the clock calibration procedure. The
- calibration is somewhat complex; to save space, the reader is
- referred to the reference implementation for the details of how
- the time base and frequency are maintained.
-
- * tclWinNotify.c: Modify ''Tcl_Sleep'' to test that the process
- has, in fact, slept for the requisite time by calling
- ''TclpGetTime'' and comparing with the desired time. Otherwise,
- roundoff errors may cause the process to awaken early.
-
- * tclWinTest.c: Add a ''testwinclock'' command. This command
- returns a four element list comprising the seconds and
- microseconds portions of the system clock and the seconds and
- microseconds portions of the Tcl clock.
-
- * winTime.test: Add to the test suite a test that makes sure that
- the Tcl clock stays within 1.1 ms of the system clock over the
- duration of the test.
+ determine the click count as a number of microseconds.
+
+ * tclWinTime.c: Modify ''TclpGetTime'' to return the time as M*Q+B,
+ where Q is the result of ''QueryPerformanceCounter'', and M and B are
+ variables maintained by the phase-locked loop to keep the result as
+ close as possible to the system clock. The ''TclpGetTime'' call will
+ also launch the phase-lock management in a separate thread the first
+ time that it is invoked. If the performance counter is unavailable, or
+ if its frequency is not one of the two common 8254-compatible rates,
+ then ''TclpGetTime'' will return the result of ''ftime'' as it does in
+ Tcl 8.3.2.
+
+ * tclWinTime.c: Add the clock calibration procedure. The calibration
+ is somewhat complex; to save space, the reader is referred to the
+ reference implementation for the details of how the time base and
+ frequency are maintained.
+
+ * tclWinNotify.c: Modify ''Tcl_Sleep'' to test that the process has,
+ in fact, slept for the requisite time by calling ''TclpGetTime'' and
+ comparing with the desired time. Otherwise, roundoff errors may cause
+ the process to awaken early.
+
+ * tclWinTest.c: Add a ''testwinclock'' command. This command returns a
+ four element list comprising the seconds and microseconds portions of
+ the system clock and the seconds and microseconds portions of the Tcl
+ clock.
+
+ * winTime.test: Add to the test suite a test that makes sure that the
+ Tcl clock stays within 1.1 ms of the system clock over the duration of
+ the test.
2000-11-21 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * doc/global.n:
- * doc/upvar.n:
- * doc/variable.n: Improved documentation to mention that variables
- so created are listed in [info locals] and added a few more
- cross-links between these commands. Fixes bug #119387
+ * doc/global.n:
+ * doc/upvar.n:
+ * doc/variable.n: Improved documentation to mention that variables so
+ created are listed in [info locals] and added a few more cross-links
+ between these commands. [Bug 119387]
2000-11-17 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* tests/safe.test: (safe-4.3):
- * generic/tclVar.c (TclLookupVar): Changed again. Now passes all
- the tests, though one needed modifying since it required the
- wrong answer. (Why on earth do we have inline modification of
- argument strings? This sort of thing is horrendous to debug and
- doesn't work well in a multithreaded environment!) Fixes bug
- 119192.
+ * generic/tclVar.c (TclLookupVar): Changed again. Now passes all the
+ tests, though one needed modifying since it required the wrong answer.
+ (Why on earth do we have inline modification of argument strings? This
+ sort of thing is horrendous to debug and doesn't work well in a
+ multithreaded environment!) [Bug 119192]
- * tests/var.test: (var-1.19) If my attempts to fix the problem
- aren't right yet, my attempts to describe it look pretty good to
- me...
+ * tests/var.test: (var-1.19) If my attempts to fix the problem aren't
+ right yet, my attempts to describe it look pretty good to me...
2000-11-16 Andreas Kupries <a.kupries@westend.com>
* win/tclWinPort.h (line 69): Changed reference to winsock2.h into
- winsock.h. This was a leftover from a foray into using winsock
- version 2 (History lesson from Scott Redman and Jeff
- Hobbs). This code was no problem when compiling Tcl itself, but
- could trip extensions. Fixes bug 122568.
+ winsock.h. This was a leftover from a foray into using winsock version
+ 2 (History lesson from Scott Redman and Jeff Hobbs). This code was no
+ problem when compiling Tcl itself, but could trip extensions. [Bug
+ 122568]
-2000-11-15 jeff hobbs <jeff.hobbs@acm.org>
+2000-11-15 Jeff Hobbs <jeff.hobbs@acm.org>
- * unix/Makefile.in: removed bp.c references (hasn't existed in a
- long time). Corrected 'make dist' to make dist with unversioned
- library directories (same as out of cvs), so make install works
- correctly with either source tree.
+ * unix/Makefile.in: removed bp.c references (hasn't existed in a long
+ time). Corrected 'make dist' to make dist with unversioned library
+ directories (same as out of cvs), so make install works correctly with
+ either source tree.
-2000-11-15 jeff hobbs <jeff.hobbs@acm.org>
+2000-11-15 Jeff Hobbs <jeff.hobbs@acm.org>
- * generic/tclVar.c (TclLookupVar): reverted fix below as it broke
- all other array unset error reporting. Bug-119192 is still
- open.
+ * generic/tclVar.c (TclLookupVar): reverted fix below as it broke all
+ other array unset error reporting. Bug 119192 is still open.
2000-11-15 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * generic/tclVar.c (TclLookupVar): Changed references to part2 to
- use elName instead in various error message generating spots, so
- as to fix Bug-119192.
+ * generic/tclVar.c (TclLookupVar): Changed references to part2 to use
+ elName instead in various error message generating spots. [Bug 119192]
2000-11-03 David Gravereaux <davygrvy@ajubasolutions.com>
- * win/.cvsignore: Removed 'configure' from the glob list now
- that it's included.
+ * win/.cvsignore: Removed 'configure' from the glob list now that it's
+ included.
2000-11-03 Jeff Hobbs <hobbs@ajubasolutions.com>
8.4a2 RELEASE
- * unix/Makefile.in (install-libraries, dist):
+ * unix/Makefile.in (install-libraries, dist):
* win/makefile.vc (install-libraries):
- * win/Makefile.in (install-libraries): updated to install
- unversioned library directories into versioned directories.
+ * win/Makefile.in (install-libraries): updated to install unversioned
+ library directories into versioned directories.
* tools/tcl.wse.in: updated for unversioning of library dirs
@@ -234,31 +225,31 @@
* generic/tclStubInit.c:
* generic/tclDecls.h:
- * generic/tcl.decls: added Tcl_SetMainLoop proc that allows people
- to set a main loop that will run for tclsh.
+ * generic/tcl.decls: added Tcl_SetMainLoop proc that allows people to
+ set a main loop that will run for tclsh.
* generic/tcl.h: added Tcl_MainLoopProc typedef
* generic/tclMain.c (Tcl_SetMainLoop, StdinProc, Prompt): new
- StdinProc and Prompt static procs and Tcl_SetMainLoop stubs proc.
- The first two handle a fileevent based prompt (taken from
- tkMain.c). Tcl_SetMainLoop enables the interactive setting of a
- main loop procedure. This enables Tk to be a loadable package.
+ StdinProc and Prompt static procs and Tcl_SetMainLoop stubs proc. The
+ first two handle a fileevent based prompt (taken from tkMain.c).
+ Tcl_SetMainLoop enables the interactive setting of a main loop
+ procedure. This enables Tk to be a loadable package.
2000-11-02 David Gravereaux <davygrvy@ajubasolutions.com>
- * generic/tclEvent.c: tclLibraryPath Tcl_Obj didn't have a way
- to share its data among threads. This caused Tcl_Init() to
- always fail in threads. Added a way to pass the data around
- with a global char*. [BUG: 5301]
+ * generic/tclEvent.c: tclLibraryPath Tcl_Obj didn't have a way to
+ share its data among threads. This caused Tcl_Init() to always fail in
+ threads. Added a way to pass the data around with a global char*.
+ [BUG: 5301]
2000-11-02 Jeff Hobbs <hobbs@ajubasolutions.com>
* unix/configure:
* unix/dltest/configure:
* win/configure:
- * tools/configure: checked in configure scripts so people doing
- CVS checkouts aren't required to have autoconf. Changes to
- configure.in in the future will require the corresponding
- configure script to also be re-autoconf'ed and checked in.
+ * tools/configure: checked in configure scripts so people doing CVS
+ checkouts aren't required to have autoconf. Changes to configure.in in
+ the future will require the corresponding configure script to also be
+ re-autoconf'ed and checked in.
* win/makefile.vc:
* win/tcl.m4: makefile fixes for Win64 support
@@ -270,14 +261,14 @@
* unix/tcl.m4: removed use of -lbsd and -ldl for AIX-5.
- * tests/subst.test: added tests for non-zero return code handling
- by subst.
+ * tests/subst.test: added tests for non-zero return code handling by
+ subst.
* generic/tclParse.c (Tcl_EvalEx): corrected handling of non-zero,
- non-error return code cases for subst. [BUG: 119829]
+ non-error return code cases for subst. [Bug 119829]
- * generic/tclVar.c (TclVarTraceExists): Corrected excessive mem
- use when info exists was called on a non-existent array element.
- [BUG: 119213, 119336]
+ * generic/tclVar.c (TclVarTraceExists): Corrected excessive mem use
+ when info exists was called on a non-existent array element. [Bug
+ 119213, 119336]
2000-10-30 David Gravereaux <davygrvy@ajubasolutions.com>
@@ -290,8 +281,8 @@
2000-10-30 Jeff Hobbs <hobbs@ajubasolutions.com>
- * unix/tclUnixInit.c: added default encoding map from
- "ja_JP.eucJP" to "euc-jp". (takahashi)
+ * unix/tclUnixInit.c: added default encoding map from "ja_JP.eucJP" to
+ "euc-jp". (takahashi)
* tests/clock.test: corrected clock-2.* test numbering
@@ -306,68 +297,67 @@
* unix/configure.in:
* unix/tcl.m4: added support for AIX-5.
- * generic/tclIO.c (Tcl_NotifyChannel): removed #ifdef around code
- for old channel structures, placed preserve/release around statePtr
- * generic/tclIO.c (CloseChannel): the statePtr for a channel was
- not being freed when the last channel in a stack was freed,
- causing a mem leak.
+ * generic/tclIO.c (Tcl_NotifyChannel): removed #ifdef around code for
+ old channel structures, placed preserve/release around statePtr
+ * generic/tclIO.c (CloseChannel): the statePtr for a channel was not
+ being freed when the last channel in a stack was freed, causing a mem
+ leak.
* unix/tclUnixChan.c: updated channel types to strict
- TCL_CHANNEL_VERSION_2 style to avoid compiler warnings. They work
+ TCL_CHANNEL_VERSION_2 style to avoid compiler warnings. They work
either way, but this avoids compiler warnings (that worries people).
2000-10-27 Jennifer Hom <jenn@ajubasolutions.com>
- * library/tcltest1.0/tcltest.tcl: Removed a cd into the test
- directory in runAllTests that screwed up the temporary directory
- setting, effectively preventing users from running tests on
- multiple platforms at the same time.
+ * library/tcltest1.0/tcltest.tcl: Removed a cd into the test directory
+ in runAllTests that screwed up the temporary directory setting,
+ effectively preventing users from running tests on multiple platforms
+ at the same time.
2000-10-26 David Gravereaux <davygrvy@ajubasolutions.com>
- * win/tclWinFile.c (TclpMatchFilesTypes): NULL was being set to
- "attr" which was a DWORD. Changed NULL to zero because a 'void *'
- can't be set to a DWORD to avoid the compiler warning.
+ * win/tclWinFile.c (TclpMatchFilesTypes): NULL was being set to "attr"
+ which was a DWORD. Changed NULL to zero because a 'void *' can't be
+ set to a DWORD to avoid the compiler warning.
2000-10-24 Jennifer Hom <jenn@ajubasolutions.com>
* tests/all.tcl: Removed support for tcltest 1.0.
-
+
* tests/tcltest.test:
* library/tcltest1.0/tcltest.tcl:
* library/tcltest1.0/pkgIndex.tcl:
* docs/tcltest.n: Moved tcltest2 code so that it's the standard
- version of tcltest. Removed all tcltest2 files
- (tests/tcltest2.test, library/tcltest1.0/tcltest2.tcl,
- docs/tcltest2.n).
+ version of tcltest. Removed all tcltest2 files (tests/tcltest2.test,
+ library/tcltest1.0/tcltest2.tcl, docs/tcltest2.n).
2000-10-20 Jeff Hobbs <hobbs@ajubasolutions.com>
* win/tclWinFile.c (TclpMatchFilesTypes): made the stat call only
- occur when necessary (for 'glob' command). Significantly speeds
- up glob command from 8.3. [BUG: 6216]
+ occur when necessary (for 'glob' command). Significantly speeds up
+ glob command from 8.3. [BUG: 6216]
2000-10-19 Jennifer Hom <jenn@ajubasolutions.com>
* library/tcltest1.0/tcltest2.tcl:
* tests/tcltest2
- * doc/tcltest2.n: Code and documentation cleanup. Modified
- -verbose to take list of keywords as well as string of letters.
- Removed Tcl version information from tcltest. Removed
- tcltest::grep from tcltest package. Added optional 3rd directory
- argument to makeFile/makeDirectory and removeFile/removeDirectory.
+ * doc/tcltest2.n: Code and documentation cleanup. Modified -verbose to
+ take list of keywords as well as string of letters. Removed Tcl
+ version information from tcltest. Removed tcltest::grep from tcltest
+ package. Added optional 3rd directory argument to
+ makeFile/makeDirectory and removeFile/removeDirectory.
* tests/basic.test: Changed references to tcltest::tclVersion to
hardcoded numbers.
- * generic/tcl.h: Changed reference to tcltest2.tcl and tcltest.tcl
- in comments to tests/basic.test.
+ * generic/tcl.h: Changed reference to tcltest2.tcl and tcltest.tcl in
+ comments to tests/basic.test.
2000-10-06 David Gravereaux <davygrvy@ajubasolutions.com>
- * win/tclWinChan.c: moved Win2K bug case test with GetStdHandle()
- from TclpGetDefaultStdChannel into Tcl_MakeFileChannel to enable
- a more general method in detecting invalid OS handles rather than
- just a specific known case. [BUG: 5971]
+ * win/tclWinChan.c: moved Win2K bug case test with GetStdHandle() from
+ TclpGetDefaultStdChannel into Tcl_MakeFileChannel to enable a more
+ general method in detecting invalid OS handles rather than just a
+ specific known case. [BUG: 5971]
2000-10-06 Jeff Hobbs <hobbs@ajubasolutions.com>
@@ -383,10 +373,10 @@
* library/tcltest1.0/tcltest2.tcl:
* tests/tcltest2.test:
- * doc/tcltest2.n: Modified the new form of the test command to
- accept both attribute-value pairs and command line options.
- Updated the tests and the documentation for this new format.
- Also changed the option names for the test command.
+ * doc/tcltest2.n: Modified the new form of the test command to accept
+ both attribute-value pairs and command line options. Updated the tests
+ and the documentation for this new format. Also changed the option
+ names for the test command.
2000-09-29 Jeff Hobbs <hobbs@scriptics.com>
@@ -394,24 +384,24 @@
space parity on Windows (Eason) [Bug 6057].
* win/Makefile.in: commented use of TESTFLAGS
- * unix/Makefile.in: added TESTFLAGS to test target to
- conform with Windows makefile and TEA style.
+ * unix/Makefile.in: added TESTFLAGS to test target to conform with
+ Windows makefile and TEA style.
* tests/stack.test: prevented possible crash on systems with low
- default stacksize (Tru64, AIX) in infinite recursion test. A
- solution to check remaining stack space in the core is best, but
- hard to do in a cross-platform manner.
+ default stacksize (Tru64, AIX) in infinite recursion test. A solution
+ to check remaining stack space in the core is best, but hard to do in
+ a cross-platform manner.
- * generic/tclIOGT.c (FLUSH_DELAY): renamed DELAY define to
- FLUSH_DELAY to avoid defn conflict using Tru64's cc.
+ * generic/tclIOGT.c (FLUSH_DELAY): renamed DELAY define to FLUSH_DELAY
+ to avoid defn conflict using Tru64's cc.
2000-09-28 Jeff Hobbs <hobbs@ajubasolutions.com>
* tools/tcl.wse.in: added tclPlatDecls.h and tkPlatDecls.h to the
Windows .exe install.
- * tests/fCmd.test (fCmd-6.20): corrected test to remove
- c:/tcl8975@ after creating it.
+ * tests/fCmd.test (fCmd-6.20): corrected test to remove c:/tcl8975@
+ after creating it.
* tests/fileName.test: cleaned up the testing of glob patterns for
c:/globTest (Windows) to directly create/remove directory.
@@ -421,13 +411,13 @@
* generic/tcl.decls:
* generic/tclIO.c: updated Tcl_IsChannelShared,
Tcl_IsChannelRegistered, Tcl_CutChannel, Tcl_SpliceChannel,
- Tcl_IsChannelExisting, and Tcl_ClearChannelHandlers to conform to
- the new stacked channel implementation. Their stub slots were
- also moved to give preference to the new 8.3.2 stub functions.
- This will cause an incompatability with 8.4a1 only.
+ Tcl_IsChannelExisting, and Tcl_ClearChannelHandlers to conform to the
+ new stacked channel implementation. Their stub slots were also moved
+ to give preference to the new 8.3.2 stub functions. This will cause an
+ incompatability with 8.4a1 only.
(StopCopy): fixed a bug introduced by a partial fix in 8.3.2 that
didn't set nonBlocking correctly when resetting the flags for the
- write side. [Bug: 6261]
+ write side. [Bug: 6261]
* doc/ChnlStack.3:
* doc/CrtChannel.3:
@@ -451,7 +441,7 @@
* win/tclWinPipe.c:
* win/tclWinSerial.c:
* win/tclWinSock.c: Up-port of changes made in 8.3.2 to 8.4a2 code
- base. Most of these changes relate to the rewrite of the stacked
+ base. Most of these changes relate to the rewrite of the stacked
channel implementation, with a few config related fixes.
Following is an asynchronous include of the applicable ChangeLog
@@ -467,67 +457,66 @@
* doc/CrtChannel.3: updated the docs to be aware of the
TCL_CHANNEL_VERSION_2 style of Tcl channels.
- * generic/tclIO.c (Tcl_CreateChannel): added assertion to verify
- that the new channel versioning will be binary compatible with
- older channel drivers.
+ * generic/tclIO.c (Tcl_CreateChannel): added assertion to verify that
+ the new channel versioning will be binary compatible with older
+ channel drivers.
2000-08-05 Jeff Hobbs <hobbs@scriptics.com>
- * generic/tclIOGT.c (TclChannelTransform): fixed segfault that
- would occur when transforming a channel with a proc that did not
- yet exist. (Kupries)
+ * generic/tclIOGT.c (TclChannelTransform): fixed segfault that would
+ occur when transforming a channel with a proc that did not yet exist.
+ (Kupries)
* generic/tclTest.c (TestChannelCmd): added some lint init'ing of
statePtr and chan vars.
2000-07-26 Jeff Hobbs <hobbs@scriptics.com>
- * merged core-8-3-1-io-rewrite back into core-8-3-1-branch.
- The core-8-3-1-io-rewrite branch should now be considered defunct.
+ Merged core-8-3-1-io-rewrite back into core-8-3-1-branch. The
+ core-8-3-1-io-rewrite branch should now be considered defunct.
* generic/tclStubInit.c:
* generic/tclDecls.h:
* generic/tcl.decls:
* generic/tcl.h:
- * generic/tclIO.c: moved the Tcl_Channel* macros from tcl.h to
- tclIO.c and made them proper stubbed functions. These are:
- Tcl_ChannelName, Tcl_ChannelVersion, Tcl_ChannelBlockModeProc,
- Tcl_ChannelCloseProc, Tcl_ChannelClose2Proc, Tcl_ChannelInputProc,
- Tcl_ChannelOutputProc, Tcl_ChannelSeekProc, Tcl_ChannelSetOptionProc,
+ * generic/tclIO.c: moved the Tcl_Channel* macros from tcl.h to tclIO.c
+ and made them proper stubbed functions. These are: Tcl_ChannelName,
+ Tcl_ChannelVersion, Tcl_ChannelBlockModeProc, Tcl_ChannelCloseProc,
+ Tcl_ChannelClose2Proc, Tcl_ChannelInputProc, Tcl_ChannelOutputProc,
+ Tcl_ChannelSeekProc, Tcl_ChannelSetOptionProc,
Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc,
- Tcl_ChannelGetHandleProc, Tcl_ChannelFlushProc,
- and Tcl_ChannelHandlerProc. These should be used to access the
+ Tcl_ChannelGetHandleProc, Tcl_ChannelFlushProc, and
+ Tcl_ChannelHandlerProc. These should be used to access the
Tcl_ChannelType structure instead of direct pointer dereferencing.
- * tests/iogt.test: added RCS string, marked tests 2.* to be
- unixOnly due to underlying system differences.
+ * tests/iogt.test: added RCS string, marked tests 2.* to be unixOnly
+ due to underlying system differences.
2000-07-25 Andreas Kupries <a.kupries@westend.com>
* tests/iogt.test: (line 866f) New tests iogt-6.[01], highlighting
- buffering trouble when stacking and unstacking transformations.
- iogt-6.0 is solved, see the changes below. iogt-6.1 remains, for
- now, due to the perceived complexity of solutions.
+ buffering trouble when stacking and unstacking transformations.
+ iogt-6.0 is solved, see the changes below. iogt-6.1 remains, for now,
+ due to the perceived complexity of solutions.
- * generic/tclIO.h: (line 139f) struct Channel, added a buffer
- queue, to hold data pushed back when stacking a transformation.
+ * generic/tclIO.h: (line 139f) struct Channel, added a buffer queue,
+ to hold data pushed back when stacking a transformation.
* generic/tclIO.c:
- (line 91f, line 7434f) New internal function 'CopyBuffer'.
- Derived from 'CopyAndTranslateBuffer', with translation
- removed.
- (line 1025f, line 1212f): Initialization of new queue.
- (line 1164f, Tcl_StackChannel): Pushback of input queue.
- (line 1293f, Tcl_UnstackChannel): Discard input and pushback.
- (line 3748f, Tcl_ReadRaw): Modified to use data in the push back
- area before going to the driver. Uses 'CopyBuffer', s.a.
- (line 4702f, GetInput): Modified to use data in the push back
- area before going to the driver.
- (line 4867f, Tcl_Seek): Modified to take pushback of the topmost
- channel in a stack into account.
- (line 5620f, Tcl_InputBuffered): See above. Added
- 'Tcl_ChannelBuffered'. Analogue to 'Tcl_InputBuffered' but for
- the buffer area in the channel.
+ (line 91f, line 7434f) New internal function 'CopyBuffer'. Derived
+ from 'CopyAndTranslateBuffer', with translation removed.
+ (line 1025f, line 1212f): Initialization of new queue.
+ (line 1164f, Tcl_StackChannel): Pushback of input queue.
+ (line 1293f, Tcl_UnstackChannel): Discard input and pushback.
+ (line 3748f, Tcl_ReadRaw): Modified to use data in the push back area
+ before going to the driver. Uses 'CopyBuffer', s.a.
+ (line 4702f, GetInput): Modified to use data in the push back area
+ before going to the driver.
+ (line 4867f, Tcl_Seek): Modified to take pushback of the topmost
+ channel in a stack into account.
+ (line 5620f, Tcl_InputBuffered): See above. Added
+ 'Tcl_ChannelBuffered'. Analog to 'Tcl_InputBuffered' but for the
+ buffer area in the channel.
* generic/tcl.decls: New public API 'Tcl_ChannelBuffered'. S.a.
@@ -541,21 +530,21 @@
* generic/tclIntDecls.h:
* generic/tclInt.decls: commented out internal decls for
TclTestChannelCmd and TclTestChannelEventCmd as they were moved to
- tclTest.c. Added new decls for TclChannelEventScriptInvoker and
+ tclTest.c. Added new decls for TclChannelEventScriptInvoker and
TclChannelTransform.
* generic/tclIO.c (CloseChannel): stopped masking out of the
- TCL_READABLE|TCL_WRITABLE bits from the state flags in
- CloseChannel, instead adding extra intelligence to
- CheckChannelErrors with a new CHANNEL_RAW_MODE bit for special
- behavior when called from Raw channel APIs.
+ TCL_READABLE|TCL_WRITABLE bits from the state flags in CloseChannel,
+ instead adding extra intelligence to CheckChannelErrors with a new
+ CHANNEL_RAW_MODE bit for special behavior when called from Raw channel
+ APIs.
2000-07-13 Jeff Hobbs <hobbs@scriptics.com>
- * generic/tclIO.c (StackSetBlockMode): moved set of chanPtr
- outside of blockModeProc check to avoid infinite loop when
- blockModeProc was NULL (Kupries). updated TransformSeekProc to
- not call Tcl_Seek directly (Kupries).
+ * generic/tclIO.c (StackSetBlockMode): moved set of chanPtr outside of
+ blockModeProc check to avoid infinite loop when blockModeProc was
+ NULL. Updated TransformSeekProc to not call Tcl_Seek directly
+ (Kupries).
* win/tclWinChan.c: updated fileChannelType to v2 channel struct
* win/tclWinConsole.c: updated consoleChannelType to v2 channel struct
@@ -565,85 +554,82 @@
2000-07-11 Brent Welch <welch@ajubasolutions.com>
- * win/tclConfig.sh.in (TCL_LIBS): Cleaned up unix-specific
- autoconf variables.
+ * win/tclConfig.sh.in (TCL_LIBS): Cleaned up unix-specific autoconf
+ variables.
2000-07-11 Jeff Hobbs <hobbs@scriptics.com>
- * tests/iogt.test: made tests [345].0 not run by default as they
- were failing in the new design, but I'm not convinced that the
- returned result isn't correct.
+ * tests/iogt.test: made tests [345].0 not run by default as they were
+ failing in the new design, but I'm not convinced that the returned
+ result isn't correct.
* generic/tclDecls.h:
* generic/tclStubInit.c:
- * generic/tcl.decls: added Tcl_GetTopChannel C API that returns
- the current top channel of a channel stack. Tcl_GetChannel was
- changed earlier to return the bottommost channel of a stack
- because that is the one that is guaranteed to stay around the
- longest, and this was needed to compensate for certain
- operations that want to look at the state of the main channel.
- Most channel APIs already compensate for grabbing the top, so it
- shouldn't be needed often.
+ * generic/tcl.decls: added Tcl_GetTopChannel C API that returns the
+ current top channel of a channel stack. Tcl_GetChannel was changed
+ earlier to return the bottommost channel of a stack because that is
+ the one that is guaranteed to stay around the longest, and this was
+ needed to compensate for certain operations that want to look at the
+ state of the main channel. Most channel APIs already compensate for
+ grabbing the top, so it shouldn't be needed often.
* generic/tclIO.c (Tcl_StackChannel, Tcl_UnstackChannel): Added
- flushing of buffers (Kupries), removed use of DownChannel macro,
- added Tcl_GetTopChannel public API to get to the top channel of
- the channel stack (necessary for TLS). Rewrote Tcl_NotifyChannel
- for new channel design (Kupries). Did some code cleanup in the
- transform code. tclIO.c must still be broken into bits (separate
- out test code and giot code, create tclIO.h).
+ flushing of buffers (Kupries), removed use of DownChannel macro, added
+ Tcl_GetTopChannel public API to get to the top channel of the channel
+ stack (necessary for TLS). Rewrote Tcl_NotifyChannel for new channel
+ design (Kupries). Did some code cleanup in the transform code.
+ tclIO.c must still be broken into bits (separate out test code and
+ giot code, create tclIO.h).
2000-07-10 Andreas Kupries <a.kupries@westend.com>
* tests/iogt.test: Reverted some earlier changes as a fix by Jeff
- revived the original and correct behaviour. IOW, the tests showed
- a genuine error and I didn't see it :(.
+ revived the original and correct behaviour. IOW, the tests showed a
+ genuine error and I didn't see it :(.
- * generic/tclIO.c (Tcl_Read|Write_Raw): Changed to directly use
- the drivers and not DoRead|DoWrite. The latter use the buffering
- system, encoding and eol-translation and this wreaks havoc with
- the data going through the transformations. Both procedures use
- CheckForchannelErrors and let it believe that there is no
- background copy in progress or else stacked channels could not
- be used for that.
+ * generic/tclIO.c (Tcl_Read|Write_Raw): Changed to directly use the
+ drivers and not DoRead|DoWrite. The latter use the buffering system,
+ encoding and eol-translation and this wreaks havoc with the data going
+ through the transformations. Both procedures use CheckForchannelErrors
+ and let it believe that there is no background copy in progress or
+ else stacked channels could not be used for that.
* generic/tclIO.c (TclCopyChannel, CopyData): Moved access to the
- topmost channel from the first to the second procedure to make
- the decision about that at the last possible time (Callbacks can
- change the stacking).
+ topmost channel from the first to the second procedure to make the
+ decision about that at the last possible time (Callbacks can change
+ the stacking).
test suite: failures of iogt-[345].0
-
+
2000-07-06 Jeff Hobbs <hobbs@scriptics.com>
- * tests/iogt.test: new tests for stacked channel stuff based off
- new 'testchannel transform|unstack' code (Kupries IOGT extension).
+ * tests/iogt.test: new tests for stacked channel stuff based off new
+ 'testchannel transform|unstack' code (Kupries IOGT extension).
* generic/tcl.decls:
* generic/tcl.h:
* generic/tclDecls.h:
* generic/tclStubsInit.c:
- * generic/tclIO.c: complete rewrite of Tcl Channel code for
- stacked channels. Channels are now designed to work in a more
- stacked fashion with a shared ChannelState data structure.
+ * generic/tclIO.c: complete rewrite of Tcl Channel code for stacked
+ channels. Channels are now designed to work in a more stacked fashion
+ with a shared ChannelState data structure.
2000-06-02 Jeff Hobbs <hobbs@scriptics.com>
* generic/tclIO.c (CloseChannel): removed the &ing out of
- (TCL_READABLE|TCL_WRITABLE) from the flags, as CloseChannel does
- this on the next pass through for the top channel, and it appeared
- to be causing hangs by not allowing the final flush.
+ (TCL_READABLE|TCL_WRITABLE) from the flags, as CloseChannel does this
+ on the next pass through for the top channel, and it appeared to be
+ causing hangs by not allowing the final flush.
2000-06-01 Jeff Hobbs <hobbs@scriptics.com>
- * generic/tclIO.c (CloseChannel): Rewrote CloseChannel code to
- unstack a channel during the close process. Fixed a refcount bug
- in Tcl_UnstackChannel. [Bug: 5623]
- (CloseChannel): further extended CloseChannel in the stacked case
- to effect certain operations on the next channel that would have
- been done in Tcl_Close. Also added CHANNEL_CLOSED and removed
- (TCL_READABLE|TCL_WRITABLE) bits from chanPtr->flags. Changed
- final reset of the WatchProc to check the chanDownPtr's (next)
- interestMask.
+ * generic/tclIO.c (CloseChannel): Rewrote CloseChannel code to unstack
+ a channel during the close process. Fixed a refcount bug in
+ Tcl_UnstackChannel. [Bug: 5623]
+ (CloseChannel): further extended CloseChannel in the stacked case to
+ effect certain operations on the next channel that would have been
+ done in Tcl_Close. Also added CHANNEL_CLOSED and removed
+ (TCL_READABLE|TCL_WRITABLE) bits from chanPtr->flags. Changed final
+ reset of the WatchProc to check the chanDownPtr's (next) interestMask.
******************************************************
** END OF ASYNCHRONOUS UP-PORT LOG (8.3.2 -> 8.4a2) **
@@ -651,49 +637,46 @@
2000-09-20 Jeff Hobbs <hobbs@scriptics.com>
- * tests/socket.test: removed doTestsWithRemoteServer constraint
- from socket-12.*. It requires 'exec', not a remote server.
- Cleaned up some coding errors.
+ * tests/socket.test: removed doTestsWithRemoteServer constraint from
+ socket-12.*. It requires 'exec', not a remote server. Cleaned up some
+ coding errors.
2000-09-20 Jennifer Hom <jenn@ajubasolutions.com>
* library/tcltest1.0/pkgIndex.tcl: Updated to load tcltest 2.0.
- * library/tcltest1.0/tcltest2.tcl: New version of tcltest.
- Cleanup of command line parsing: allows users to specify command
- line arguments through an environment variable named
- TCLTEST_OPTIONS [RFE: 3748], does not respond to incorrect
- arguments, and forces usage of entire flag name when using command
- line arguments. Defines accessor procs for all tcltest
- variables. Allows users to use 'return' in test scripts. Allow
- users to specify whether test files should be sourced or run in a
- separate process. 'all.tcl' code moved to tcltest package.
- 'test' proc modified to use attribute-value pairs. Allow users to
+ * library/tcltest1.0/tcltest2.tcl: New version of tcltest.
+ Cleanup of command line parsing: allows users to specify command line
+ arguments through an environment variable named TCLTEST_OPTIONS [RFE:
+ 3748], does not respond to incorrect arguments, and forces usage of
+ entire flag name when using command line arguments. Defines accessor
+ procs for all tcltest variables. Allows users to use 'return' in test
+ scripts. Allow users to specify whether test files should be sourced
+ or run in a separate process. 'all.tcl' code moved to tcltest package.
+ 'test' proc modified to use attribute-value pairs. Allow users to
specify what return codes, output, and errors can be compared and
- whether these values should be compared using regexp, glob, or
- exact matching. makeDirectory & removeDirectory now operate with
- respect to temporaryDirectory [Bug: 6001]. Test results from
- tests run in slave interpreters are now included in test totals
- [Bug: 1493]. Test files that return error values are now reported.
-
- * tests/all.tcl: Added code to check for the tcltest version
- loaded; modified to figure out which tests to run based on the
- tcltest version loaded.
+ whether these values should be compared using regexp, glob, or exact
+ matching. makeDirectory & removeDirectory now operate with respect to
+ temporaryDirectory [Bug: 6001]. Test results from tests run in slave
+ interpreters are now included in test totals [Bug: 1493]. Test files
+ that return error values are now reported.
+ * tests/all.tcl: Added code to check for the tcltest version loaded;
+ modified to figure out which tests to run based on the tcltest version
+ loaded.
* tests/tcltest.test: Modified to explicitly load version 1.0 of
tcltest.
- * tests/tcltest2.test: New test suite for tcltest; includes all of
- the old tests plus new ones reflecting changes made for version
- 2.0.
- * tests/cmdAH.test: Added singleTestInterp constraint to
- cmdAH-31.2; this test does not run if tests aren't sourced into a
- single interpreter.
- * tests/socket.test: Fixed two tests that were referencing
- variables outside of scope.
-
+ * tests/tcltest2.test: New test suite for tcltest; includes all of the
+ old tests plus new ones reflecting changes made for version 2.0.
+ * tests/cmdAH.test: Added singleTestInterp constraint to cmdAH-31.2;
+ this test does not run if tests aren't sourced into a single
+ interpreter.
+ * tests/socket.test: Fixed two tests that were referencing variables
+ outside of scope.
+
* tools/tcl.wse.in: Added code to install tcltest2.tcl.
- * doc/tcltest2.n: New documentation for tcltest version 2.0.
- Removes documentation for tcltest namespace variables. Adds
- documentation for new tcltest procs.
+ * doc/tcltest2.n: New documentation for tcltest version 2.0. Removes
+ documentation for tcltest namespace variables. Adds documentation for
+ new tcltest procs.
* unix/mkLinks: Added code to link to tcltest2.n.
@@ -702,15 +685,15 @@
2000-09-19 Eric Melski <ericm@ajubasolutions.com>
- * generic/tclCmdMZ.c (Tcl_RegexpObjCmd): When using -all, all
- attempts after the first to match the regexp against the string
- should include the TCL_REG_NOTBOL flag, to avoid erroneously
- matching ^ in the middle of the string. Added code to set this
- flag after the first pass through the matching loop. [Bug: 6284].
+ * generic/tclCmdMZ.c (Tcl_RegexpObjCmd): When using -all, all attempts
+ after the first to match the regexp against the string should include
+ the TCL_REG_NOTBOL flag, to avoid erroneously matching ^ in the middle
+ of the string. Added code to set this flag after the first pass
+ through the matching loop. [Bug: 6284].
2000-09-19 David Gravereaux <davygrvy@ajubasolutions.com>
- * doc/Eval.3: Added a note about the script argument to Tcl_Eval()
+ * doc/Eval.3: Added a note about the script argument to Tcl_Eval()
should be in UTF-8 or risk implied conversion errors when possible
combinations of upper ascii can be valid UTF-8 special codes.
@@ -726,24 +709,24 @@
* doc/Alloc.3: Added entries for Tcl_AttemptAlloc, Tcl_AttempRealloc.
* doc/StringObj.3: Added entry for Tcl_AttemptSetObjLength.
-
+
* generic/tclDecls.h:
* generic/tclStubInit.c: Regen'ed stubs files from new tcl.decls.
* generic/tcl.decls: Added stubs for the Tcl_Attempt* memory
allocators and for Tcl_AttemptSetObjLength.
- * generic/tcl.h: Added #define's for attemptckalloc,
- attemptckrealloc, which map to the Tcl_Attempt* memory allocators.
+ * generic/tcl.h: Added #define's for attemptckalloc, attemptckrealloc,
+ which map to the Tcl_Attempt* memory allocators.
* generic/tclCkalloc.c: Added non-panic'ing versions of Tcl_Alloc,
Tcl_Realloc, etc.; these are called Tcl_AttemptAlloc,
- Tcl_AttemptRealloc, etc. These are used by
- Tcl_AttemptSetObjLength and the string obj append functions.
+ Tcl_AttemptRealloc, etc. These are used by Tcl_AttemptSetObjLength and
+ the string obj append functions.
* generic/tclStringObj.c: Modified string growth algorithm to use
- doubling algorithm as long as possible, and only fall back when
- that fails. Added Tcl_AttemptSetObjLength, and modified
+ doubling algorithm as long as possible, and only fall back when that
+ fails. Added Tcl_AttemptSetObjLength, and modified
AppendUnicodeToUnicodeRep, AppendUtfToUtfRep, and
Tcl_AppendStringsToObjVA to support this.
@@ -753,11 +736,11 @@
project conversion backups.
* win/tclWinPipe.c: Stage-1 bug fix for TR#2460 "exec leaks memory".
- Added more logic around the close-down of the pipe reader thread so
- as to avoid, at all cost, a TerminateThread. Most cases with exec
- are fixed, but I don't consider 2460 done yet. Closing down the
- read side of a pipe before the child process, doesn't really fit
- the windows model. [BUG: 2460]
+ Added more logic around the close-down of the pipe reader thread so as
+ to avoid, at all cost, a TerminateThread. Most cases with exec are
+ fixed, but I don't consider 2460 done yet. Closing down the read side
+ of a pipe before the child process, doesn't really fit the windows
+ model. [BUG: 2460]
2000-09-07 Jeff Hobbs <hobbs@scriptics.com>
@@ -771,14 +754,14 @@
* win/tclWinLoad.c (TclpLoadFile): added special message for
ERROR_PROC_NOT_FOUND exception in loading a dll.
- * win/tclWinError.c: changed ERROR_PROC_NOT_FOUND to map from
- ESRCH (POSIX: no such process) to EINVAL because there is no good
- mapping for "procedure not found".
+ * win/tclWinError.c: changed ERROR_PROC_NOT_FOUND to map from ESRCH
+ (POSIX: no such process) to EINVAL because there is no good mapping
+ for "procedure not found".
* README:
* generic/tcl.h:
* library/tcltest1.0/tcltest.tcl:
- * tools/tcl.wse.in:
+ * tools/tcl.wse.in:
* tools/tcltk-man2html.tcl:
* unix/configure.in:
* unix/tcl.spec:
@@ -795,8 +778,8 @@
appends.
* doc/source.n:
- * doc/Eval.3: added extra note about how to safe use ^Z in code,
- as it is now a cross-platform (was just Windows) EOF char.
+ * doc/Eval.3: added extra note about how to safe use ^Z in code, as it
+ is now a cross-platform (was just Windows) EOF char.
2000-09-05 Jeff Hobbs <hobbs@scriptics.com>
@@ -810,26 +793,26 @@
2000-08-29 Eric Melski <ericm@ajubasolutions.com>
- * generic/tclStringObj.c: Applied patch from Gerhard Hintermayer
- to provide a more conservative string growth algorithm for strings
- larger than one megabyte; this allows more efficient use of memory
- for very large strings.
+ * generic/tclStringObj.c: Applied patch from Gerhard Hintermayer to
+ provide a more conservative string growth algorithm for strings larger
+ than one megabyte; this allows more efficient use of memory for very
+ large strings.
2000-08-25 Eric Melski <ericm@ajubasolutions.com>
* tests/trace.test: Extended array tracing tests.
- * doc/trace.n: Clarified information about when array traces will
- be fired.
+ * doc/trace.n: Clarified information about when array traces will be
+ fired.
* generic/tclVar.c (Tcl_ArrayObjCmd): Corrected call to CallTraces
- (for TCL_TRACE_ARRAY) to only be called when the variable is
- either an array or is undefined, to ensure that array traces do
- not fire for scalar variables.
+ (for TCL_TRACE_ARRAY) to only be called when the variable is either an
+ array or is undefined, to ensure that array traces do not fire for
+ scalar variables.
2000-08-24 Eric Melski <ericm@ajubasolutions.com>
-
- * doc/man.macros: Tweaked tab settings for .SO (Standard Options)
+
+ * doc/man.macros: Tweaked tab settings for .SO (Standard Options)
sections, based on suggestion from Peter Spjuth.
2000-08-24 Mo DeJong <mdejong@redhat.com>
@@ -838,23 +821,22 @@
* unix/configure.in:
* unix/tcl.m4 (SC_ENABLE_GCC): Remove --enable-gcc option.
* win/README: Add note about building with Cygwin.
- * win/configure.in:
- * win/tcl.m4 (SC_ENABLE_GCC): Remove --enable-gcc option.
- Remove quick hack that provided cross compile support for
- windows builds.
+ * win/configure.in:
+ * win/tcl.m4 (SC_ENABLE_GCC): Remove --enable-gcc option. Remove quick
+ hack that provided cross compile support for windows builds.
2000-08-24 Eric Melski <ericm@ajubasolutions.com>
- Overall change: Added support for command rename/delete traces
- and new trace syntax, from patch from Vince Darley. Added support
- for array traces for variables. [RFE: 5048, 5967].
+ Overall change: Added support for command rename/delete traces and new
+ trace syntax, from patch from Vince Darley. Added support for array
+ traces for variables. [RFE: 5048, 5967].
* doc/trace.n: Updated documentation for new syntax; flagged old
- syntax as deprecated; added documentation for command
- rename/delete traces and variable array traces.
+ syntax as deprecated; added documentation for command rename/delete
+ traces and variable array traces.
- * tests/trace.test: Updated tests for new trace syntax; new tests
- for command rename/delete traces; new tests for array traces.
+ * tests/trace.test: Updated tests for new trace syntax; new tests for
+ command rename/delete traces; new tests for array traces.
* generic/tclVar.c: Support for new trace syntax; support for
TCL_TRACE_ARRAY.
@@ -863,17 +845,17 @@
* generic/tclDecls.h:
* generic/tcl.decls: Stub functions for command rename/delete traces.
- * generic/tcl.h:
+ * generic/tcl.h:
* generic/tclInt.h:
* generic/tclBasic.c: Support for command traces.
- * generic/tclCmdMZ.c (TclTraceVariableObjCmd): Patched to support
- new [trace] syntax:
+ * generic/tclCmdMZ.c (TclTraceVariableObjCmd): Patched to support new
+ [trace] syntax:
trace {add|remove|list} {variable|command} name ops command
Added support for command traces (rename, delete operations).
- Added support for TCL_TRACE_ARRAY at Tcl level (array operation
- for variable traces).
-
+ Added support for TCL_TRACE_ARRAY at Tcl level (array operation for
+ variable traces).
+
2000-08-20 Eric Melski <ericm@ajubasolutions.com>
* generic/tclVar.c: Added check for non-arrays for [array statistics]
@@ -885,11 +867,11 @@
tclPlatDecls.h can't be parsed due to a missing definition of TCHAR.
Added a check to include it when not defined.
- ***POSSIBLE OBSCURE BUG*** could be caused when the compile flags
- for the core happen to be different than a project who uses these
- publics regarding -D_MBCS and -D_UNICODE. This added check might
- have to be revisited later with a better understanding of the
- reprocusions. I think TCHAR should be replaced with it's expansion.
+ ***POSSIBLE OBSCURE BUG*** could be caused when the compile flags for
+ the core happen to be different than a project who uses these publics
+ regarding -D_MBCS and -D_UNICODE. This added check might have to be
+ revisited later with a better understanding of the reprocusions. I
+ think TCHAR should be replaced with it's expansion.
2000-08-18 David Gravereaux <davygrvy@ajubasolutions.com>
@@ -899,13 +881,13 @@
2000-08-15 Eric Melski <ericm@ajubasolutions.com>
* library/tcltest1.0/tcltest.tcl: Set debug level in
- tcltest::restoreState to 2, for consistancy with the debug level
- in tcltest::saveState [Bug: 4505].
+ tcltest::restoreState to 2, for consistancy with the debug level in
+ tcltest::saveState [Bug: 4505].
2000-08-14 Eric Melski <ericm@ajubasolutions.com>
- * win/makefile.vc:
- * win/Makefile.in:
+ * win/makefile.vc:
+ * win/Makefile.in:
* unix/Makefile.in: Added tclPlatDecls.h to the list of installed
headers, for more complete stubs support. [Bug: 5241].
@@ -913,47 +895,44 @@
platform-specific stubs declarations (Tcl_WinTCharToUtf, etc)
[Bug: 5241].
- * README: Updated link for instructions on compiling Tcl from
- sources to point to correct location
- (http://dev.scriptics.com/doc/... instead of
- http://dev.scriptics.com/support/...).
+ * README: Updated link for instructions on compiling Tcl from sources
+ to point to correct location (http://dev.scriptics.com/doc/... instead
+ of http://dev.scriptics.com/support/...).
2000-08-11 Eric Melski <ericm@ajubasolutions.com>
* generic/tclEnv.c (TclUnsetEnv): Changed declaration of length
- variable from "unsigned int" to "int", to match usage when passed
- to TclpFindVariable [Bug: 6126].
+ variable from "unsigned int" to "int", to match usage when passed to
+ TclpFindVariable [Bug: 6126].
2000-08-10 Eric Melski <ericm@ajubasolutions.com>
- * library/msgcat1.0/pkgIndex.tcl: Bumped version number to 1.2
- [Bug: 6100].
+ * library/msgcat1.0/pkgIndex.tcl: Bumped version number to 1.2 [Bug:
+ 6100].
- * library/msgcat1.0/msgcat.tcl: Removed erroneous [package forget]
- in msgcat namespace initializer. Bumped version number to 1.2
- [Bug: 6100].
+ * library/msgcat1.0/msgcat.tcl: Removed erroneous [package forget] in
+ msgcat namespace initializer. Bumped version number to 1.2 [Bug: 6100]
2000-08-10 David Gravereaux <davygrvy@ajubasolutions.com>
- * generic/tclObj.c: r1.15 accidentally changed a global mutex
- name tclObjMutex to ObjMutex. Put the correct name back.
+ * generic/tclObj.c: r1.15 accidentally changed a global mutex name
+ tclObjMutex to ObjMutex. Put the correct name back.
2000-08-07 Eric Melski <ericm@ajubasolutions.com>
* tests/indexObj.test: Added tests using the [testwrongnumargs]
command to test Tcl_WrongNumArgs.
- * generic/tclTest.c (TestWrongNumArgsObjCmd): Added test function
- for the Tcl_WrongNumArgs function.
+ * generic/tclTest.c (TestWrongNumArgsObjCmd): Added test function for
+ the Tcl_WrongNumArgs function.
- * generic/tclIndexObj.c (Tcl_WrongNumArgs): Corrected algorithm to
- not insert a space before the message component when objc == 0
- [Bug: 6078].
+ * generic/tclIndexObj.c (Tcl_WrongNumArgs): Corrected algorithm to not
+ insert a space before the message component when objc == 0 [Bug: 6078]
2000-07-27 Mo DeJong <mdejong@redhat.com>
- * win/configure.in: TCL_STUB_LIB_FLAG should not
- include ${TCL_DBGX} in win/tclConfig.sh, fix that.
+ * win/configure.in: TCL_STUB_LIB_FLAG should not include ${TCL_DBGX}
+ in win/tclConfig.sh, fix that.
2000-07-25 David Gravereaux <davygrvy@ajubasolutions.com>
@@ -965,30 +944,30 @@
* generic/tclTest.c:
* mac/tclMacPort.h:
* unix/tclUnixPort.h:
- * win/tclWinInit.c: Thread-safe rewrite for tclAsync.c. Added
- notifier alerting on all platforms as it was only working on Win
- before. Removed older Win hacks that would end-up waking the
- wrong notifier in the presence of a threaded build. All tests
- pass as before. New test cases will be added soon for the new
- behavior. [BUG: 5791]
+ * win/tclWinInit.c: Thread-safe rewrite for tclAsync.c. Added notifier
+ alerting on all platforms as it was only working on Win before.
+ Removed older Win hacks that would end-up waking the wrong notifier in
+ the presence of a threaded build. All tests pass as before. New test
+ cases will be added soon for the new behavior. [BUG: 5791]
2000-07-25 Eric Melski <ericm@ajubasolutions.com>
- * generic/tclVar.c (CallTraces): Added check for VAR_TRACE_ACTIVE
- on the array containing the variable before executing traces on
- that array, to conform with normal variable traces and the
- documentation, which states that while executing a trace, other
- traces on that variable are disabled. [Bug: 6049].
+ * generic/tclVar.c (CallTraces): Added check for VAR_TRACE_ACTIVE on
+ the array containing the variable before executing traces on that
+ array, to conform with normal variable traces and the documentation,
+ which states that while executing a trace, other traces on that
+ variable are disabled. [Bug: 6049].
- * win/tclWinPipe.c (BuildCommandLine): Added Tcl_DStringFree call
- to prevent potential memory leaks [Bug: 6041].
+ * win/tclWinPipe.c (BuildCommandLine): Added Tcl_DStringFree call to
+ prevent potential memory leaks [Bug: 6041].
2000-07-24 Eric Melski <ericm@ajubasolutions.com>
- * doc/msgcat.n: Added documentation about the selection of the
- default locale on Windows.
+ * doc/msgcat.n: Added documentation about the selection of the default
+ locale on Windows.
2000-07-23 Joe English <jenglish@flightlab.com>
+
* doc/AddErrInfo.3:
* doc/ChnlStack.3:
* doc/Exit.3:
@@ -1006,13 +985,13 @@
2000-07-21 Eric Melski <ericm@ajubasolutions.com>
- * generic/tclStubInit.c:
- * generic/tclObj.c:
- * generic/tclInt.h:
- * generic/tclHash.c:
- * generic/tclDecls.h:
- * generic/tcl.h:
- * generic/tcl.decls:
+ * generic/tclStubInit.c:
+ * generic/tclObj.c:
+ * generic/tclInt.h:
+ * generic/tclHash.c:
+ * generic/tclDecls.h:
+ * generic/tcl.h:
+ * generic/tcl.decls:
* doc/Hash.3: Reapplied patch from Paul Duffin to extend hash tables
to allow custom key types, such as Tcl_Obj *'s, and others.
@@ -1022,41 +1001,41 @@
2000-07-21 Mo DeJong <mdejong@redhat.com>
* win/configure.in: Define ${prefix} and ${exec_prefix} like
- unix/configure.in. Fix or add TCL_SRC_DIR, TCL_STUB_LIB_FILE,
+ unix/configure.in. Fix or add TCL_SRC_DIR, TCL_STUB_LIB_FILE,
TCL_STUB_LIB_FLAG, TCL_BUILD_STUB_LIB_SPEC, TCL_STUB_LIB_SPEC,
TCL_BUILD_STUB_LIB_PATH, TCL_STUB_LIB_PATH.
2000-07-20 Eric Melski <ericm@ajubasolutions.com>
- * generic/tclStubInit.c:
- * generic/tclObj.c:
- * generic/tclInt.h:
- * generic/tclHash.c:
- * generic/tclDecls.h:
- * generic/tcl.h:
- * generic/tcl.decls:
- * doc/Hash.3: Reverted patch from Paul Duffin to extend hash tables
- to allow custom key types, such as Tcl_Obj *'s, and others; it
- seems to break Tk.
+ * generic/tclStubInit.c:
+ * generic/tclObj.c:
+ * generic/tclInt.h:
+ * generic/tclHash.c:
+ * generic/tclDecls.h:
+ * generic/tcl.h:
+ * generic/tcl.decls:
+ * doc/Hash.3: Reverted patch from Paul Duffin to extend hash tables to
+ allow custom key types, such as Tcl_Obj *'s, and others; it seems to
+ break Tk.
2000-07-19 Eric Melski <ericm@ajubasolutions.com>
- * generic/tclStubInit.c:
- * generic/tclObj.c:
- * generic/tclInt.h:
- * generic/tclHash.c:
- * generic/tclDecls.h:
- * generic/tcl.h:
- * generic/tcl.decls:
- * doc/Hash.3: Applied patch from Paul Duffin to extend hash tables
- to allow custom key types, such as Tcl_Obj *'s, and others.
+ * generic/tclStubInit.c:
+ * generic/tclObj.c:
+ * generic/tclInt.h:
+ * generic/tclHash.c:
+ * generic/tclDecls.h:
+ * generic/tcl.h:
+ * generic/tcl.decls:
+ * doc/Hash.3: Applied patch from Paul Duffin to extend hash tables to
+ allow custom key types, such as Tcl_Obj *'s, and others.
* tests/pkgMkIndex.test: Added tests for pkg_compareExtension.
- * library/package.tcl: Enhanced pkg_compareExtension to handle
- Unixes which tack the version number on to the end of library
- names (eg, foo.so.1.2); such filenames will be correctly matched.
- (Patch from Vince Darley).
+ * library/package.tcl: Enhanced pkg_compareExtension to handle Unixes
+ which tack the version number on to the end of library names (eg,
+ foo.so.1.2); such filenames will be correctly matched. (Patch from
+ Vince Darley).
* win/makefile.vc: Applied patch from Don Porter to provide better
nmake support for NT/Alpha [RFE: 5938].
@@ -1065,50 +1044,47 @@
* unix/configure.in:
* unix/tcl.m4:
- * win/tcl.m4: Properly quote arguments to m4 macros. This allows
- Tcl to work with the new version of autoconf.
+ * win/tcl.m4: Properly quote arguments to m4 macros. This allows Tcl
+ to work with the new version of autoconf.
2000-07-18 Eric Melski <ericm@ajubasolutions.com>
* tests/opt.test: Removed references to Lfirst, Lrest functions.
- * library/opt0.4/optparse.tcl: Applied patch from Chris Nelson,
- which replaces the [Lfirst] function with an inline [lindex ... 0]
- and [Lrest] with [lrange ... 1 end], for better performance.
- [RFE: 6019]
-
+ * library/opt0.4/optparse.tcl: Applied patch from Chris Nelson, which
+ replaces the [Lfirst] function with an inline [lindex ... 0] and
+ [Lrest] with [lrange ... 1 end], for better performance. [RFE: 6019]
2000-07-18 Eric Melski <ericm@scriptics.com>
- * compat/string.h: Fixed function prototypes for strpbrk and
- strtok [Bug: 6020].
+ * compat/string.h: Fixed function prototypes for strpbrk and strtok
+ [Bug: 6020].
2000-07-17 David Gravereaux <davygrvy@ajubasolutions.com>
- * win/tclWinChan.c: Win2K OS bug with
- GetStdHandle(STD_OUTPUT_HANDLE) giving the wrong answer. This
- made TclpGetDefaultStdChannel grab what it thought was a valid
- native stdout handle. Added a new WriteFile() test to make sure
- it's really valid. This OS bug doesn't affect the shells. Only
- -subsystem:windows (aka WinMain) application that dynamically
- load tclXX.dll [BUG: 5971]
+ * win/tclWinChan.c: Win2K OS bug with GetStdHandle(STD_OUTPUT_HANDLE)
+ giving the wrong answer. This made TclpGetDefaultStdChannel grab what
+ it thought was a valid native stdout handle. Added a new WriteFile()
+ test to make sure it's really valid. This OS bug doesn't affect the
+ shells. Only -subsystem:windows (aka WinMain) application that
+ dynamically load tclXX.dll [BUG: 5971]
2000-07-17 Eric Melski <ericm@scriptics.com>
- * library/msgcat1.0/msgcat.tcl:
- * doc/msgcat.n:
- * tests/msgcat.test: Applied patches from Chris Nelson, to provide
- the mcmset function, which allows the translator to set multiple
- string translations in a single function call, rather than
- requiring many calls to mcset. [RFE: 6000, 5993]. In addition,
- these patches correct mcload to use utf-8 encoding on when reading
- message catalog files, and provides for better default behavior
- for determining the locale on a Windows system.
+ * library/msgcat1.0/msgcat.tcl:
+ * doc/msgcat.n:
+ * tests/msgcat.test: Applied patches from Chris Nelson, to provide the
+ mcmset function, which allows the translator to set multiple string
+ translations in a single function call, rather than requiring many
+ calls to mcset. [RFE: 6000, 5993]. In addition, these patches correct
+ mcload to use utf-8 encoding on when reading message catalog files,
+ and provides for better default behavior for determining the locale on
+ a Windows system.
2000-07-17 Mo DeJong <mdejong@redhat.com>
- * unix/tcl.m4 (SC_ENABLE_GCC): Don't set CC=gcc
- before running AC_PROG_CC if CC is already set.
+ * 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>
@@ -1124,31 +1100,30 @@
2000-07-07 Mo DeJong <mdejong@redhat.com>
- * win/configure.in: Fix definition of
- TCL_SRC_DIR so that it matches the Unix version.
+ * win/configure.in: Fix definition of TCL_SRC_DIR so that it matches
+ the Unix version.
* win/tclConfig.sh.in: Removed duplicate variables.
2000-07-06 Eric Melski <ericm@scriptics.com>
- * tests/msgcat.test:
- * library/msgcat1.0/msgcat.tcl: Applied patch from Christian
- Krone, to provide extended args support for msgcat::unknown, which
- is used for strings without a known translation in the current
- locale [Bug: 5984].
+ * tests/msgcat.test:
+ * library/msgcat1.0/msgcat.tcl: Applied patch from Christian Krone, to
+ provide extended args support for msgcat::unknown, which is used for
+ strings without a known translation in the current locale [Bug: 5984].
2000-06-29 Eric Melski <ericm@scriptics.com>
* doc/msgcat.n: Doc's for mcmax function.
- * library/msgcat1.0/msgcat.tcl: Applied patches from Laurent
- Duperval, to add mcmax function, which computes the length of the
- longest of several translated strings. Bumped version number to 1.1.
+ * library/msgcat1.0/msgcat.tcl: Applied patches from Laurent Duperval,
+ to add mcmax function, which computes the length of the longest of
+ several translated strings. Bumped version number to 1.1.
2000-06-27 Eric Melski <ericm@scriptics.com>
- * tests/stringObj.test: Tweaked tests to avoid hardcoded
- high-ASCII characters (which will fail in multibyte locales);
- instead used \uXXXX syntax. [Bug: 3842].
+ * tests/stringObj.test: Tweaked tests to avoid hardcoded high-ASCII
+ characters (which will fail in multibyte locales); instead used \uXXXX
+ syntax. [Bug: 3842].
2000-06-26 Eric Melski <ericm@scriptics.com>
@@ -1157,17 +1132,17 @@
2000-06-23 Eric Melski <ericm@scriptics.com>
- * doc/Hash.3: Added documentation patch for Tcl_Obj *'s as keys in
- Tcl hash tables [RFE: 5934].
+ * doc/Hash.3: Added documentation patch for Tcl_Obj *'s as keys in Tcl
+ hash tables [RFE: 5934].
- * generic/tcl.h:
- * generic/tclHash.c: Applied patch from [RFE: 5934], which extends
- Tcl hash tables to allow Tcl_Obj *'s as the key.
+ * generic/tcl.h:
+ * generic/tclHash.c: Applied patch from [RFE: 5934], which extends Tcl
+ hash tables to allow Tcl_Obj *'s as the key.
2000-06-20 Eric Melski <ericm@ajubasolutions.com>
* tests/opt.test:
- * library/opt0.4/optparse.tcl: Applied patch from [Bug: 5922], which
+ * library/opt0.4/optparse.tcl: Applied patch from [Bug: 5922], which
corrected an incorrect use of [string match].
* unix/tclConfig.sh.in:
@@ -1183,23 +1158,23 @@
* win/tcl.m4:
* win/configure.in:
- * win/Makefile.in: Applied patch from [RFE: 5844], to extend
- support for mingw compile environment on Windows.
+ * win/Makefile.in: Applied patch from [RFE: 5844], to extend support
+ for mingw compile environment on Windows.
* win/tclWinDde.c:
* win/tclWinInit.c:
* win/tclWinNotify.c:
* win/tclWinPipe.c:
* win/tclWinReg.c:
- * win/tclWinThrd.c: Applied patch from [Bug: 5794], to fix
- compiler warnings when using mingw on Windows.
+ * win/tclWinThrd.c: Applied patch from [Bug: 5794], to fix compiler
+ warnings when using mingw on Windows.
2000-05-31 Jeff Hobbs <hobbs@scriptics.com>
* tests/set-old.test:
* doc/unset.n:
- * generic/tclVar.c (Tcl_UnsetObjCmd): added -nocomplain and --
- options to unset, to allow for a silent unset operation.
+ * generic/tclVar.c (Tcl_UnsetObjCmd): added -nocomplain and -- options
+ to unset, to allow for a silent unset operation.
2000-05-31 Eric Melski <ericm@scriptics.com>
@@ -1216,68 +1191,66 @@
8.4a1 RELEASE
- * generic/tclExecute.c (TclExecuteByteCode INST_STR_CMP): added
- test of iResult return from memcmp, as memcmp isn't required to
- return only -1,0,1.
+ * generic/tclExecute.c (TclExecuteByteCode INST_STR_CMP): added test
+ of iResult return from memcmp, as memcmp isn't required to return only
+ -1,0,1.
2000-06-03 Jeff Hobbs <hobbs@scriptics.com>
- * generic/tclIndexObj.c (Tcl_GetIndexFromObjStruct): Corrected
- caching of the index ptr to account for offsets != sizeof(char *).
- [Bug: 5153]
+ * generic/tclIndexObj.c (Tcl_GetIndexFromObjStruct): Corrected caching
+ of the index ptr to account for offsets != sizeof(char *). [Bug: 5153]
2000-05-29 Sandeep Tamhankar <sandeep@scriptics.com>
* tests/http.test
* doc/http.n
- * library/http2.3/http.tcl: Fixed bug 5741, where unsuccessful
- geturl calls sometimes leaked memory and resources (sockets).
- Also, switched around some of the logic so that http::wait never
- throws an exception. This is because in an asynchronous geturl,
- the command callback will probably end up doing all the error
- handling anyway, and in an asynchronous situation, the user
- expects to check the state when the transaction completes, as
- opposed to being thrown an exception. For the http package, this
- menas the user can check http::status for "error" and http::error
- for the error message after doing the http::wait.
+ * library/http2.3/http.tcl: Fixed bug 5741, where unsuccessful geturl
+ calls sometimes leaked memory and resources (sockets). Also, switched
+ around some of the logic so that http::wait never throws an exception.
+ This is because in an asynchronous geturl, the command callback will
+ probably end up doing all the error handling anyway, and in an
+ asynchronous situation, the user expects to check the state when the
+ transaction completes, as opposed to being thrown an exception. For
+ the http package, this menas the user can check http::status for
+ "error" and http::error for the error message after doing the
+ http::wait.
2000-05-27 Jeff Hobbs <hobbs@scriptics.com>
* tests/info.test:
* doc/info.n:
* generic/tclIOUtil.c (Tcl_EvalFile):
- * generic/tclCmdIL.c (InfoScriptCmd): added ability to set the
- info script return value [info script ?newFileName?]. This will
- be beneficial for virtual file system programs. [Bug: 4225]
+ * generic/tclCmdIL.c (InfoScriptCmd): added ability to set the info
+ script return value [info script ?newFileName?]. This will be
+ beneficial for virtual file system programs. [Bug: 4225]
2000-05-26 Jeff Hobbs <hobbs@scriptics.com>
* generic/tclCmdMZ.c (Tcl_RegsubObjCmd): reworked to operate in
Unicode, tweaked for performance.
(Tcl_StringObjCmd) changed STR_FIRST/STR_LAST error message to
- something more understandable, reworked STR_FIRST, STR_LAST,
- STR_MAP, STR_MATCH, STR_RANGE, STR_REPLACE to operate in Unicode.
- Removed inneffectual STR_RANGE "special" ByteArray support.
- Optimized STR_MAP algorithm, especially optimized for one-pair case.
- Fixed possible mem overrun in STR_INDEX bytearray case.
-
+ something more understandable, reworked STR_FIRST, STR_LAST, STR_MAP,
+ STR_MATCH, STR_RANGE, STR_REPLACE to operate in Unicode. Removed
+ inneffectual STR_RANGE "special" ByteArray support. Optimized STR_MAP
+ algorithm, especially optimized for one-pair case. Fixed possible mem
+ overrun in STR_INDEX bytearray case.
+
* generic/tclCompExpr.c: changed INST_STREQ -> INST_STR_EQ,
INST_STRNEQ -> INST_STR_NEQ
* generic/tclCompile.c: added streq, strneq, strcmp, strlen &
strmatch to the compiled stats instructionTable
* generic/tclCompile.h: added instructions INST_STR_CMP,
INST_STR_INDEX, INST_STR_MATCH
- * generic/tclCompCmds.c: added byte compiler support for
- [string compare|match|index].
- * generic/tclExecute.c:
- Changed INST_STR_(N)EQ to return an Int object and not bother
- trying to reuse the top stack object.
- Added INST_STR_CMP, INST_STR_INDEX, INST_STR_MATCH bytecode ops.
- Extended evalstats output info with Tcl_IsShared stat info.
+ * generic/tclCompCmds.c: added byte compiler support for [string
+ compare|match|index].
+ * generic/tclExecute.c: Changed INST_STR_(N)EQ to return an Int object
+ and not bother trying to reuse the top stack object. Added
+ INST_STR_CMP, INST_STR_INDEX, INST_STR_MATCH bytecode ops. Extended
+ evalstats output info with Tcl_IsShared stat info.
* generic/tclInt.h:
- * generic/tclObj.c (Tcl_DbIsShared): added support for checking
- result of Tcl_IsShared in evalstats (TCL_COMPILE_STATS).
+ * generic/tclObj.c (Tcl_DbIsShared): added support for checking result
+ of Tcl_IsShared in evalstats (TCL_COMPILE_STATS).
* generic/tclStringObj.c (Tcl_AppendUnicodeToObj): removed dead code.
(AppendUnicodeToUnicodeRep) removed overallocation by extra
@@ -1289,31 +1262,30 @@
2000-05-23 Eric Melski <ericm@scriptics.com>
- * generic/tclInt.h: Added function prototypes for
- TclCompileStringCmd and TclCompileReturnCmd.
+ * generic/tclInt.h: Added function prototypes for TclCompileStringCmd
+ and TclCompileReturnCmd.
* generic/tclCompile.h: Added definition of INST_STRLEN opcode and
updated LAST_INST_OPCODE value.
- * generic/tclBasic.c: Added information about TclCompileStringCmd
- and TclCompileReturnCmd to BuiltInCmds table.
+ * generic/tclBasic.c: Added information about TclCompileStringCmd and
+ TclCompileReturnCmd to BuiltInCmds table.
* generic/tclExecute.c (TclExecuteByteCode): Added support for the
INST_STRLEN opcode.
- * generic/tclCompCmds.c
- (TclCompileStringCmd): Basic implementation of byte-compiled
- [string] command. Not all subcommands are implemented; those
- that are not an out-line compiled.
+ * generic/tclCompCmds.c (TclCompileStringCmd): Basic implementation of
+ byte-compiled [string] command. Not all subcommands are implemented;
+ those that are not an out-line compiled.
(TclCompileReturnCmd): Byte-compiled implementation of [return]
- command. Only "simple" returns are byte-compiled; in particular,
- if the -code, -errorinfo or -errorcode flags are used, the command
- is not byte-compiled.
+ command. Only "simple" returns are byte-compiled; in particular, if
+ the -code, -errorinfo or -errorcode flags are used, the command is not
+ byte-compiled.
2000-05-22 Jeff Hobbs <hobbs@scriptics.com>
- * doc/scan.n:
+ * doc/scan.n:
* doc/array.n: minor doc fixes [Bug: 5396]
* generic/tclEnv.c: cast cleanup [Bug: 5624]
@@ -1331,9 +1303,9 @@
* generic/tclStubInit.c:
* generic/tclIntDecls.h:
- * generic/tclInt.decls: removed TclTestChannel*Cmd from internal
- stubs table and added TclChannelEventScriptInvoker to the internal
- stubs table so it can be used from the test code.
+ * generic/tclInt.decls: removed TclTestChannel*Cmd from internal stubs
+ table and added TclChannelEventScriptInvoker to the internal stubs
+ table so it can be used from the test code.
2000-05-18 Eric Melski <ericm@scriptics.com>
@@ -1342,9 +1314,9 @@
* generic/tclDate.c: Regenerated from tclGetDate.y.
- * generic/tclGetDate.y: Tweaked grammar to properly handle the
- "ago" keyword when it follows multiple relative unit specifiers,
- as in "2 days 2 hours ago". [Bug: 5497].
+ * generic/tclGetDate.y: Tweaked grammar to properly handle the "ago"
+ keyword when it follows multiple relative unit specifiers, as in "2
+ days 2 hours ago". [Bug: 5497]
2000-05-18 Jeff Hobbs <hobbs@scriptics.com>
@@ -1354,9 +1326,9 @@
* generic/tclClock.c (FormatClock): correct code to handle locale
specific return values from strftime, if any. [Bug: 3345]
- * unix/tclUnixInit.c (TclpSetInitialEncodings): attempt to
- correct setlocale calls for XIM support and locale issues.
- [BUG: 5422 3345 4236 2522 2521]
+ * unix/tclUnixInit.c (TclpSetInitialEncodings): attempt to correct
+ setlocale calls for XIM support and locale issues. [BUG: 5422 3345
+ 4236 2522 2521]
2000-05-17 Jeff Hobbs <hobbs@scriptics.com>
@@ -1373,32 +1345,32 @@
2000-05-10 Jeff Hobbs <hobbs@scriptics.com>
- * generic/tclPosixStr.c (Tcl_SignalMsg): clarified #defines for
- Linux on Sparc to compile correctly. [Bug: 5364]
+ * generic/tclPosixStr.c (Tcl_SignalMsg): clarified #defines for Linux
+ on Sparc to compile correctly. [Bug: 5364]
* doc/namespace.n:
* tests/namespace.test:
- * generic/tclNamesp.c (Tcl_NamespaceObjCmd): added 'namespace
- exists' command. [Bug: 4665]
+ * generic/tclNamesp.c (Tcl_NamespaceObjCmd): added 'namespace exists'
+ command. [Bug: 4665]
* doc/source.n:
* doc/Eval.3:
* tests/source.test:
- * generic/tclIOUtil.c (Tcl_EvalFile): added explicit \32 (^Z)
- eofchar (affects Tcl_EvalFile in C, "source" in Tcl). This was
- implicit on Windows already, and is now cross-platform to allow
- for scripted documents.
+ * generic/tclIOUtil.c (Tcl_EvalFile): added explicit \32 (^Z) eofchar
+ (affects Tcl_EvalFile in C, "source" in Tcl). This was implicit on
+ Windows already, and is now cross-platform to allow for scripted
+ documents.
2000-05-09 Andreas Kupries <a.kupries@westend.com>
operating as proxy for David Gravereaux <davygrvy@pobox.com>
-
+
* win/tclWinThrd.c (TclpInitLock, TclpMasterLock): Added missing
- initialization of joinLock.
+ initialization of joinLock.
2000-05-09 Eric Melski <ericm@scriptics.com>
- * tests/lsearch.test:
- * doc/lsearch.n:
+ * tests/lsearch.test:
+ * doc/lsearch.n:
* generic/tclCmdIL.c (Tcl_LsearchObjCmd): Extended [lsearch] to
support sorted list searching and typed list searching. [RFE: 4098].
@@ -1408,19 +1380,19 @@
* tests/expr.test:
* tests/expr-old.test: added tests for 'eq' and 'ne'
* generic/tclExecute.c:
- * generic/tclCompile.h: added INST_STREQ and INST_STRNEQ opcodes
- that do strict string comparisons.
+ * generic/tclCompile.h: added INST_STREQ and INST_STRNEQ opcodes that
+ do strict string comparisons.
* generic/tclCompExpr.c: added 'eq' and 'ne' string comparison
operators.
- * generic/tclParseExpr.c (GetLexeme): added 'eq' and 'ne' expr
- parse terms (string (in)equality check).
+ * generic/tclParseExpr.c (GetLexeme): added 'eq' and 'ne' expr parse
+ terms (string (in)equality check).
* generic/tclCmdIL.c (Tcl_LinsertObjCmd): made use of
- Tcl_DuplicateObj where code was otherwise duplicated. Made
- special case of inserting one element at the end work again (where
- index == len).
- (Tcl_LreplaceObjCmd): moved Tcl_DuplicateObj call lower and
- cleaned up use of other arguments.
+ Tcl_DuplicateObj where code was otherwise duplicated. Made special
+ case of inserting one element at the end work again (where index ==
+ len).
+ (Tcl_LreplaceObjCmd): moved Tcl_DuplicateObj call lower and cleaned
+ up use of other arguments.
* generic/tclObj.c (Tcl_DuplicateObj): simplified code to call
TclInitStringRep, which the code was just duplicating in part.
@@ -1437,16 +1409,15 @@
2000-05-08 Eric Melski <ericm@scriptics.com>
- * tests/set-old.test:
- * doc/array.n:
+ * tests/set-old.test:
+ * doc/array.n:
* generic/tclVar.c: Added [array statistics] command [RFE: 4557]
2000-05-06 Andreas Kupries <a.kupries@westend.com>
operating as proxy for David Gravereaux <davygrvy@pobox.com>
- * tclThreadJoin.c: Fixed several places with missing a & in
- arguments to calls of Tcl_Mutex(Un)lock and
- Tcl_ConditionNotify functions.
+ * tclThreadJoin.c: Fixed several places with missing a & in arguments
+ to calls of Tcl_Mutex(Un)lock and Tcl_ConditionNotify functions.
2000-05-02 Jeff Hobbs <hobbs@scriptics.com>
@@ -1480,72 +1451,70 @@
2000-05-02 Andreas Kupries <a.kupries@westend.com>
- * Overall changes:
+ Overall changes:
(1) Implementation of joinable threads for all platforms.
- (2) Additional API's for channels. Required to allow the
- thread extension to move channels between threads.
+ (2) Additional API's for channels. Required to allow the thread
+ extension to move channels between threads.
* generic/tcl.decls (lines 1360f): Added Tcl_JoinThread,
- Tcl_IsChannelShared, Tcl_IsChannelRegistered, Tcl_CutChannel,
- Tcl_SpliceChannel, Tcl_IsChannelExisting and
- Tcl_ClearChannelHandlers (slots 394 to 400).
+ Tcl_IsChannelShared, Tcl_IsChannelRegistered, Tcl_CutChannel,
+ Tcl_SpliceChannel, Tcl_IsChannelExisting and Tcl_ClearChannelHandlers
+ (slots 394 to 400).
* generic/tclIO.c: Implemented Tcl_IsChannelRegistered,
- Tcl_IsChannelShared, Tcl_CutChannel, Tcl_SpliceChannel,
- Tcl_IsChannelExisting and Tcl_ClearChannelHandlers.
- Tcl_CutChannel uses code from CloseChannel. Replaced this code
- by a call to Tcl_CutChannel. Replaced several code fragments
- adding channels to the channel list with calls to
- Tcl_SpliceChannel. Removed now unused variables from
- CloseChannel and Tcl_UnstackChannel. Tcl_ClearChannelHandlers
- uses code from Tcl_Close. Replaced this code by a call to
- Tcl_ClearChannelHandlers. Removed now unused variables from
- Tcl_Close. Added the subcommands 'cut', 'forgetch', 'splice' and
- 'isshared' to the test code
- (TclTestChannelCmd).
+ Tcl_IsChannelShared, Tcl_CutChannel, Tcl_SpliceChannel,
+ Tcl_IsChannelExisting and Tcl_ClearChannelHandlers. Tcl_CutChannel
+ uses code from CloseChannel. Replaced this code by a call to
+ Tcl_CutChannel. Replaced several code fragments adding channels to
+ the channel list with calls to Tcl_SpliceChannel. Removed now unused
+ variables from CloseChannel and Tcl_UnstackChannel.
+ Tcl_ClearChannelHandlers uses code from Tcl_Close. Replaced this code
+ by a call to Tcl_ClearChannelHandlers. Removed now unused variables
+ from Tcl_Close. Added the subcommands 'cut', 'forgetch', 'splice' and
+ 'isshared' to the test code (TclTestChannelCmd).
* unix/tclUnixThread.c: Implemented Tcl_JoinThread using the
- pthread-functionality.
+ pthread-functionality.
* win/tclWinThrd.c: Fixed several small typos in comments.
- Implemented Tcl_JoinThread using a platform independent
- emulation layer (see generic/tclThreadJoin.c below). Added
- 'joinLock' to serialize Tcl_CreateThread and TclpExitThread to
- prevent a race for joinable threads.
+ Implemented Tcl_JoinThread using a platform independent emulation
+ layer (see generic/tclThreadJoin.c below). Added 'joinLock' to
+ serialize Tcl_CreateThread and TclpExitThread to prevent a race for
+ joinable threads.
* mac/tclMacThrd.c: Implemented Tcl_JoinThread using a platform
- independent emulation layer (see generic/tclThreadJoin.c
- below). Due to the cooperative nature of threading on this
- platform the race mentioned above is not present.
+ independent emulation layer (see generic/tclThreadJoin.c below). Due
+ to the cooperative nature of threading on this platform the race
+ mentioned above is not present.
- * generic/tclThreadJoin.c: New file. Contains a platform
- independent emulation layer helping in the implementation of
- joinable threads for the win and mac platforms.
+ * generic/tclThreadJoin.c: New file. Contains a platform independent
+ emulation layer helping in the implementation of joinable threads for
+ the win and mac platforms.
* generic/tclInt.h: Added declarations for TclJoinThread,
- TclRememberJoinableThread and TclSignalExitThread. These
- procedures define the API of the emulation layer for joinable
- threads (see generic/tclThreadJoin.c above).
+ TclRememberJoinableThread and TclSignalExitThread. These procedures
+ define the API of the emulation layer for joinable threads (see
+ generic/tclThreadJoin.c above).
* win/Makefile.in:
* win/makefile.vc: Added generic/tclTheadJoin.o to the rules.
- * mac/: I don't know to which file generic/tclTheadJoin.o has to
- be added to so that it compiles. Sorry.
+ * mac/: I don't know to which file generic/tclTheadJoin.o has to be
+ added to so that it compiles. Sorry.
- * unix/tclUnixChan.c: #ifdef'd the thread-local list of file
- channels as it prevents us from transfering channels. To restore
- this we may need an extended interface to drivers in the
- future. Target: 9.0. Found while testing the new transfer of
- channels. The information in this list for a channel was left
- behind and then crashed the system during finalization.
+ * unix/tclUnixChan.c: #ifdef'd the thread-local list of file channels
+ as it prevents us from transfering channels. To restore this we may
+ need an extended interface to drivers in the future. Target:
+ 9.0. Found while testing the new transfer of channels. The information
+ in this list for a channel was left behind and then crashed the system
+ during finalization.
* generic/tclThreadTest.c: Added -joinable flag to 'testthread
- create'. Added subcommand 'testthread join'.
+ create'. Added subcommand 'testthread join'.
* doc/CrtChannel.3: Added documentation for Tcl_IsChannelRegistered,
- Tcl_IsChannelShared, Tcl_CutChannel, Tcl_SpliceChannel,
- Tcl_IsChannelExisting and Tcl_ClearChannelHandlers.
+ Tcl_IsChannelShared, Tcl_CutChannel, Tcl_SpliceChannel,
+ Tcl_IsChannelExisting and Tcl_ClearChannelHandlers.
* doc/Thread.3: Added documentation for Tcl_JoinThread.
@@ -1563,8 +1532,8 @@
2000-04-26 Eric Melski <ericm@scriptics.com>
- * doc/memory.n: Man page for Tcl "memory" command, which is
- created when TCL_MEM_DEBUG is defined at compile time.
+ * doc/memory.n: Man page for Tcl "memory" command, which is created
+ when TCL_MEM_DEBUG is defined at compile time.
* doc/TCL_MEM_DEBUG.3: Man page with overall information about
TCL_MEM_DEBUG usage.
@@ -1577,13 +1546,13 @@
* unix/mkLinks: Regen'd with new mkLinks.tcl.
* unix/mkLinks.tcl: Fixed indentation, made link setup more
- intelligent (only do one existance test per man page, instead of
- one per function).
+ intelligent (only do one existance test per man page, instead of one
+ per function).
* doc/library.n: Fixed .SH NAME macro to include each function
- documented on the page, so that mkLinks will know about the
- functions listed there, and so that the Windows help file index
- will get set up correctly [Bug: 1898, 5273].
+ documented on the page, so that mkLinks will know about the functions
+ listed there, and so that the Windows help file index will get set up
+ correctly [Bug: 1898, 5273].
2000-04-26 Jeff Hobbs <hobbs@scriptics.com>
@@ -1613,42 +1582,41 @@
2000-04-25 Eric Melski <ericm@scriptics.com>
- * unix/mkLinks:
+ * unix/mkLinks:
* doc/AddErrInfo.3: Added information about Tcl_LogCommandInfo
[Bug: 1818].
2000-04-24 Eric Melski <ericm@scriptics.com>
- * unix/mkLinks:
+ * unix/mkLinks:
* doc/OpenFileChnl.3: Added man entry for Tcl_Ungets [Bug: 1834].
- * unix/mkLinks:
+ * unix/mkLinks:
* doc/SourceRCFile.3: Man page for Tcl_SourceRCFile [Bug: 1833].
- * unix/mkLinks:
+ * unix/mkLinks:
* doc/ParseCmd.3: Added documentation for Tcl_ParseVar [Bug: 1828].
2000-04-24 Jeff Hobbs <hobbs@scriptics.com>
* unix/tclUnixNotfy.c (Tcl_FinalizeNotifier, NotifierThreadProc):
- added write of 'q' into triggerPipe for notifier in threaded case,
- so that Tcl doesn't hang when children are still running [Bug: 4139]
+ added write of 'q' into triggerPipe for notifier in threaded case, so
+ that Tcl doesn't hang when children are still running [Bug: 4139]
* unix/tclUnixThrd.c (Tcl_MutexLock): minor comment fixes.
2000-04-23 Jim Ingham <jingham@cygnus.com>
These changes make some error handling marginally better for Mac
- sockets. It is still somewhat flakey, however.
-
- * mac/tclMacSock.c (TcpClose): Add timeouts to the close - these
- don't seem to be honored, however.
- Use a separate PB for the release, since an async connect socket
- will still be using the original buffer.
- Make sure TCPRelease returns noErr before freeing the recvBuff.
- If the call returns an error, then the buffer is not right.
- * mac/tclMacSock.c (CreateSocket): Add timeouts to the async
- create. These don't seem to trigger, however. Sigh...
+ sockets. It is still somewhat flakey, however.
+
+ * mac/tclMacSock.c (TcpClose): Add timeouts to the close - these don't
+ seem to be honored, however. Use a separate PB for the release, since
+ an async connect socket will still be using the original buffer. Make
+ sure TCPRelease returns noErr before freeing the recvBuff. If the call
+ returns an error, then the buffer is not right.
+ * mac/tclMacSock.c (CreateSocket): Add timeouts to the async create.
+ These don't seem to trigger, however. Sigh...
* mac/tclMacSock.c (WaitForSocketEvent): If an TCP_ASYNC_CONNECT
socket errors out, then return EWOULDBLOCK & error out.
* mac/tclMacSock.c (NotifyRoutine): Added a NotifyRoutine for
@@ -1662,20 +1630,20 @@
2000-04-21 Sandeep Tamhankar <sandeep@scriptics.com>
* library/http2.1/http.tcl: Fixed a newly introduced bug where if
- there's a -command callback and something goes wrong, geturl threw
- an exception, called the callback, and unset the token. I changed
- it so that it will not call the callback when throwing an
- exception (so the caller only finds out about a given error from
- one place). Also, fixed http::ncode so that it actually gives you
- back the http return code (i.e. 200, 404, etc.) instead of the
- first digit of the version of HTTP being used (i.e. 1).
+ there's a -command callback and something goes wrong, geturl threw an
+ exception, called the callback, and unset the token. I changed it so
+ that it will not call the callback when throwing an exception (so the
+ caller only finds out about a given error from one place). Also,
+ fixed http::ncode so that it actually gives you back the http return
+ code (i.e. 200, 404, etc.) instead of the first digit of the version
+ of HTTP being used (i.e. 1).
2000-04-21 Brent Welch <welch@scriptics.com>
* library/http2.1/http.tcl: More thrashing with the "server closes
- without reading post data" scenario. Reverted to the previous
- filevent configuratiuon, which seems to work better with small
- amounts of post data.
+ without reading post data" scenario. Reverted to the previous filevent
+ configuratiuon, which seems to work better with small amounts of post
+ data.
2000-04-20 Jeff Hobbs <hobbs@scriptics.com>
@@ -1688,15 +1656,15 @@
* library/dde1.1/pkgIndex.tcl:
* library/reg1.0/pkgIndex.tcl:
* win/tclWinChan.c:
- * win/tclWinThrd.c: converted CRLF to LF the */tcl.hpj.in files
- were not converted, as it confuses hcw locally. [Bug: 5096]
+ * win/tclWinThrd.c: converted CRLF to LF the */tcl.hpj.in files were
+ not converted, as it confuses hcw locally. [Bug: 5096]
* win/Makefile.in: expanded cleanup target for help files
* doc/Thread.3: minor macro cleanup
- * generic/tclFileName.c (SplitUnixPath): added support for QNX
- node ids.
+ * generic/tclFileName.c (SplitUnixPath): added support for QNX node
+ ids.
2000-04-18 Jeff Hobbs <hobbs@scriptics.com>
@@ -1716,9 +1684,8 @@
* unix/Makefile.in: added install-strip target; bindir, libdir,
mandir, includedir vars; tclLoadDyld.c target [Bug: 2527]
- * unix/tclUnixChan.c (CreateSocket): force a socket back into
- blocking mode (default state) after a -async connect succeeds.
- [Bug: 4388]
+ * unix/tclUnixChan.c (CreateSocket): force a socket back into blocking
+ mode (default state) after a -async connect succeeds. [Bug: 4388]
* generic/tclEvent.c (TclInitSubsystems): Moved tclLibraryPath to
thread-local storage to prevent thread-related race condition.
@@ -1732,23 +1699,23 @@
* win/Makefile.in:
* win/tcl.rc:
* win/tclsh.rc:
- * win/tclsh.ico: Modified copyright dates in Windows resource
- files. Added an icon for tclsh.exe.
+ * win/tclsh.ico: Modified copyright dates in Windows resource files.
+ Added an icon for tclsh.exe.
2000-04-17 Brent Welch <welch@scriptics.com>
* generic/tcl.h, generic/tclThreadTest.c, unix/tclUnixThrd.c,
- win/tclWinThread.c, mac/tclMacThread.c:
- Added Tcl_CreateThreadType and TCL_RETURN_THREAD_TYPE
- macros for declaring the NewThread callback proc.
+ * win/tclWinThread.c, mac/tclMacThread.c: Added Tcl_CreateThreadType
+ and TCL_RETURN_THREAD_TYPE macros for declaring the NewThread callback
+ proc.
2000-04-14 Jeff Hobbs <hobbs@scriptics.com>
* unix/tclUnixChan.c (TtyParseMode): Only allow setting mark/space
parity on platforms that support it [Bug: 5089]
- * generic/tclBasic.c (Tcl_GetVersion): adjusted use of major/minor
- to not conflict with global decl on some systems [Bug: 2882]
+ * generic/tclBasic.c (Tcl_GetVersion): adjusted use of major/minor to
+ not conflict with global decl on some systems [Bug: 2882]
* doc/AppInit.3:
* doc/Async.3:
@@ -1798,17 +1765,17 @@
* generic/tcl.h: Fixed Tcl_CreateThread declaration.
* library/tcltest1.0/tcltest.tcl: Fixed the "mainThread"
initialization to work with either testthread or the thread extension
- * unix/tclUnixThrd.c: Fixed compiler warning when compiling
- with -DTCL_THREADS
+ * unix/tclUnixThrd.c: Fixed compiler warning when compiling with
+ -DTCL_THREADS
2000-04-10 Eric Melski <ericm@scriptics.com>
- * win/tclWinPipe.c (TclpCreateTempFile): Added conversion of
- contents string from UTF to native encoding [Bug: 4030].
+ * win/tclWinPipe.c (TclpCreateTempFile): Added conversion of contents
+ string from UTF to native encoding [Bug: 4030].
* tests/regexp.test: Added tests for infinite looping in [regexp
-all].
-
+
* generic/tclCmdMZ.c: Fixed infinite loop bug with [regexp -all]
[Bug: 4981].
@@ -1817,14 +1784,13 @@
2000-04-09 Brent Welch <welch@scriptics.com>
- * lib/httpd2.1/http.tcl: Worked on the "server closes before
- reading post data" case, which unfortunately causes different
- error cases on Solaris, which can read the reply, and Linux
- and Windows, which cannot read anything. This is all in the
- loop-back case - client and server on the same host. Also
- unified the error handling so the "ioerror" status goes away
- and errors are reflected in a more uniform way. Updated the
- man page to document the behavior.
+ * lib/httpd2.1/http.tcl: Worked on the "server closes before reading
+ post data" case, which unfortunately causes different error cases on
+ Solaris, which can read the reply, and Linux and Windows, which cannot
+ read anything. This is all in the loop-back case - client and server
+ on the same host. Also unified the error handling so the "ioerror"
+ status goes away and errors are reflected in a more uniform way.
+ Updated the man page to document the behavior.
2000-04-09 Jeff Hobbs <hobbs@scriptics.com>
@@ -1834,70 +1800,68 @@
* generic/tclBasic.c (Tcl_SetCommandInfo): comment fix
* unix/tclUnixThrd.c (Tcl_CreateThread): moved TCL_THREADS ifdef
- inside of func as it is declared for non-threads builds as well.
- In the non-threads case, it always returns TCL_ERROR (couldn't
- create thread).
+ inside of func as it is declared for non-threads builds as well. In
+ the non-threads case, it always returns TCL_ERROR (couldn't create
+ thread).
2000-04-08 Andreas Kupries <a.kupries@westend.com>
* Overall change: Definition of a public API for the creation of
- new threads.
+ new threads.
* generic/tclInt.h (line 1802f): Removed the definition of
'TclpThreadCreate'. (line 793f) Removed the definition of
'Tcl_ThreadCreateProc'.
* generic/tcl.h (line 388f): Readded the definition of
- 'Tcl_ThreadCreateProc'. Added Win32 stuff send in by David
- Graveraux <davygrvy@bigfoot.com> to that too (__stdcall,
- ...). Added macros for the default stacksize and allowed flags.
+ 'Tcl_ThreadCreateProc'. Added Win32 stuff send in by David Graveraux
+ <davygrvy@bigfoot.com> to that too (__stdcall, ...). Added macros for
+ the default stacksize and allowed flags.
* generic/tcl.decls (line 1356f): Added definition of
- 'Tcl_CreateThread', slot 393 of the stub table. Two new
- arguments in the public API, for stacksize and flags.
+ 'Tcl_CreateThread', slot 393 of the stub table. Two new arguments in
+ the public API, for stacksize and flags.
* win/tclWinThrd.c:
* mac/tclMacThrd.c: Renamed TclpThreadCreate to Tcl_CreateThread,
- added handling of the stacksize. Flags are currently ignored.
+ added handling of the stacksize. Flags are currently ignored.
- * unix/tclUnixThrd.c: See above, but handles joinable
- flag. Ignores the specified stacksize if the macro
- HAVE_PTHREAD_ATTR_SETSTACKSIZE is not defined.
+ * unix/tclUnixThrd.c: See above, but handles joinable flag. Ignores
+ the specified stacksize if the macro HAVE_PTHREAD_ATTR_SETSTACKSIZE is
+ not defined.
* generic/tclThreadTest.c (line 363): See below.
- * unix/tclUnixNotfy.c (line 210): Adapted to the changes
- above. Uses default stacksize and no flags now.
+ * unix/tclUnixNotfy.c (line 210): Adapted to the changes above. Uses
+ default stacksize and no flags now.
* unic/tcl.m4 (line 382f): Added a check for
- 'pthread_attr_setstacksize' to detect platforms not implementing
- this feature of pthreads. If it is implemented, configure will
- define the macro HAVE_PTHREAD_ATTR_SETSTACKSIZE (See
- unix/tclUnixThrd.c too).
+ 'pthread_attr_setstacksize' to detect platforms not implementing this
+ feature of pthreads. If it is implemented, configure will define the
+ macro HAVE_PTHREAD_ATTR_SETSTACKSIZE (See unix/tclUnixThrd.c too).
- * doc/Thread.3: Added Tcl_CreateThread and its arguments to the
- list of described functions. Removed stuff about not providing a
- public C-API for thread-creation.
+ * doc/Thread.3: Added Tcl_CreateThread and its arguments to the list
+ of described functions. Removed stuff about not providing a public
+ C-API for thread-creation.
2000-04-07 Jeff Hobbs <hobbs@scriptics.com>
- * doc/binary.n: clarified docs on sign extension in binary scan
- [Bug: 3466]
+ * doc/binary.n: clarified docs on sign extension in binary scan [Bug:
+ 3466]
* library/tcltest1.0/tcltest.tcl (initConstraints): removed win32s
references (no longer supported)
- * tests/fCmd.test: marked test 8.1 knownBug because it is
- dangerous on poorly configured systems [Bug: 3881]
- and added 8.2 to keep essence of 8.1 tested.
+ * tests/fCmd.test: marked test 8.1 knownBug because it is dangerous on
+ poorly configured systems [Bug: 3881] and added 8.2 to keep essence of
+ 8.1 tested.
2000-04-05 Andreas Kupries <a.kupries@westend.com>
- * generic/tclIO.c (Tcl_UnstackChannel, line 1831): Forcing
- interest mask to the correct value after an unstack and
- re-initialization of the notifier via the watchProc. Without this
- the first fileevent after an unstack will come through and be
- processed, but no more. [Bug: ??].
+ * generic/tclIO.c (Tcl_UnstackChannel, line 1831): Forcing interest
+ mask to the correct value after an unstack and re-initialization of
+ the notifier via the watchProc. Without this the first fileevent after
+ an unstack will come through and be processed, but no more. [Bug: ??].
2000-03-04 Brent Welch <welch@scriptics.com>
@@ -1909,18 +1873,18 @@
2000-03-29 Sandeep Tamhankar <sandeep@scriptics.com>
- * library/http2.1/http.tcl: For the -querychannel option,
- fconfigure the socket to be binary so that we don't translate
- anything while reading the data. This is because we determine the
- content length of the data on the channel by using seek (to the end
- of the file) and tell on the file handle, and we need the
- content-length to match the amount of data actually sent, and
- translation can affect the number of bytes posted.
+ * library/http2.1/http.tcl: For the -querychannel option, fconfigure
+ the socket to be binary so that we don't translate anything while
+ reading the data. This is because we determine the content length of
+ the data on the channel by using seek (to the end of the file) and
+ tell on the file handle, and we need the content-length to match the
+ amount of data actually sent, and translation can affect the number of
+ bytes posted.
2000-04-03 Andreas Kupries <a.kupries@westend.com>
- * Overall change: Definition of public API's for the finalization
- of conditions and mutexes. [Bug: 4199].
+ * Overall change: Definition of public API's for the finalization of
+ conditions and mutexes. [Bug: 4199].
* generic/tclInt.h: Removed definitions of TclFinalizeMutex and
TclFinalizeCondition.
@@ -1928,27 +1892,26 @@
* generic/tcl.decls: Added declarations of Tcl_MutexFinalize and
Tcl_ConditionFinalize.
- * generic/tclThread.c: Renamed TclFinalizeMutex to
- Tcl_MutexFinalize. Renamed TclFinalizeCondition to
- Tcl_ConditionFinalize.
+ * generic/tclThread.c: Renamed TclFinalizeMutex to Tcl_MutexFinalize.
+ Renamed TclFinalizeCondition to Tcl_ConditionFinalize.
* generic/tclNotify.c: Changed usage of TclFinalizeMutex to
Tcl_MutexFinalize.
- * unix/tclUnixNotfy.c:
+ * unix/tclUnixNotfy.c:
* generic/tclThreadTest.c: Changed usages of TclFinalizeCondition to
Tcl_ConditionFinalize.
* generic/tcl.h: Added empty macros for Tcl_MutexFinalize and
- Tcl_ConditionFinalize, to be used when the core is compiled
- without threads.
+ Tcl_ConditionFinalize, to be used when the core is compiled without
+ threads.
* doc/Thread.3: Added description the new API's.
2000-04-03 Jeff Hobbs <hobbs@scriptics.com>
- * generic/tclCmdIL.c (InfoVarsCmd): checked for non-NULL procPtr
- to prevent itcl info override crash [Bug: 4064]
+ * generic/tclCmdIL.c (InfoVarsCmd): checked for non-NULL procPtr to
+ prevent itcl info override crash [Bug: 4064]
* tests/foreach.test:
* tests/namespace.test:
@@ -1967,27 +1930,27 @@
2000-04-03 Eric Melski <ericm@scriptics.com>
- * unix/tclUnixFCmd.c (SetGroupAttribute):
- * unix/tclUnixFCmd.c (SetOwnerAttribute): Added (uid_t) and (gid_t)
+ * unix/tclUnixFCmd.c (SetGroupAttribute):
+ * unix/tclUnixFCmd.c (SetOwnerAttribute): Added (uid_t) and (gid_t)
casts to avoid compiler warnings.
2000-03-31 Eric Melski <ericm@scriptics.com>
* generic/tclGet.c (Tcl_GetDouble): Added additional conditions to
- error test (previously only errno was checked, but the return
- value of strtod() should be checked as well). [Bug: 4118].
+ error test (previously only errno was checked, but the return value of
+ strtod() should be checked as well). [Bug: 4118]
- * tests/exec.test: Added test for proper conversion of UTF data
- when used with "<< $dataWithUTF" on exec's.
+ * tests/exec.test: Added test for proper conversion of UTF data when
+ used with "<< $dataWithUTF" on exec's.
* unix/tclUnixPipe.c (TclpCreateTempFile): Added
- Tcl_UtfToExternalDString call, so that if there is UTF content in
- the string it will be properly converted to the system encoding
- before being written [Bug: 4030].
+ Tcl_UtfToExternalDString call, so that if there is UTF content in the
+ string it will be properly converted to the system encoding before
+ being written [Bug: 4030].
(TclpCreateTempFile): Added a check on the return value of tmpnam;
some systems (Linux, for example) will start to return NULL after
- tmpnam has been called TMP_MAX times; not checking for this can
- have bad results (overwriting temp files, core dumps, etc.)
+ tmpnam has been called TMP_MAX times; not checking for this can have
+ bad results (overwriting temp files, core dumps, etc.)
2000-03-30 Jeff Hobbs <hobbs@scriptics.com>
@@ -2000,8 +1963,8 @@
* win/tclWin32Dll.c: removed TclWinSynchSpawn (vestige of Win32s
support).
- * win/tclWinReg.c: made use of TclWinGetPlatformId instead of
- getting info again
+ * win/tclWinReg.c: made use of TclWinGetPlatformId instead of getting
+ info again
* win/tclWinPort.h:
* win/Makefile.in:
@@ -2019,16 +1982,15 @@
2000-03-29 Sandeep Tamhankar <sandeep@scriptics.com>
- * library/http2.1/http.tcl: Removed an unnecessary fileevent
- statement from the error processing part of the Write method.
- Also, fixed two potential memory leaks in wait and reset, in which
- the state array wasn't being unset before throwing an exception.
- Prior to this version, Brent checked in a fix to catch a
- fileevent statement that was sometimes causing a stack trace when
- geturl was called with -timeout. I believe Brent's fix is
- necessary because TLS closes bad sockets for secure connections,
- and the fileevent was trying to act on a socket that no longer
- existed.
+ * library/http2.1/http.tcl: Removed an unnecessary fileevent statement
+ from the error processing part of the Write method. Also, fixed two
+ potential memory leaks in wait and reset, in which the state array
+ wasn't being unset before throwing an exception. Prior to this
+ version, Brent checked in a fix to catch a fileevent statement that
+ was sometimes causing a stack trace when geturl was called with
+ -timeout. I believe Brent's fix is necessary because TLS closes bad
+ sockets for secure connections, and the fileevent was trying to act on
+ a socket that no longer existed.
2000-03-27 Jeff Hobbs <hobbs@scriptics.com>
@@ -2036,118 +1998,115 @@
* tests/namespace.test:
* generic/tclNamesp.c (Tcl_Export): added a uniq'ing test to the
- export list so only one instance of each export pattern would
- exist in the list.
+ export list so only one instance of each export pattern would exist in
+ the list.
- * generic/tclExecute.c (TclExecuteByteCode): optimized case for
- the empty string in ==/!= comparisons
+ * generic/tclExecute.c (TclExecuteByteCode): optimized case for the
+ empty string in ==/!= comparisons
2000-03-27 Eric Melski <ericm@scriptics.com>
- * unix/tclUnixChan.c: Added (off_t) type casts in lseek() call
- [Bug: 4409].
+ * unix/tclUnixChan.c: Added (off_t) type casts in lseek() call [Bug:
+ 4409].
- * unix/tclLoadAout.c:
- * unix/tclUnixPipe.c: Added (off_t) type casts in lseek() calls
- [Bug: 4410].
+ * unix/tclLoadAout.c:
+ * unix/tclUnixPipe.c: Added (off_t) type casts in lseek() calls [Bug:
+ 4410].
2000-03-22 Sandeep Tamhankar <sandeep@scriptics.com>
- * library/http2.1/http.tcl: Fixed a bug where string query data
- that was bigger than queryblocksize would get duplicate characters
- at block boundaries.
+ * library/http2.1/http.tcl: Fixed a bug where string query data that
+ was bigger than queryblocksize would get duplicate characters at block
+ boundaries.
2000-03-22 Sandeep Tamhankar <sandeep@scriptics.com>
- * library/http2.1/http.tcl: Fixed bug 4463, where we were getting
- a stack trace if we tried to publish a project to a good host but
- a port where there was no server listening. It turned out the
- problem was a stray fileevent that needed to be cleared. Also,
- fixed a bug where http::code could stack trace if called on a bad
- token (one which didn't represent a successful geturl) by adding
- an http element to the state array in geturl.
+ * library/http2.1/http.tcl: Fixed bug 4463, where we were getting a
+ stack trace if we tried to publish a project to a good host but a port
+ where there was no server listening. It turned out the problem was a
+ stray fileevent that needed to be cleared. Also, fixed a bug where
+ http::code could stack trace if called on a bad token (one which
+ didn't represent a successful geturl) by adding an http element to the
+ state array in geturl.
2000-03-21 Eric Melski <ericm@scriptics.com>
* tests/clock.test: Modified some tests that were not robust with
- respect to the time zone in which they were run and were thus
- failing.
+ respect to the time zone in which they were run and were thus failing.
- * doc/clock.n: Clarified meaning of -gmt with respect to -base
- when used with [clock scan] (-gmt does not affect the
- interpretation of -base).
+ * doc/clock.n: Clarified meaning of -gmt with respect to -base when
+ used with [clock scan] (-gmt does not affect the interpretation of
+ -base).
2000-03-19 Sandeep Tamhankar <sandeep@scriptics.com>
- * library/http2.1/http.tcl: geturl used to throw an exception when
- the connection failed; I accidentally returned a token with the
- error info, breaking backwards compatibility. I changed it back
- to throwing an exception, but unsetting the state array first
- (thus still eliminating the original memory leak problem).
+ * library/http2.1/http.tcl: geturl used to throw an exception when the
+ connection failed; I accidentally returned a token with the error
+ info, breaking backwards compatibility. I changed it back to throwing
+ an exception, but unsetting the state array first (thus still
+ eliminating the original memory leak problem).
2000-03-19 Sandeep Tamhankar <sandeep@scriptics.com>
* library/http2.1/http.tcl: Added -querychannel option and altered
some of Brent's modifications to allow asynchronous posts (via
- -command). Also modified -queryprogress so that it calls the
- query callback as <callback> <token> <total size> <current size>
- to be consistent with -progress. Added -queryblocksize option
- with default 8192 bytes for post blocksize. Fixed a bunch of
- potential memory leaks for the case when geturl receives bad args
- or can't open a socket, etc. Overall, the package really rocks
- now.
+ -command). Also modified -queryprogress so that it calls the query
+ callback as <callback> <token> <total size> <current size> to be
+ consistent with -progress. Added -queryblocksize option with default
+ 8192 bytes for post blocksize. Fixed a bunch of potential memory leaks
+ for the case when geturl receives bad args or can't open a socket,
+ etc. Overall, the package really rocks now.
* doc/http.n: Added -queryblocksize, -querychannel, and
- -queryprogress. Also, changed the description of -blocksize,
- which states that the -progress callback will be called for each
- block, to now qualify that with an "if -progress is specified".
+ -queryprogress. Also, changed the description of -blocksize, which
+ states that the -progress callback will be called for each block, to
+ now qualify that with an "if -progress is specified".
* tests/http.test: Added a querychannel test for synchronous and
asynchronous posts, altered the queryprogress test such that the
- callback conforms to the -progress format. Also, had to use the
- -queryblocksize option to do the post 16K at a time to match
- Brent's expected results (and to test that -queryblocksize works).
+ callback conforms to the -progress format. Also, had to use the
+ -queryblocksize option to do the post 16K at a time to match Brent's
+ expected results (and to test that -queryblocksize works).
2000-03-15 Brent Welch <welch@scriptics.com>
* library/http2.1/http.tcl: Added -queryprogress callback to
- http::geturl and also changed it so that writing the post data
- is event driven if the queryprogress callback or a timeout is given.
- This allows a timeout to occur when writing lots of post data.
- The queryprogress callback is called after each block of query
- data is posted. It has the same signature as the -progress callback.
+ http::geturl and also changed it so that writing the post data is
+ event driven if the queryprogress callback or a timeout is given.
+ This allows a timeout to occur when writing lots of post data. The
+ queryprogress callback is called after each block of query data is
+ posted. It has the same signature as the -progress callback.
2000-03-06 Eric Melski <ericm@scriptics.com>
* library/package.tcl: Applied patch from Bug: 2570; rather than
setting geometry of slave interp to 0x0 when Tk was loaded, it now
- does "wm withdraw .". Both remove the main window from the
- display, but the former caused some internal structures to get
- initialized to zero, which caused crashes with some extensions.
+ does "wm withdraw .". Both remove the main window from the display,
+ but the former caused some internal structures to get initialized to
+ zero, which caused crashes with some extensions.
2000-03-02 Jeff Hobbs <hobbs@scriptics.com>
- * library/package.tcl (tclPkgUnknown): extended to allow
- recognizes changes in the auto_path while sourcing in other
- pkgIndex.tcl files
+ * library/package.tcl (tclPkgUnknown): extended to allow recognizes
+ changes in the auto_path while sourcing in other pkgIndex.tcl files
* doc/FindExec.3: fixed doc for declaration of Tcl_FindExecutable
[Bug: 4275]
- * generic/tclFileName.c (Tcl_TranslateFileName): Applied patch
- from Newman to significantly speedup file split/join on Windows
- (replaces regexp with custom parser). [Bug: 2867]
+ * generic/tclFileName.c (Tcl_TranslateFileName): Applied patch from
+ Newman to significantly speedup file split/join on Windows (replaces
+ regexp with custom parser). [Bug: 2867]
- * win/README.binary: change mailing lists from @consortium.org
- to @scriptics.com [Bug: 4173]
+ * win/README.binary: change mailing lists from @consortium.org to
+ @scriptics.com [Bug: 4173]
2000-02-28 Eric Melski <ericm@scriptics.com>
* tests/clock.test: Added test for ISO bases < 100000
* generic/tclDate.c: (generated on Solaris)
- * generic/tclGetDate.y: Changed condition for deciding if a number
- is an ISO 8601 base from number >= 100000 to numberOfDigits >= 6.
+ * generic/tclGetDate.y: Changed condition for deciding if a number is
+ an ISO 8601 base from number >= 100000 to numberOfDigits >= 6.
Previously it would fail to recognize 000000 as an ISO base.
2000-02-14 Eric Melski <ericm@scriptics.com>
@@ -2166,42 +2125,41 @@
* doc/load.n: added notes about dll load errors on Windows
* unix/README:
- * unix/Makefile.in (dist): removed porting.notes and porting.old
- from distribution and CVS. The information was very outdated. Now
- refer to http://dev.scriptics.com/services/support/platforms.html
+ * unix/Makefile.in (dist): removed porting.notes and porting.old from
+ distribution and CVS. The information was very outdated. Now refer to
+ http://dev.scriptics.com/services/support/platforms.html
* tests/unixInit.test: fixed japanese LANG encoding test [Bug: 3549]
* unix/configure.in:
- * unix/tcl.m4: correct CFLAG_WARNING setting,
- fixed gcc config for AIX,
- added -export-dynamic to LDFLAGS for FreeBSD-3+ [Bug: 2998]
+ * unix/tcl.m4: correct CFLAG_WARNING setting, fixed gcc config for
+ AIX, added -export-dynamic to LDFLAGS for FreeBSD-3+ [Bug: 2998]
* win/tclWinLoad.c (TclpLoadFile): improved error message for load
failures, could perhaps be even more intelligent.
2000-02-09 Jim Ingham <jingham@cygnus.com>
- * mac/tclMacSock.c: Don't panic when you get an error closing an async
- socket. This doesn't seem to hurt anything, and we return the error so
+ * mac/tclMacSock.c: Don't panic when you get an error closing an async
+ socket. This doesn't seem to hurt anything, and we return the error so
the caller can do the right thing.
New Files:
* mac/MW_TclHeader.h:
* mac/MW_TclTestHeader.h:
* mac/MW_TclTestHeader.pch:
- * mac/MW_TclAppleScriptHeader.h: More convenient to use .h prefix files
- in the preference panels...
+ * mac/MW_TclAppleScriptHeader.h: More convenient to use .h prefix
+ files in the preference panels...
The above are curtesy of Daniel Steffen (steffen@math.mq.edu.au)
2000-02-08 Eric Melski <ericm@scriptics.com>
* tests/clock.test: Added tests for "next monthname" constructs.
- * generic/tclDate.c:
+ * generic/tclDate.c:
* generic/tclGetDate.y (Message): Added a grammar rule for "next
- monthname" so that we can handle "next january" and similar
- constructs (bug #4146).
+ monthname" so that we can handle "next january" and similar constructs
+ (bug #4146).
2000-02-08 Jeff Hobbs <hobbs@scriptics.com>
@@ -2228,35 +2186,35 @@
* tests/httpold.test: changed test script to source in the httpd
server procs from httpd instead of having its own set.
- * tests/httpd: improved query support in test httpd to handle fix
- in http.tcl. [Bug: 4089 change 2000-02-01]
+ * tests/httpd: improved query support in test httpd to handle fix in
+ http.tcl. [Bug: 4089 change 2000-02-01]
- * unix/README: fixed notes about --enable-shared and add note
- about --disable-shared.
+ * unix/README: fixed notes about --enable-shared and add note about
+ --disable-shared.
2000-02-07 Eric Melski <ericm@scriptics.com>
- * tests/package.test:
- * library/tclIndex:
+ * tests/package.test:
+ * library/tclIndex:
* library/package.tcl: Renamed ::package namespace to ::pkg.
2000-02-03 Eric Melski <ericm@scriptics.com>
* doc/Package.n:
- * doc/packagens.n: Renamed Package.n -> packagens.n because Windows
+ * doc/packagens.n: Renamed Package.n -> packagens.n because Windows
can't deal with case-sensitive names.
2000-02-02 Jeff Hobbs <hobbs@scriptics.com>
* tests/regexp.test: added tests for -all and -inline switches
* doc/regexp.n: added docs for -all and -inline switches
- * generic/tclCmdMZ.c (Tcl_RegexpObjCmd): added extra comments for
- new -all and -inline switches to regexp command
+ * generic/tclCmdMZ.c (Tcl_RegexpObjCmd): added extra comments for new
+ -all and -inline switches to regexp command
2000-02-01 Eric Melski <ericm@scriptics.com>
- * library/init.tcl: Applied patch from rfe 1734 regarding
- auto_load errors not setting error message and errorInfo properly.
+ * library/init.tcl: Applied patch from rfe 1734 regarding auto_load
+ errors not setting error message and errorInfo properly.
2000-02-01 Jeff Hobbs <hobbs@scriptics.com>
@@ -2271,13 +2229,13 @@
2000-01-31 Eric Melski <ericm@scriptics.com>
- * tests/package.test:
- * library/tclIndex:
- * library/package.tcl: Added ::package namespace and
- ::package::create function.
+ * tests/package.test:
+ * library/tclIndex:
+ * library/package.tcl: Added ::package namespace and ::package::create
+ function.
- * library/init.tcl: Fixed problem with auto_load and determining
- if commands were loaded.
+ * library/init.tcl: Fixed problem with auto_load and determining if
+ commands were loaded.
* library/auto.tcl: "Fixed" issues with $ in files to be auto indexed.
@@ -2289,66 +2247,66 @@
2000-01-28 Eric Melski <ericm@scriptics.com>
- * tests/pkg/magicchar2.tcl:
+ * tests/pkg/magicchar2.tcl:
* tests/autoMkindex.test: Test for auto loader fix (bug #2480).
* library/init.tcl: auto_load was using [info commands $name] to
- determine if a given command was available; if the command name
- had * or [] it, this would fail because info commands uses
- glob-style matching. This is fixed. (Bug #2480).
+ determine if a given command was available; if the command name had *
+ or [] it, this would fail because info commands uses glob-style
+ matching. This is fixed. (Bug #2480).
- * tests/pkg/spacename.tcl:
+ * tests/pkg/spacename.tcl:
* tests/pkgMkIndex.test: Tests for fix for bug #2360.
- * library/package.tcl: Fixed to extract only the first element of
- the list returned by auto_qualify (bug #2360).
+ * library/package.tcl: Fixed to extract only the first element of the
+ list returned by auto_qualify (bug #2360).
- * tests/pkg/magicchar.tcl:
+ * tests/pkg/magicchar.tcl:
* tests/autoMkindex.test: Test for fix for bug #2611.
* library/auto.tcl: Fixed the regular expression that performs $
- escaping before sourcing a file to index. It was erroneously
- adding \ escapes even to $'s that were already escaped,
- effectively "un-escaping" those $'s. (bug #2611).
+ escaping before sourcing a file to index. It was erroneously adding \
+ escapes even to $'s that were already escaped, effectively
+ "un-escaping" those $'s. (bug #2611).
2000-01-27 Eric Melski <ericm@scriptics.com>
- * tests/autoMkindex.test:
- * library/auto.tcl: Applied patch (with slight modification) from
- bug #2701: auto_mkIndex uses platform dependent file paths.
- Added test for fix.
+ * tests/autoMkindex.test:
+ * library/auto.tcl: Applied patch (with slight modification) from bug
+ #2701: auto_mkIndex uses platform dependent file paths. Added test for
+ fix.
2000-01-27 Jennifer Hom <jenn@scriptics.com>
* library/tcltest1.0/tcltest.tcl: Changed NormalizePath to
- normalizePath and exported it as a public proc. This proc
- creates an absolute path given the name of the variable containing
- the path to modify. The path is modified in place.
+ normalizePath and exported it as a public proc. This proc creates an
+ absolute path given the name of the variable containing the path to
+ modify. The path is modified in place.
* library/tcltest1.0/pkgIndex.tcl: Added normalizePath.
* tests/all.tcl: Changed code to use normalizePath.
2000-01-27 Eric Melski <ericm@scriptics.com>
* tests/pkg/samename.tcl: test file for bug #1983
-
- * tests/pkgMkIndex.test:
- * doc/pkgMkIndex.n:
+
+ * tests/pkgMkIndex.test:
+ * doc/pkgMkIndex.n:
* library/package.tcl: Per rfe #4097, optimized creation of direct
- load packages to bypass computing the list of commands added by
- the new package. Also made direct loading the default, and added
- a -lazy option.
+ load packages to bypass computing the list of commands added by the
+ new package. Also made direct loading the default, and added a -lazy
+ option.
Fixed bug #1983, dealing with pkg_mkIndex incorrectly handling
- situations with two procs by the same name but in different
- namespaces (ie, foo::baz and bar::baz).
+ situations with two procs by the same name but in different namespaces
+ (ie, foo::baz and bar::baz).
2000-01-26 Eric Melski <ericm@scriptics.com>
* generic/tclNamesp.c: Undid fix for #956, which broke backwards
compatibility.
- * doc/variable.n:
- * doc/trace.n:
- * doc/namespace.n:
+ * doc/variable.n:
+ * doc/trace.n:
+ * doc/namespace.n:
* doc/info.n: Added further information about differences between
"namespace which" and "info exists".
@@ -2357,18 +2315,18 @@
2000-01-25 Jeff Hobbs <hobbs@scriptics.com>
- * unix/tcl.m4: modified EXTRA_CFLAGS to add -DHAVE_TZSET for
- OSF1-V* and ULTRIX-4.* when not using gcc. Also added higher min
- stack size for OSF1-V* when building with threads. [Bug: 4063]
+ * unix/tcl.m4: modified EXTRA_CFLAGS to add -DHAVE_TZSET for OSF1-V*
+ and ULTRIX-4.* when not using gcc. Also added higher min stack size
+ for OSF1-V* when building with threads. [Bug: 4063]
* generic/tclClock.c (FormatClock): inlined resultPtr, as it
conflicted with var creation for HAVE_TZSET #def [Bug: 4063]
- * generic/tclCmdIL.c (Tcl_LsortObjCmd): fixed potential leak
- when calling lsort -command with bad command [Bug: 4067]
+ * generic/tclCmdIL.c (Tcl_LsortObjCmd): fixed potential leak when
+ calling lsort -command with bad command [Bug: 4067]
- * generic/tclFileName.c (Tcl_JoinPath): added support for special
- QNX node id prefixes in pathnames [Bug: 4053]
+ * generic/tclFileName.c (Tcl_JoinPath): added support for special QNX
+ node id prefixes in pathnames [Bug: 4053]
* doc/ListObj.3: clarified Tcl_ListObjGetElements docs [Bug: 4080]
@@ -2378,18 +2336,18 @@
2000-01-23 Jeff Hobbs <hobbs@scriptics.com>
- * library/init.tcl (auto_execok): added 'start' to list of
- recognized built-in commands for COMSPEC on NT. [Bug: 2858]
+ * library/init.tcl (auto_execok): added 'start' to list of recognized
+ built-in commands for COMSPEC on NT. [Bug: 2858]
* unix/tclUnixPort.h: moved include of <utime.h> lower since some
systems (UTS) require sys/types.h to be included first [Bug: 4031]
- * unix/tclUnixChan.c (CreateSocketAddress): changed comparison
- with -1 to 0xFFFFFFFF, to ensure 32 bit comparison even on 64 bit
- systems. [Bug: 3878]
+ * unix/tclUnixChan.c (CreateSocketAddress): changed comparison with -1
+ to 0xFFFFFFFF, to ensure 32 bit comparison even on 64 bit systems.
+ [Bug: 3878]
- * generic/tclFileName.c: improved guessing of path separator
- for the Mac. (Darley)
+ * generic/tclFileName.c: improved guessing of path separator for the
+ Mac. (Darley)
* generic/tclInt.h:
* generic/tcl.decls: moved Tcl_ProcObjCmd to stubs table [Bug: 3827]
@@ -2398,7 +2356,7 @@
2000-01-21 Eric Melski <ericm@scriptics.com>
- * unix/mkLinks:
+ * unix/mkLinks:
* doc/GetHostName.3: Man page for Tcl_GetHostName (bug #1817).
* doc/lreplace.n: Corrected man page with respect to treatment of
@@ -2412,24 +2370,24 @@
* generic/tclNamesp.c: Added check for undefined variables in
NamespaceWhichCmd (bug #956).
- * tests/var.test: Added tests for corrected variable behavior
- (bug #981).
+ * tests/var.test: Added tests for corrected variable behavior (bug
+ #981).
* doc/upvar.n: Expanded explanation of upvar behavior with respect to
- variable traces. (bugs 3917 1433 2110).
+ variable traces. (bugs 3917 1433 2110).
* generic/tclVar.c: Changed behavior of variable command when name
refers to an element in an array (ie, "variable foo(x)") to always
- return an error, regardless of existance of that element in the
- array (now behavior is consistant with docs too) (bug #981).
+ return an error, regardless of existance of that element in the array
+ (now behavior is consistant with docs too) (bug #981).
2000-01-20 Jeff Hobbs <hobbs@scriptics.com>
- * generic/tclCmdIL.c (InfoBodyCmd): made [info body] return a
- string if the body has been bytecompiled.
+ * generic/tclCmdIL.c (InfoBodyCmd): made [info body] return a string
+ if the body has been bytecompiled.
* generic/tclBasic.c (Tcl_EvalObjEx): added pedantic check for
- originating proc body of bytecompiled code, #def'd out as the
- change for [info body] should make it unnecessary
+ originating proc body of bytecompiled code, #def'd out as the change
+ for [info body] should make it unnecessary
* unix/tclUnixNotfy.c (Tcl_InitNotifier): added cast for tsdPtr
@@ -2442,20 +2400,19 @@
* doc/vwait.n: added notes about requirement for vwait var being
globally scoped [Bug: 3329]
- * library/word.tcl: changed tcl_(non)wordchars settings to use
- new unicode regexp char class escapes instead of char sequences
+ * library/word.tcl: changed tcl_(non)wordchars settings to use new
+ unicode regexp char class escapes instead of char sequences
2000-01-14 Eric Melski <ericm@scriptics.com>
* tests/var.test: Added a test for the array multiple delete
protection in Tcl_UnsetVar2.
- * generic/tclVar.c: Added protection in Tcl_UnsetVar2 against
- attempts to multiply delete arrays when unsetting them (bug
- #3453). This could happen if there was an unset trace on an array
- element and the trace proc made a global or upvar link to the
- array, and then the array was unset at the global level. See the
- bug reference for more information.
+ * generic/tclVar.c: Added protection in Tcl_UnsetVar2 against attempts
+ to multiply delete arrays when unsetting them (bug #3453). This could
+ happen if there was an unset trace on an array element and the trace
+ proc made a global or upvar link to the array, and then the array was
+ unset at the global level. See the bug reference for more information.
* unix/tclUnixTime.c: New clock format format.
@@ -2480,14 +2437,14 @@
2000-01-13 Eric Melski <ericm@scriptics.com>
- * tests/cmdIL.test: Added tests for lsort -dictionary with
- characters that occur between Z and a in ASCII.
+ * tests/cmdIL.test: Added tests for lsort -dictionary with characters
+ that occur between Z and a in ASCII.
* generic/tclCmdIL.c: Modified DictionaryCompare function (used by
lsort -dictionary) to do upper/lower case equivalency before doing
- character comparisons, instead of after. This fixes bug #1357, in
- which lsort -dictionary [list ` AA c CC] and lsort -dictionary
- [list AA c ` CC] gave different (and both wrong) results.
+ character comparisons, instead of after. This fixes bug #1357, in
+ which lsort -dictionary [list ` AA c CC] and lsort -dictionary [list
+ AA c ` CC] gave different (and both wrong) results.
2000-01-12 Eric Melski <ericm@scriptics.com>
@@ -2497,23 +2454,22 @@
* doc/tests/clock.test: Added numerous tests for clock scan.
- * doc/generic/tclGetDate.y: Fixed some shift/reduce conflicts in
- clock grammar.
+ * doc/generic/tclGetDate.y: Fixed some shift/reduce conflicts in clock
+ grammar.
- * doc/doc/clock.n: Added documentation for new supported clock
- scan formats and additional explanation of daylight savings time
- correction algorithm.
+ * doc/doc/clock.n: Added documentation for new supported clock scan
+ formats and additional explanation of daylight savings time correction
+ algorithm.
2000-01-12 Jeff Hobbs <hobbs@scriptics.com>
* doc/file.n:
* tests/unixFCmd.test:
- * unix/tclUnixFCmd.c: added support for symbolic permissions
- setting in SetPermissionsAttribute (file attr $file -perm ...)
- [Bug: 3970]
+ * unix/tclUnixFCmd.c: added support for symbolic permissions setting
+ in SetPermissionsAttribute (file attr $file -perm ...) [Bug: 3970]
- * generic/tclClock.c: fixed support for 64bit handling of clock
- values [Bug: 1806]
+ * generic/tclClock.c: fixed support for 64bit handling of clock values
+ [Bug: 1806]
* generic/tclThreadTest.c: upped a buffer size to hold double
@@ -2526,20 +2482,20 @@
* tests/expr.test:
* unix/Makefile.in:
* unix/configure.in:
- * unix/tcl.m4: recognize strtod bug on Tru64 v5.0 [Bug: 3378]
- and added tests to prevent unnecessary chmod +x in sources while
+ * unix/tcl.m4: recognize strtod bug on Tru64 v5.0 [Bug: 3378] and
+ added tests to prevent unnecessary chmod +x in sources while
installing, as well as more intelligent setsockopt/gethostbyname
checks [Bug: 3366, 3389]
- * unix/tclUnixThrd.c: added compile time support (through use of
- the TCL_THREAD_STACK_MIN define) for increasing the default stack
- size for a thread. [Bug: 3797, 1966]
+ * unix/tclUnixThrd.c: added compile time support (through use of the
+ TCL_THREAD_STACK_MIN define) for increasing the default stack size for
+ a thread. [Bug: 3797, 1966]
2000-01-11 Eric Melski <ericm@scriptics.com>
- * generic/tclGetDate.y: Added comments for the Convert function.
- Added a fix for daylight savings time handling for relative time
- spans of days, weeks or fortnights. (bug 3441, 3868).
+ * generic/tclGetDate.y: Added comments for the Convert function. Added
+ a fix for daylight savings time handling for relative time spans of
+ days, weeks or fortnights. (bug 3441, 3868).
* generic/tclDate.c: Fixed compiler warning issues.
@@ -2548,8 +2504,8 @@
* compat/waitpid.c: use pid_t type instead of int [Bug: 3999]
* tests/utf.test: fixed test that allowed \8 as octal value
- * generic/tclUtf.c: changed Tcl_UtfBackslash to not allow
- non-octal digits (8,9) in \ooo substs. [Bug: 3975]
+ * generic/tclUtf.c: changed Tcl_UtfBackslash to not allow non-octal
+ digits (8,9) in \ooo substs. [Bug: 3975]
* generic/tcl.h: noted need to change win/tcl.m4 and
tools/tclSplash.bmp for minor version changes
@@ -2579,5 +2535,5 @@
2000-01-07 Eric Melski <ericm@scriptics.com>
* generic/tclClock.c: Changed switch in Tcl_ClockObjCmd to use
- enumerated values instead of constants. (ie, COMMAND_SCAN instead
- of 3).
+ enumerated values instead of constants. (ie, COMMAND_SCAN instead of
+ 3).
diff --git a/ChangeLog.2001 b/ChangeLog.2001
index 2c8b4d7..6579651 100644
--- a/ChangeLog.2001
+++ b/ChangeLog.2001
@@ -1,20 +1,20 @@
2001-12-28 Jeff Hobbs <jeffh@ActiveState.com>
- * library/init.tcl: make sure env(COMSPEC) on Windows is executed
- with the right case, as it may otherwise fail inexplicably.
+ * library/init.tcl: make sure env(COMSPEC) on Windows is executed with
+ the right case, as it may otherwise fail inexplicably.
2001-12-28 Don Porter <dgp@users.sourceforge.net>
- * generic/tclCkalloc.c (MemoryCmd, TclFinalizeMemorySubsystem):
- Added the [memory onexit] command, intended to replace [checkmem].
+ * generic/tclCkalloc.c (MemoryCmd, TclFinalizeMemorySubsystem): Added
+ the [memory onexit] command, intended to replace [checkmem].
- * doc/DumpActiveMemory.3:
+ * doc/DumpActiveMemory.3:
* doc/memory.n: Updated documentation for [memory] and related
- matters. [Bug 487677]
+ matters. [Bug 487677]
* mac/tclMacBOAMain.c (Tcl_Main, CheckmemCmd): Removed all the
- machinery for the [checkmem] command that is completely duplicated
- by code in generic/tclCkalloc.c.
+ machinery for the [checkmem] command that is completely duplicated by
+ code in generic/tclCkalloc.c.
* generic/tclBinary.c:
* generic/tclListObj.c:
@@ -27,12 +27,11 @@
* mac/tclMacInit.c:
* mac/tclMacTclCode.r: synced up tclInit features to unix/win:
- implemented TclSetPreInitScript support, use of existing tclInit
- proc if defined, check of default encoding dir if set. Changed
- script library resource names to lowercase (i.e. same as
- corresponding files). Used Tcl_JoinPath instead of string append.
- Check that system encoding could be loaded before utf translating
- the LibraryPath.
+ implemented TclSetPreInitScript support, use of existing tclInit proc
+ if defined, check of default encoding dir if set. Changed script
+ library resource names to lowercase (i.e. same as corresponding
+ files). Used Tcl_JoinPath instead of string append. Check that system
+ encoding could be loaded before utf translating the LibraryPath.
* mac/tclMacApplication.r:
* mac/tclMacLibrary.r:
* mac/tclMacOSA.r:
@@ -41,147 +40,138 @@
2001-12-21 Mo DeJong <mdejong@users.sourceforge.net>
* unix/tcl.m4 (SC_PATH_TCLCONFIG, SC_PATH_TKCONFIG):
- Search for config file using exec_prefix instead of
- prefix when no --with-tcl or --with-tk argument is used. [Bug 492418]
+ Search for config file using exec_prefix instead of prefix when no
+ --with-tcl or --with-tk argument is used. [Bug 492418]
2001-12-21 Daniel Steffen <das@users.sourceforge.net>
- * unix/tcl.m4: fixed incorrect SHLIB_LD_LIBS
- setting for MacOSX / Darwin.
+ * unix/tcl.m4: fixed incorrect SHLIB_LD_LIBS setting for MacOSX /
+ Darwin.
* unix/configure: Regen.
- * unix/mkLinks.tcl: improved case-insensitive
- filesystem support.
+ * unix/mkLinks.tcl: improved case-insensitive filesystem support.
* unix/mkLinks: Regen.
2001-12-19 Don Porter <dgp@users.sourceforge.net>
- * unix/Makefile.in (dist): corrected use of eolFix.tcl on
- working files. It should operate on distributed files. [Bug 495120]
+ * unix/Makefile.in (dist): corrected use of eolFix.tcl on working
+ files. It should operate on distributed files. [Bug 495120]
2001-12-19 David Gravereaux <davygrvy@pobox.com>
- * tools/tcl.wse.in: Fix for #495120. tcl.wse.in was
- stored in cvs with improper <eol>. This resulted in
- corrupted <eol> when checked-out on translating CVS
- clients such as windows (CRCRLF) and mac (CRCR).
+ * tools/tcl.wse.in: Fix for [Bug 495120]. tcl.wse.in was stored in cvs
+ with improper <eol>. This resulted in corrupted <eol> when checked-out
+ on translating CVS clients such as windows (CRCRLF) and mac (CRCR).
2001-12-19 Mo DeJong <mdejong@users.sourceforge.net>
* unix/configure:
- * unix/tcl.m4 (SC_CONFIG_CFLAGS): Update
- SunOS 5.[0-6] target so that correct linker
- options are passed to gcc or ld. [Tk Bug 220863]
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): Update SunOS 5.[0-6] target so that
+ correct linker options are passed to gcc or ld. [Tk Bug 220863]
2001-12-19 Mo DeJong <mdejong@users.sourceforge.net>
- * unix/README: Update to account for changes
- in the unix/dltest directory, the way autoconf
- is run, and the new "make shell" target.
+ * unix/README: Update to account for changes in the unix/dltest
+ directory, the way autoconf is run, and the new "make shell" target.
2001-12-19 Mo DeJong <mdejong@users.sourceforge.net>
- * unix/Makefile.in: Rename dltest to dlpkgs to
- fix problem where lib files were not getting
- built because dltest/ directory already existed.
+ * unix/Makefile.in: Rename dltest to dlpkgs to fix problem where lib
+ files were not getting built because dltest/ directory already
+ existed.
2001-12-19 Jeff Hobbs <jeffh@ActiveState.com>
- * win/tclWinSerial.c (SerialCheckProc): corrected time
- calculations to be unsigned. (schroedter)
+ * win/tclWinSerial.c (SerialCheckProc): corrected time calculations to
+ be unsigned. (schroedter)
2001-12-18 Mo DeJong <mdejong@users.sourceforge.net>
- * unix/Makefile.in: Define new dltest target that
- simply does a cd to dltest/ before running make.
- There is no need for the separate configure
- script that was previously being used.
+ * unix/Makefile.in: Define new dltest target that simply does a cd to
+ dltest/ before running make. There is no need for the separate
+ configure script that was previously being used.
* unix/configure: Regen.
* unix/configure.in: Subst into dltest/Makefile.
- * unix/dltest/Makefile.in: Define LIBS using
- DL_LIBS, LIBS, and MATH_LIBS variables instead
- of TCL_LIBS variable from tclConfig.sh.
- * unix/dltest/README: Update readme to account for new
- configure free implementation.
+ * unix/dltest/Makefile.in: Define LIBS using DL_LIBS, LIBS, and
+ MATH_LIBS variables instead of TCL_LIBS variable from tclConfig.sh.
+ * unix/dltest/README: Update readme to account for new configure free
+ implementation.
* unix/dltest/configure: Removed.
* unix/dltest/configure.in: Removed.
2001-12-18 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * generic/tcl.h (TCL_STUB_MAGIC): Added cast to force type to be
- an int and get rid of a persistent and pointless warning with
- SunPro compiler.
+ * generic/tcl.h (TCL_STUB_MAGIC): Added cast to force type to be an
+ int and get rid of a persistent and pointless warning with SunPro
+ compiler.
- * generic/tclCkalloc.c (Tcl_AttemptDbCkalloc,Tcl_AttemptDbCkrealloc):
+ * generic/tclCkalloc.c (Tcl_AttemptDbCkalloc,Tcl_AttemptDbCkrealloc):
* generic/tcl.decls (Tcl_AttemptDbCkalloc,Tcl_AttemptDbCkrealloc):
- Made the file parameters to these functions into CONST char *,
- like they always should have been to match the other Tcl*Db* API
- functions.
+ Made the file parameters to these functions into CONST char *, like
+ they always should have been to match the other Tcl*Db* API functions.
-2001-12-17 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+2001-12-17 Andreas Kupries <andreas_kupries@users.sourceforge.net>
- * Applied #219311 on behalf of Rolf Schroedter
- <schroedter@users.sourceforge.net> to prevent fcopy on serial
- ports from flooding the event queue.
+ * Applied [Bug 219311] on behalf of Rolf Schroedter
+ <schroedter@users.sourceforge.net> to prevent fcopy on serial ports
+ from flooding the event queue.
2001-12-11 Miguel Sofer <msofer@users.sourceforge.net>
* doc/CrtInterp.3:
- * generic/tclBasic.c: docs and comments corrections [Bug 493412]
- Bug & patch by Don Porter.
+ * generic/tclBasic.c: docs and comments corrections. [Bug 493412]
+ Bug & patch by Don Porter.
2001-12-14 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * win/tclWinNotify.c (Tcl_FinalizeNotifier): Stop Tcl on Windows
- from crashing when shutdown from a non-Tcl thread. Fixes Bug
- #217982 [orig. 5804] reported by Hugh Vu and Gene Leache. I'm
- not convinced that the shutdown process is right even with this,
- but it was definitely wrong without...
+ * win/tclWinNotify.c (Tcl_FinalizeNotifier): Stop Tcl on Windows from
+ crashing when shutdown from a non-Tcl thread. Fixes [Bug 217982]
+ [orig. 5804] reported by Hugh Vu and Gene Leache. I'm not convinced
+ that the shutdown process is right even with this, but it was
+ definitely wrong without...
-2001-12-13 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+2001-12-13 Andreas Kupries <andreas_kupries@users.sourceforge.net>
- * win/tclWinSock.c (TcpGetOptionProc): Fix for tcl bug item
- #478565 reported by an unknown person. Bypasses all calls to
- "gethostbyaddr" for address "0.0.0.0" to prevent delays on
- Win/NT.
+ * win/tclWinSock.c (TcpGetOptionProc): Fix for [Bug 478565] reported
+ by an unknown person. Bypasses all calls to "gethostbyaddr" for
+ address "0.0.0.0" to prevent delays on Win/NT.
2001-12-12 Jeff Hobbs <jeffh@ActiveState.com>
- * doc/Preserve.3: doc'd TCL_DYNAMIC use. [Patch #483989] (porter)
+ * doc/Preserve.3: doc'd TCL_DYNAMIC use. [Patch 483989] (porter)
-2001-12-12 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+2001-12-12 Andreas Kupries <andreas_kupries@users.sourceforge.net>
- * generic/tclIO.c (Tcl_GetsObj): Applied patch for bug #491341 as
- provided by Don Porter <dgp@users.sourceforge.net>. Fixes the
- assumption of having an empty Tcl_Obj to work with.
+ * generic/tclIO.c (Tcl_GetsObj): Applied patch for [Bug 491341] as
+ provided by Don Porter <dgp@users.sourceforge.net>. Fixes the
+ assumption of having an empty Tcl_Obj to work with.
2001-12-11 Miguel Sofer <msofer@users.sourceforge.net>
* generic/tclCompCmds.c:
* generic/tclCompile.c:
- * generic/tclExecute.c: consistency patch, to make all
- instructions that pop a variable number of Tcl_Obj's off the
- execution stack take the number of popped objects as first
- operand. Modified *only* the new instructions
- INST_LIST_INDEX_MULTI and INST_LSET_FLAT, so this has no effect
- on bytecodes generated up to tcl8.4a3 inclusive.
+ * generic/tclExecute.c: consistency patch, to make all instructions
+ that pop a variable number of Tcl_Obj's off the execution stack take
+ the number of popped objects as first operand. Modified *only* the new
+ instructions INST_LIST_INDEX_MULTI and INST_LSET_FLAT, so this has no
+ effect on bytecodes generated up to tcl8.4a3 inclusive.
- * generic/tclExecute.c: fix debug messages in INST_LSET_LIST.
+ * generic/tclExecute.c: fix debug messages in INST_LSET_LIST.
* generic/tclCompCmds.c (TclCompileLindexCmd):
- * generic/tclCompExpr.c (CompileMathFuncCall): removed the last
- two overestimates of the necessary stack depth for bytecodes in
- the fix of [Bug 483611].
+ * generic/tclCompExpr.c (CompileMathFuncCall): removed the last two
+ overestimates of the necessary stack depth for bytecodes in the fix of
+ [Bug 483611]
-2001-12-10 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+2001-12-10 Andreas Kupries <andreas_kupries@users.sourceforge.net>
- * unix/tclUnixPipe.c (TclpCreateProcess): Applied Don Porter's
- patch fixing bug #437489.
+ * unix/tclUnixPipe.c (TclpCreateProcess): Applied Don Porter's patch
+ fixing [Bug 437489].
2001-12-10 Miguel Sofer <msofer@users.sourceforge.net>
* generic/tclEvent.c:
- * tests/event.test: fix background error reporting in the absence
- of a bgerror proc [Bug 219142].
+ * tests/event.test: fix background error reporting in the absence of a
+ bgerror proc [Bug 219142].
2001-12-10 Don Porter <dgp@users.sourceforge.net>
@@ -198,7 +188,7 @@
* doc/Utf.3:
* doc/file.n:
* doc/tclsh.1: Several typo and formatting corrections discovered
- during conversion to TMML. Thanks to Joe English. [Patch 490514]
+ during conversion to TMML. Thanks to Joe English. [Patch 490514]
* unix/mkLinks: 'make mklinks'
2001-12-10 Miguel Sofer <msofer@users.sourceforge.net>
@@ -208,14 +198,14 @@
* generic/tclCompile.c:
* generic/tclCompile.h:
* generic/tclExecute.c:
- * generic/tclProc.c: fixed the calculation of the maximal stack
- depth required by bytecodes [Bug 483611].
+ * generic/tclProc.c: fixed the calculation of the maximal stack depth
+ required by bytecodes. [Bug 483611]
2001-12-07 Miguel Sofer <msofer@users.sourceforge.net>
- * generic/tclVar.c:
+ * generic/tclVar.c:
* tests/trace.test: restored consistency in refCount accounting by
- array traces [Bug #4484339], submitted by Don Porter.
+ array traces [Bug 4484339], submitted by Don Porter.
2001-12-06 Donal K. Fellows <fellowsd@cs.man.ac.uk>
@@ -225,19 +215,19 @@
* generic/tclParseExpr.c (ParsePrimaryExpr): Rewrote to give even
better syntax errors in the fairly common case of an identifier
without decorations by guessing based on the currently available
- functions. Also made messages consistent between memdebug and
- ordinary builds.
+ functions. Also made messages consistent between memdebug and ordinary
+ builds.
2001-12-05 Miguel Sofer <msofer@users.sourceforge.net>
- * generic/tclVar.c:
- * tests/trace.test: new algorithm for [array get], safe when there
- are traces that modify the array [Bug #449893].
+ * generic/tclVar.c:
+ * tests/trace.test: new algorithm for [array get], safe when there are
+ traces that modify the array. [Bug 449893]
2001-12-04 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * tests/compExpr-old.test, tests/compExpr.test, tests/compile.test:
- * tests/expr-old.test, tests/expr.test, tests/for.test:
+ * tests/compExpr-old.test, tests/compExpr.test, tests/compile.test:
+ * tests/expr-old.test, tests/expr.test, tests/for.test:
* tests/while.test, tests/if.test: Rewrite to handle more specific
syntax errors.
* tests/parseExpr.test: Rewrite to get rid of dup test numbers and
@@ -246,26 +236,25 @@
argument to help explain what the syntax error is.
(Tcl_ParseExpr, ParseCondExpr, ParsePrimaryExpr): Added detail
messages.
- (UNKNOWN_CHAR): New lexeme for characters that are always illegal
- in expressions outside strings.
+ (UNKNOWN_CHAR): New lexeme for characters that are always illegal in
+ expressions outside strings.
2001-12-03 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * doc/expr.n: Various documentation improvements in relation to
- the function calls. Includes fix for Bug #487704 submitted by
- Devin Eyre.
+ * doc/expr.n: Various documentation improvements in relation to the
+ function calls. Includes fix for [Bug 487704] submitted by Devin Eyre.
2001-12-03 David Gravereaux <davygrvy@pobox.com>
* win/makefile.vc: Some install target bugs repaired along with
$(TCLSTUBLIB) added to the dependencies rather than implicit through
- the dde and reg extensions which don't happen to always require it
- for some build types.
+ the dde and reg extensions which don't happen to always require it for
+ some build types.
2001-11-30 Miguel Sofer <msofer@users.sourceforge.net>
- * generic/tclVar.c: Tcl_Preserve'ing VarTrace structures to avoid
- memory corruption. Patch for [Bug: 484334] provided by Don Porter
+ * generic/tclVar.c: Tcl_Preserve'ing VarTrace structures to avoid
+ memory corruption. Patch for [Bug 484334] provided by Don Porter
2001-11-29 Miguel Sofer <msofer@users.sourceforge.net>
@@ -275,16 +264,15 @@
2001-11-29 Miguel Sofer <msofer@users.sourceforge.net>
* tests/namespace.test: added namespace-41.2, a simpler test for
- [Bug: 231259]
+ [Bug 231259]
2001-11-29 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* generic/tclBinary.c (BINARY_SCAN_MAX_CACHE, Tcl_BinaryObjCmd,
- ScanNumber): Added caching scheme to reduce number of object
- allocations when doing scans of large repetitive binary strings.
- See comments in file for reasoning behind implementation.
- Suggested by Miguel Sofer in Patch #429916, but independently
- implemented.
+ (ScanNumber): Added caching scheme to reduce number of object
+ allocations when doing scans of large repetitive binary strings. See
+ comments in file for reasoning behind implementation. Suggested by
+ Miguel Sofer in [Patch 429916], but independently implemented.
2001-11-28 Donal K. Fellows <fellowsd@cs.man.ac.uk>
@@ -293,8 +281,8 @@
2001-11-27 D. Richard Hipp <drh@hwaci.com>
- * win/tclWinFCmd.c: Fix a coredump in the filename normalizer
- code for Win95/98.
+ * win/tclWinFCmd.c: Fix a coredump in the filename normalizer code for
+ Win95/98.
2001-11-27 David Gravereaux <davygrvy@pobox.com>
@@ -305,37 +293,36 @@
2001-11-27 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* tests/cmdAH.test (cmdAH-24.2): Made test less sensitive to OS
- preemption, but perfection isn't practical [Bug 463189, reported
- by Don Porter.]
+ preemption, but perfection isn't practical. [Bug 463189, reported by
+ Don Porter]
- * tests/switch.test (switch-9.*): Added tests to exercise more of
- the argument checking. (switch-7.2,switch-7.3): Test changed
- behaviour slightly.
- * generic/tclCmdMZ.c (Tcl_SwitchObjCmd): Reworked argument parsing
- to be stricter about what it accepts. This should make uses of
- the [switch] command be more maintainable. [Bug 475397, reported
- by Don Porter.]
+ * tests/switch.test (switch-9.*): Added tests to exercise more of the
+ argument checking. (switch-7.2,switch-7.3): Test changed behaviour
+ slightly.
+ * generic/tclCmdMZ.c (Tcl_SwitchObjCmd): Reworked argument parsing to
+ be stricter about what it accepts. This should make uses of the
+ [switch] command be more maintainable. [Bug 475397, reported by Don
+ Porter]
2001-11-26 Don Porter <dgp@users.sourceforge.net>
- * generic/tclIntPlatDecls.h: 'make genstubs' after changes
- in 2001-11-23 commit from Daniel Steffen.
+ * generic/tclIntPlatDecls.h: 'make genstubs' after changes in
+ 2001-11-23 commit from Daniel Steffen.
2001-11-24 Mo DeJong <mdejong@users.sourceforge.net>
- * unix/Makefile.in: Add comments to better describe
- TCL_EXE and when it should be available.
- * win/Makefile.in: Add TCL_EXE variable to be used
- by rules like `make genstubs`. Don't set TCL_LIBRARY
- before running `make genstubs` since we will be running
- with a tclsh from the PATH not the one we build.
+ * unix/Makefile.in: Add comments to better describe TCL_EXE and when
+ it should be available.
+ * win/Makefile.in: Add TCL_EXE variable to be used by rules like `make
+ genstubs`. Don't set TCL_LIBRARY before running `make genstubs` since
+ we will be running with a tclsh from the PATH not the one we build.
2001-11-24 Mo DeJong <mdejong@users.sourceforge.net>
* win/configure: Regen.
- * win/tcl.m4 (SC_CONFIG_CFLAGS): Add comctl32.lib
- to wish link libs. This change was originally added
- to Tk on 2001-11-09 but was not committed to Tcl.
+ * win/tcl.m4 (SC_CONFIG_CFLAGS): Add comctl32.lib to wish link libs.
+ This change was originally added to Tk on 2001-11-09 but was not
+ committed to Tcl.
2001-11-23 Daniel Steffen <das@users.sourceforge.net>
@@ -346,17 +333,17 @@
* unix/mkLinks.tcl:
* unix/tclLoadDyld.c:
* unix/tclMtherr.c: Mac OSX support: build system, dynamic code loading
- and support for case-insensitive filesystems in mkLinks (patch #435258)
+ and support for case-insensitive filesystems in mkLinks. [Patch 435258]
2001-11-23 Daniel Steffen <das@users.sourceforge.net>
- Up-port to 8.4 of mac code changes for 8.3.3 & various new
- changes for 8.4, some already backported to 8.3.4 (patch #435658)
+ Up-port to 8.4 of mac code changes for 8.3.3 & various new changes for
+ 8.4, some already backported to 8.3.4. [Patch 435658]
* generic/tclObj.c: added #include to fix missing prototype errors
* generic/tcl.h: MAC_TCL: addition of ConditionalMacros.h and use of
- DLLIMPORT and DLLEXPORT like on other platforms. ( => no longer need
+ DLLIMPORT and DLLEXPORT like on other platforms. ( => no longer need
the .exp files and can remove use of #pragma export that never worked
well)
removed line continuation in #if clause as this breaks the mac
@@ -364,10 +351,10 @@
* mac/tclMacFile.c: fixed bug in permission checking code
- * mac/tclMacLoad.c: corrected utf8 handling, comparison of
- package names to code fragment names changed to only match on the
- length of package name, this allows for fragment names with version
- numbers appended
+ * mac/tclMacLoad.c: corrected utf8 handling, comparison of package
+ names to code fragment names changed to only match on the length of
+ package name, this allows for fragment names with version numbers
+ appended.
* mac/tclMacInt.h:
* generic/tclInt.h:
@@ -402,7 +389,7 @@
platforms, removed use of #pragma export.
* mac/tcltkMacBuildSupport.sea.hqx: new archive of mac build support
- files & suggested build environment directory hierarchy:
+ files & suggested build environment directory hierarchy:
'Building MacTclTk' & 'CW Pro6 changes' readme's.
projects for MoreFiles 1.5.2 static & shared libraries.
project & sources for 'pseudoCarbonSupport', see below.
@@ -430,13 +417,13 @@
Highly experimental "pseudoCarbon" support for Tcl only on OS 8/9:
binaries in "Build:(Carbon):" link against CarbonLib instead of
InterfaceLib, however the actual code has not been carbonized! i.e. it
- will not run on OSX and may not even run properly with CarbonLib.
+ will not run on OSX and may not even run properly with CarbonLib.
This should in principle allow you to build & test OS9 CFM Carbon
- binaries that need to link with Tcl.shlb. On OSX you can use the
+ binaries that need to link with Tcl.shlb. On OSX you can use the
native Tcl.framework, but you have to build a MachO binary as there
is no CFM glue lib for Tcl.framework.
- the library pseudoCarbonSupport.shlb manually loads the symbols
- from InterfaceLib that are not in CarbonLib but are needed by the
+ the library pseudoCarbonSupport.shlb manually loads the symbols from
+ InterfaceLib that are not in CarbonLib but are needed by the
uncarbonized code in Tcl.shlb and TclShell.
* generic/tclMain.c: MAC_TCL: workaround for broken/non-standard isatty
@@ -461,10 +448,10 @@
strings; updated version strings to standard usage; added support for
'(Support Libraries)' subfolder for shared runtime libraries in
unmerged binaries; commented out demo setting of "Tcl Environment
- Variables"; reorganized resources among these files to avoid
- multiple copies in applications and shared libraries, the script
- libraries are now no longer duplicated in Tclsh but are only included
- in the resources of Tcl.shlb.
+ Variables"; reorganized resources among these files to avoid multiple
+ copies in applications and shared libraries, the script libraries are
+ now no longer duplicated in Tclsh but are only included in the
+ resources of Tcl.shlb.
* mac/tclMacChan.c:
* mac/tclMacSock.c: cast for *BlockMode
@@ -497,52 +484,51 @@
* mac/tclMacUnix.c: added missing (Tcl_Obj ***) cast to
Tcl_ListObjGetElements call
- * mac/tclMacAlloc.c: modernized TclpSysAlloc() to use temporary
- memory instead of system heap memory when available (MacOS
- >= 7.5 and possibly earlier, use of system heap has been
- discouraged for a long time and has many disadvantages, e.g. memory
- isn't paged out, and errors can very easily bring the system down);
- fixed crashing bug in TclpSysRealloc() and CleanUpExitProc() where
- memory was being accessed after having been deallocated; fixed
- memory leak in (de)allocation code (for every block ever allocated
- with TclpSysAlloc, a Ptr was leaked), if temporary memory is
- available, don't track allocated memory, instead use
- RecoverHandle() to get Handle from Ptr, otherwise use doubly linked
- list to correctly track memory and free all allocated memory; added
- new option for ConfigureMemory: MEMORY_DONT_USE_TEMPMEM, disables
- use of temporary memory even when it would be available, only
- necessary when writing e.g. a driver (using tcl??); increased
- fraction of application heap reserved for OS routines to 512K
-
- * compat/strftime.c:
+ * mac/tclMacAlloc.c: modernized TclpSysAlloc() to use temporary memory
+ instead of system heap memory when available (MacOS >= 7.5 and
+ possibly earlier, use of system heap has been discouraged for a long
+ time and has many disadvantages, e.g. memory isn't paged out, and
+ errors can very easily bring the system down); fixed crashing bug in
+ TclpSysRealloc() and CleanUpExitProc() where memory was being accessed
+ after having been deallocated; fixed memory leak in (de)allocation
+ code (for every block ever allocated with TclpSysAlloc, a Ptr was
+ leaked), if temporary memory is available, don't track allocated
+ memory, instead use RecoverHandle() to get Handle from Ptr, otherwise
+ use doubly linked list to correctly track memory and free all
+ allocated memory; added new option for ConfigureMemory:
+ MEMORY_DONT_USE_TEMPMEM, disables use of temporary memory even when it
+ would be available, only necessary when writing e.g. a driver (using
+ tcl??); increased fraction of application heap reserved for OS
+ routines to 512K
+
+ * compat/strftime.c:
* mac/tclMacTime.c:
* mac/tclMacPort.h:
- * generic/tclInt.decls:
+ * generic/tclInt.decls:
* generic/tclIntPlatDecls.h:
- * generic/tclStubInit.c: timezone support for mac via
- TclpGetTZName() like on windows, using an inverse timezone table
- adapted from tclDate.c to map gmtoffset in seconds gotten from
- the MacOS APIs to a timezone string, as there is no good way to get
- this info from MacOS. I had to make up some unusual timezones and
- arbitrarily decide on the most standard of the multiple choices
- available for every timezone.
-
- * generic/tclExecute.c: workaround for a MSL bug/misfeature: for
- very small floats, MSL can return errno ERANGE but a
- non-zero value ( < LDBL_MIN however)
-
- * mac/tclMacAppInit.c: support for WASTE text library using
- temporary memory, setting has no effect if WASTE is not used.
-
+ * generic/tclStubInit.c: timezone support for mac via TclpGetTZName()
+ like on windows, using an inverse timezone table adapted from
+ tclDate.c to map gmtoffset in seconds gotten from the MacOS APIs to a
+ timezone string, as there is no good way to get this info from MacOS.
+ I had to make up some unusual timezones and arbitrarily decide on the
+ most standard of the multiple choices available for every timezone.
+
+ * generic/tclExecute.c: workaround for a MSL bug/misfeature: for very
+ small floats, MSL can return errno ERANGE but a non-zero value (<
+ LDBL_MIN however)
+
+ * mac/tclMacAppInit.c: support for WASTE text library using temporary
+ memory, setting has no effect if WASTE is not used.
+
* mac/tclMacPanic.c: removed duplicate code from generic/tclPanic.c
and added that file to projects instead.
* tests/all.tcl: set tcltest::singleProcess 1 as multiple processes
are not available on the mac.
-
- * tests/cmdAH.test: access time not available on the mac, skip the
+
+ * tests/cmdAH.test: access time not available on the mac, skip the
atime touch test
-
+
* tests/appendComp.test:
* tests/cmdMZ.test:
* tests/compile.test:
@@ -550,20 +536,20 @@
* tests/fileName.test:
* tests/lset.test:
* tests/namespace.test:
- * tests/tcltest.test: added missing cleanups/tests/catches that
- caused tests to fail on the mac.
+ * tests/tcltest.test: added missing cleanups/tests/catches that caused
+ tests to fail on the mac.
* doc/tclvars.n: doc bug, env(PWD) should be env(HOME) [Bug 463834]
-
+
2001-11-21 Don Porter <dgp@users.sourceforge.net>
* tests/trace.test (trace-8.8): Corrected test for Bug 219393.
* generic/tclBasic.c (Tcl_DeleteCommandFromToken,CallCommandTraces):
* generic/tclCmdMZ>c (Tcl_UntraceCommand): Added Tcl_Preserve and
- Tcl_Release calls to prevent deletion of CommandTrace structures
- until all callers are done using them, preventing memory corruption.
- [Bug 453805]
+ Tcl_Release calls to prevent deletion of CommandTrace structures until
+ all callers are done using them, preventing memory corruption. [Bug
+ 453805]
2001-11-20 Kevin B. Kenny <kennykb@users.sourceforge.net>
@@ -575,7 +561,7 @@
* generic/tclUtil.c (TclpGetTime):
* generic/tclTest.c (GetTimesCmd):
* generic/tclTimer.c (Tcl_CreateTimerHandler, TimerSetupProc,
- TimerCheckProc, TimerHandlerEventProc):
+ (TimerCheckProc, TimerHandlerEventProc):
* mac/tclMacNotify.c (Tcl_SetTimer):
* mac/tclMacShLib.exp (Tcl_GetTime):
* mac/tclMacTime.c (Tcl_GetTime):
@@ -586,72 +572,72 @@
* win/tclWinNotify.c (Tcl_Sleep):
* win/tclWinTest.c (TestwinclockCmd):
* win/tclWinTime.c (TclpGetSeconds, TclpGetClicks, Tcl_GetTime):
- Changed all uses of TclpGetTime to Tcl_GetTime. Added Tcl_GetTime
- to the Stubs table and the library documentation. Added a
- TclpGetTime in tclUtil.c for backward compatibility of
- extensions. [Patch #483500, TIP#73]
+ Changed all uses of TclpGetTime to Tcl_GetTime. Added Tcl_GetTime to
+ the Stubs table and the library documentation. Added a TclpGetTime in
+ tclUtil.c for backward compatibility of extensions. [Patch 483500,
+ TIP#73]
* generic/tclCmdMZ.c (Tcl_TimeObjCmd): Corrected an error in the
[time] command that caused incorrect results to be returned if the
- total duration of all iterations exceeded 2**31 microseconds.
- [Bug #478847]
+ total duration of all iterations exceeded 2**31 microseconds. [Bug
+ 478847]
* generic/tclInt.decls:
* generic/tclInt.h:
* generic/tclStubInit.h: Reran 'make genstubs'
-
+
2001-11-20 Miguel Sofer <msofer@users.sourceforge.net>
* generic/tclBasic.c
- * generic/tclCompile.h:
+ * generic/tclCompile.h:
* generic/tclExecute.c: moving all code relative to bytecodes from
tclBasic.c to tclExecute.c - the functions RecordTracebackInfo and
Tcl_ExprObj went to tclExecute.c, and new interface function was
defined (TclCompEvalObj).
- The final objective of this sequence of moves is to provide a
- clean, clear-cut interface between Tcl's core and the
- compiler/engine subsystem.
+ The final objective of this sequence of moves is to provide a clean,
+ clear-cut interface between Tcl's core and the compiler/engine
+ subsystem.
2001-11-20 Miguel Sofer <msofer@users.sourceforge.net>
* generic/tclBasic.c
- * generic/tclCompile.h:
+ * generic/tclCompile.h:
* generic/tclExecute.c: factoring out of common code in tclBasic.c
- (new function TclInterpReady defined: it resets the interp's
- result, then checks that it hasn't been deleted and that the
- nesting level is acceptable). Passed the responsibility of calling
- it to the *callers* of TclEvalObjvInternal.
+ (new function TclInterpReady defined: it resets the interp's result,
+ then checks that it hasn't been deleted and that the nesting level is
+ acceptable). Passed the responsibility of calling it to the *callers*
+ of TclEvalObjvInternal.
2001-11-20 Miguel Sofer <msofer@users.sourceforge.net>
* generic/tclBasic.c
* generic/tclExecute.c: a better variant of the previous-to-last
- commit (restoring numLevels computations). The managing of the
- levels now has to be done by the *callers* of TclEvalObjvInternal
+ commit (restoring numLevels computations). The managing of the levels
+ now has to be done by the *callers* of TclEvalObjvInternal
2001-11-20 Miguel Sofer <msofer@users.sourceforge.net>
* generic/tclExecute.c: missing variable declaration under
- TCL_COMPILE_DEBUG.
+ TCL_COMPILE_DEBUG.
2001-11-20 Miguel Sofer <msofer@users.sourceforge.net>
* generic/tclExecute.c:
- * generic/tclProc.c: restoring the computations of iPtr->numLevels
- to the original logic (previous to buggy modifs on 2001-11-16).
+ * generic/tclProc.c: restoring the computations of iPtr->numLevels to
+ the original logic (previous to buggy modifs on 2001-11-16).
2001-11-20 Jeff Hobbs <jeffh@ActiveState.com>
* tools/eolFix.tcl (new-file):
* unix/Makefile.in: added EOL correction for Windows bat files to
- dist target. [Bug #219409] (davygrvy)
+ dist target. [Bug 219409] (davygrvy)
- * unix/tclUnixInit.c (TclpSetInitialEncodings): update of patch
- from 2001-11-16 that uses the old Tcl encoding check mechanism as
- a fallback to the original. Also added a TCL_DEFAULT_ENCODING
- #define (defaults to iso8859-1). Tcl will first try setlocale and
- nl_langinfo, and if that fails, guess based on certain LANG|LC_*
- env vars. [Patch #418645]
+ * unix/tclUnixInit.c (TclpSetInitialEncodings): update of patch from
+ 2001-11-16 that uses the old Tcl encoding check mechanism as a
+ fallback to the original. Also added a TCL_DEFAULT_ENCODING #define
+ (defaults to iso8859-1). Tcl will first try setlocale and nl_langinfo,
+ and if that fails, guess based on certain LANG|LC_* env vars. [Patch
+ 418645]
2001-11-19 David Gravereaux <davygrvy@pobox.com>
@@ -667,42 +653,42 @@
* win/tclWinFCmd.c:
* win/tclWin32Dll.c:
* doc/file.n:
- * tests/winFCmd.test: improved speed of file normalization
- for Win95/98, and clarified docs on differences in file
- normalization between NT/2000 and the older operating systems.
- Added test to ensure normalization is correct.
-
+ * tests/winFCmd.test: improved speed of file normalization for
+ Win95/98, and clarified docs on differences in file normalization
+ between NT/2000 and the older operating systems. Added test to ensure
+ normalization is correct.
+
2001-11-19 Miguel Sofer <msofer@users.sourceforge.net>
* generic/tclBasic.c:
* generic/tclParse.c: Code reorganisation. Moved all evaluation
- functions from tclParse.c to tclBasic.c, so that now tclParse.c
- deals exclusively with parsing and all evaluations are done by
- code in tclBasic.c. The functions moved are: TclEvalObjvInternal,
+ functions from tclParse.c to tclBasic.c, so that now tclParse.c deals
+ exclusively with parsing and all evaluations are done by code in
+ tclBasic.c. The functions moved are: TclEvalObjvInternal,
Tcl_EvalObjv, Tcl_LogCommandInfo, Tcl_EvalTokensStandard,
Tcl_EvalTokens, Tcl_EvalEx, Tcl_Eval, Tcl_EvalObj and
- Tcl_GlobalEvalObj.
+ Tcl_GlobalEvalObj.
2001-11-19 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * tests/trace.test (trace-8.8): Added adapted version of Bug
- #219393 as new test; the test won't reliably show up the old
- problem unless it is being run under something like Purify, but
- something is better than nothing...
+ * tests/trace.test (trace-8.8): Added adapted version of [Bug 219393]
+ as new test; the test won't reliably show up the old problem unless it
+ is being run under something like Purify, but something is better than
+ nothing...
* generic/tclVar.c (Tcl_TraceVar2, Tcl_UntraceVar2): Added missing
mask bits for trace result type and a check for a nonsense flag
combination.
- * generic/tclCmdMZ.c (TraceVarProc): Added missing test for NULL
- when deleting a trace that doesn't cause an error.
+ * generic/tclCmdMZ.c (TraceVarProc): Added missing test for NULL when
+ deleting a trace that doesn't cause an error.
* doc/TraceVar.3: Added documentation for change due to TIP#68.
- * generic/tclCmdMZ.c (TraceVarInfo): Removed problematic errMsg
- field from structure.
+ * generic/tclCmdMZ.c (TraceVarInfo): Removed problematic errMsg field
+ from structure.
(TraceVarProc): Removed references to errMsg field and changed
handling of errors so that they returned a Tcl_Obj* containing the
- error string. This minimizes the number of calls to the memory
+ error string. This minimizes the number of calls to the memory
management subsystem.
(TclTraceCommandObjCmd, TraceCommandProc): Removed references to
errMsg field which was never used in command traces in any case.
@@ -710,14 +696,14 @@
errMsg field and made variable traces register with
TCL_TRACE_RESULT_OBJECT bit set.
- * generic/tcl.h (TCL_TRACE_RESULT_DYNAMIC,TCL_TRACE_RESULT_OBJECT):
- New constants to define how to handle the strings returned from
- trace callbacks [TIP#68]
+ * generic/tcl.h (TCL_TRACE_RESULT_DYNAMIC,TCL_TRACE_RESULT_OBJECT):
+ New constants to define how to handle the strings returned from trace
+ callbacks [TIP#68]
* generic/tclVar.c (CallTraces, Tcl_GetVar2Ex, TclGetIndexedScalar,
- TclGetElementOfIndexedArray, Tcl_SetVar2Ex, TclSetIndexedScalar,
- TclSetElementOfIndexedArray, Tcl_UnsetVar2, Tcl_ArrayObjCmd,
- TclDeleteVars, TclDeleteCompiledLocalVars, DeleteArray,
- TclVarTraceExists): Support for those new trace flags.
+ (TclGetElementOfIndexedArray, Tcl_SetVar2Ex, TclSetIndexedScalar,
+ (TclSetElementOfIndexedArray, Tcl_UnsetVar2, Tcl_ArrayObjCmd,
+ (TclDeleteVars, TclDeleteCompiledLocalVars, DeleteArray,
+ (TclVarTraceExists): Support for those new trace flags.
2001-11-19 Miguel Sofer <msofer@users.sourceforge.net>
@@ -725,14 +711,14 @@
2001-11-16 Kevin B. Kenny <kennykb@users.sourceforge.net>
- * generic/tclListObj.c: removed a C++-style comment that
- was inadvertently left in the source code.
+ * generic/tclListObj.c: removed a C++-style comment that was
+ inadvertently left in the source code.
2001-11-16 Jeff Hobbs <jeffh@ActiveState.com>
- * tests/interp.test:
- * generic/tclInterp.c (SlaveObjCmd): Corrected argument checking
- for '$interp alias|aliases|issafe'. [Patch #479560] (thoyts, hobbs)
+ * tests/interp.test:
+ * generic/tclInterp.c (SlaveObjCmd): Corrected argument checking for
+ '$interp alias|aliases|issafe'. [Patch 479560] (thoyts, hobbs)
* unix/tclUnixInit.c: added HAVE_LANGINFO code block.
* unix/configure: regened
@@ -740,17 +726,17 @@
* unix/tcl.m4: made SHLIB_LD_LIBS='${LIBS}' for FreeBSD* (meyer)
Added modified version of Wagner patch to make use of nl_langinfo
where possible to determine Unix platform encoding, instead of the
- inflexible built-in system. This is used by default when
- possible, and can be disabled with --enable-langinfo=no.
- [Patch #418645] (hobbs, wagner)
+ inflexible built-in system. This is used by default when possible, and
+ can be disabled with --enable-langinfo=no. [Patch 418645] (hobbs,
+ wagner)
2001-11-16 Miguel Sofer <msofer@users.sourceforge.net>
* generic/tclCompile.h:
* generic/tclExecute.c:
- * generic/tclObj.c: moved Tcl_GetCommandFromObj and all defining
- code for tclCmdNameType objects to tclObj.c (from tclExecute.c).
- This code has nothing to do with bytecodes.
+ * generic/tclObj.c: moved Tcl_GetCommandFromObj and all defining code
+ for tclCmdNameType objects to tclObj.c (from tclExecute.c). This code
+ has nothing to do with bytecodes.
2001-11-16 Miguel Sofer <msofer@users.sourceforge.net>
@@ -760,18 +746,17 @@
* generic/tclParse.c:
* generic/tclProc.c:
* tests/stack.test: consolidation of duplicated code (in
- TclExecuteByteCode and EvalObjv); renaming of EvalObjv to
- TclEvalObjv as it is not static anymore; restored consistency of
- level counts between compiled and directly evaled code.
- [Bug 480896]
+ TclExecuteByteCode and EvalObjv); renaming of EvalObjv to TclEvalObjv
+ as it is not static anymore; restored consistency of level counts
+ between compiled and directly evaled code. [Bug 480896]
2001-11-12 David Gravereaux <davygrvy@pobox.com>
* win/makefile.vc:
* win/rules.vc: Small bug fixes.
- * win/README: added some docs pointing to the docs in makefile.vc
- for it's use.
+ * win/README: added some docs pointing to the docs in makefile.vc for
+ it's use.
2001-10-17 Kevin B. Kenny <kennykb@users.sourceforge.net>
@@ -806,17 +791,17 @@
* tests/obj.test:
* tests/string.test:
* tests/stringComp.test:
- Reference implementation of TIP's #22, #33 and #45. Adds the
- ability of the [lindex] command to have multiple index arguments,
- and adds the [lset] command. Both commands are byte-code compiled.
- [Patch #471874] (work by Kenny, commited by Hobbs)
+ Reference implementation of TIP's #22, #33 and #45. Adds the ability
+ of the [lindex] command to have multiple index arguments, and adds the
+ [lset] command. Both commands are byte-code compiled. [Patch 471874]
+ (work by Kenny, commited by Hobbs)
2001-11-12 David Gravereaux <davygrvy@pobox.com>
* win/buildall.vc.bat(new):
* win/makefile.vc: Small fix with deriving the "OriginalFilename"
- string in the .rc scripts. Added a quick batchfile for building
- the entire thing.
+ string in the .rc scripts. Added a quick batchfile for building the
+ entire thing.
2001-11-12 Jeff Hobbs <jeffh@ActiveState.com>
@@ -827,8 +812,8 @@
2001-11-10 Mo DeJong <mdejong@users.sourceforge.net>
* unix/Makefile.in:
- * win/Makefile.in: Add "make gdb" target. This target
- can run tclsh inside either gdb or insight.
+ * win/Makefile.in: Add "make gdb" target. This target can run tclsh
+ inside either gdb or insight.
2001-11-10 David Gravereaux <davygrvy@pobox.com>
@@ -837,20 +822,19 @@
* win/mkd.bat:
* win/rmd.bat: Changes from Llyod Lim for better stability.
- [Patch #456759]
+ [Patch 456759]
2001-11-09 David Gravereaux <davygrvy@pobox.com>
* win/makefile.vc:
- * win/tcl.dsp: winhelp target fixes for non-NT systems. It
- seems NMAKE under these remembers changed directories during
- commands. A new tcltest feature from Peter Spjuth
- <peter.spjuth@space.se> to specify a pattern file from the
- commandline and redirecting output to a file when not under
- NT with it's scrollback console. Then it replays it, piped
- through more. Added 2 new static "configurations" to tcl.dsp.
- I could keep adding more, but I think we should leave it up to
- the user for customizing it.
+ * win/tcl.dsp: winhelp target fixes for non-NT systems. It seems
+ NMAKE under these remembers changed directories during commands. A new
+ tcltest feature from Peter Spjuth <peter.spjuth@space.se> to specify a
+ pattern file from the commandline and redirecting output to a file
+ when not under NT with it's scrollback console. Then it replays it,
+ piped through more. Added 2 new static "configurations" to tcl.dsp.
+ I could keep adding more, but I think we should leave it up to the
+ user for customizing it.
Sticky-points left: 'profile' option.
@@ -860,9 +844,9 @@
* doc/StdChannels.3:
* doc/file.n:
* doc/tcltest.n:
- * tools/man2help.tcl:
+ * tools/man2help.tcl:
* tools/man2help2.tcl: fixed winhelp generation problems
- [Patch #480268]
+ [Patch 480268]
* unix/configure:
* unix/tcl.m4: added -lc to AIX libs, fixed path to ldAix
@@ -870,68 +854,64 @@
2001-11-09 Don Porter <dgp@users.sourceforge.net>
* tests/var.test:
- * generic/tclVar.c: Corrected bug in [global] when dealing
- with variable names matching :*. [Bug 480176]
+ * generic/tclVar.c: Corrected bug in [global] when dealing with
+ variable names matching :*. [Bug 480176]
2001-11-08 Mo DeJong <mdejong@users.sourceforge.net>
- Fixup stack size under OSF1. [Tcl patch 474790]
+ Fixup stack size under OSF1. [Patch 474790]
* unix/configure: Regen.
- * unix/tcl.m4: Add HAVE_PTHREAD_ATTR_SETSTACKSIZE define
- to EXTRA_CFLAGS to adjust initial stack size.
+ * unix/tcl.m4: Add HAVE_PTHREAD_ATTR_SETSTACKSIZE define to
+ EXTRA_CFLAGS to adjust initial stack size.
2001-11-08 Mo DeJong <mdejong@users.sourceforge.net>
- Enable thread support under FreeBSD. [Tcl bug 473708]
+ Enable thread support under FreeBSD. [Bug 473708]
* unix/configure: Regen.
- * unix/tcl.m4 (SC_ENABLE_THREADS): Check for pthread functions
- in libc_r and enable thread support if found.
- * unix/dltest/Makefile.in: Set SHLIB_LD_LIBS and use it in
- the Makefile to properly link a shared library.
+ * unix/tcl.m4 (SC_ENABLE_THREADS): Check for pthread functions in
+ libc_r and enable thread support if found.
+ * unix/dltest/Makefile.in: Set SHLIB_LD_LIBS and use it in the
+ Makefile to properly link a shared library.
2001-11-08 Mo DeJong <mdejong@users.sourceforge.net>
* unix/Makefile.in:
- * unix/dltest/Makefile.in:
- Avoid adding libc to the LIBS variable since it
- is not needed when linking with CC. If required
- when linking with LD it should be done on a case
- by case basis in tcl.m4.
+ * unix/dltest/Makefile.in: Avoid adding libc to the LIBS variable
+ since it is not needed when linking with CC. If required when linking
+ with LD it should be done on a case by case basis in tcl.m4.
2001-11-08 David Gravereaux <davygrvy@pobox.com>
* win/rules.vc:
- * win/makefile.vc: Fixed install target to adjust for the
- different build types. Added a 'linkexten' option to link the
- win extensions inside the shell when built static. Placed
- win/tclAppInit.c patch in SF patch DB for approval. 'profile'
- option not hooked in yet. Everything else know is done.
+ * win/makefile.vc: Fixed install target to adjust for the different
+ build types. Added a 'linkexten' option to link the win extensions
+ inside the shell when built static. Placed win/tclAppInit.c patch in
+ SF patch DB for approval. 'profile' option not hooked in yet.
+ Everything else know is done.
* win/tcl.dsp(new):
* win/tcl.dsw(new): Simple MsDev stub project files that calls
- makefile.vc. Will help run Tcl in the debugger easier without
+ makefile.vc. Will help run Tcl in the debugger easier without
confusing MsDev for where the .pdb files are.
2001-11-07 Mo DeJong <mdejong@users.sourceforge.net>
* unix/Makefile.in:
- * win/Makefile.in:
- Print a message indicating that the user should
- run "make genstubs" when the generated tclStubInit.c
- file is out of date. We can't regenerate automatically
- since there may be no tclsh on the system and that
- would cause bootstrap problems. [Tcl bug 465874]
+ * win/Makefile.in: Print a message indicating that the user should run
+ "make genstubs" when the generated tclStubInit.c file is out of date.
+ We can't regenerate automatically since there may be no tclsh on the
+ system and that would cause bootstrap problems. [Bug 465874]
2001-11-07 Mo DeJong <mdejong@users.sourceforge.net>
- Define TCL_INCLUDE_SPEC in tclConfig.sh. It should be
- included by extensions that need to find Tcl include
- headers in the install location. The user can override
- the include install dir with --includedir so we need
- to record this information for extensions. [Tcl bug 421835]
-
+ Define TCL_INCLUDE_SPEC in tclConfig.sh. It should be included by
+ extensions that need to find Tcl include headers in the install
+ location. The user can override the include install dir with
+ --includedir so we need to record this information for extensions.
+ [Bug 421835]
+
* unix/configure: Regen.
* unix/configure.in: Define TCL_INCLUDE_SPEC.
* unix/tclConfig.sh.in: Define TCL_INCLUDE_SPEC.
@@ -942,45 +922,41 @@
2001-11-07 David Gravereaux <davygrvy@pobox.com>
* win/rules.vc:
- * win/makefile.vc: Dropped the NOMSVCRT macro and put it on the
- option list instead. It makes more sense to me this way as
- NOMSVCRT=0 would only be the valid setting. Fixed the dde and reg
- extension for building static. Improved, but not perfected, the
- winhelp target.
+ * win/makefile.vc: Dropped the NOMSVCRT macro and put it on the option
+ list instead. It makes more sense to me this way as NOMSVCRT=0 would
+ only be the valid setting. Fixed the dde and reg extension for
+ building static. Improved, but not perfected, the winhelp target.
2001-11-07 Mo DeJong <mdejong@users.sourceforge.net>
- * win/README: Change minimum VC++ version to 5.X since
- 4.X is known not to work.
- Indicate that Mingw is required and building with Cygwin
- gcc is not supported. Include instructions that indicate
- how to install Mingw and what URLs folks should use to
- download the supported version of Mingw.
+ * win/README: Change minimum VC++ version to 5.X since 4.X is known
+ not to work.
+ Indicate that Mingw is required and building with Cygwin gcc is not
+ supported. Include instructions that indicate how to install Mingw and
+ what URLs folks should use to download the supported version of Mingw.
* win/configure: Regen.
- * win/configure.in: Error out if user tries to compile the
- Windows version of Tcl with Cygwin gcc. Users should compile
- with Mingw gcc instead.
+ * win/configure.in: Error out if user tries to compile the Windows
+ version of Tcl with Cygwin gcc. Users should compile with Mingw gcc
+ instead.
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 fileevents when [read]ing less data from the channel than
- buffered. Due to an empty input buffer the flag
- CHANNEL_NEED_MORE_DATA was set but never reset, causing the I/O
- system to wait for more data instead of using a timer to
- synthesize fileevents and to flush the pending data out of the
- buffers.
+ * generic/tclIO.c (ReadChars): Fixed [Bug 478856] reported by Stuart
+ Cassoff <stwo@users.sourceforge.net>. The bug caused loss of
+ fileevents when [read]ing less data from the channel than buffered.
+ Due to an empty input buffer the flag CHANNEL_NEED_MORE_DATA was set
+ but never reset, causing the I/O system to wait for more data instead
+ of using a timer to synthesize fileevents and to flush the pending
+ data out of the buffers.
2001-11-06 David Gravereaux <davygrvy@pobox.com>
* win/rules.vc (new):
* win/makefile.vc: Complete over/under rewrite to support numerous
- build options all from the commandline itself without needing to
- edit the makefile. Now requires vcvars32.bat to be run prior to
- running nmake for bootstraping the environment. Fully doc'd usage
- for it is in makefile.vc. Commentary welcome. Sticky points left
- are:
+ build options all from the commandline itself without needing to edit
+ the makefile. Now requires vcvars32.bat to be run prior to running
+ nmake for bootstraping the environment. Fully doc'd usage for it is in
+ makefile.vc. Commentary welcome. Sticky points left are:
1) winhelp target shows errors in the converting script.
2) .rc scripts aren't getting the right #defines to build the correct
@@ -992,158 +968,153 @@
2001-11-04 Vince Darley <vincentdarley@users.sourceforge.net>
- * library/init.tcl: made filesystem fallback proc
- ::tcl::CopyDirectory more robust to vagaries of non-native
- filesystems.
-
+ * library/init.tcl: made filesystem fallback proc ::tcl::CopyDirectory
+ more robust to vagaries of non-native filesystems.
+
2001-11-02 Vince Darley <vincentdarley@users.sourceforge.net>
* doc/file.n:
- * generic/tclIOUtil.c: updated documentation and comments
- to clarify behaviour of 'file copy' wrt soft links.
-
+ * generic/tclIOUtil.c: updated documentation and comments to clarify
+ behaviour of 'file copy' wrt soft links.
+
2001-10-29 Vince Darley <vincentdarley@users.sourceforge.net>
- * win/tclWinFile.c: fix to '-types {f r}' bug in
- TclpMatchInDirectory (which could cause a UMR, as well as
- returning wrong results). Also improved API for 'stat'
- to resolve [Bug#219258].
+ * win/tclWinFile.c: fix to '-types {f r}' bug in TclpMatchInDirectory
+ (which could cause a UMR, as well as returning wrong results). Also
+ improved API for 'stat' to resolve [Bug 219258].
* win/tclWin32Dll.c
- * win/tclWinInt.h: addition of improved stat API to internal
- lookup table.
+ * win/tclWinInt.h: addition of improved stat API to internal lookup
+ table.
* tests/fileName.test: two new tests for the above bug.
* generic/tclIOUtil.c: some cleanup of comments and #ifdefs
-
+
2001-10-29 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * unix/tclUnixFile.c (TclpMatchInDirectory): Argument to access()
- was entryPtr->d_name instead of nativeEntry which failed when
- trying to check access for files in other than the current
- directory. [Bug 475941, reported by Georgios Petasis]
+ * unix/tclUnixFile.c (TclpMatchInDirectory): Argument to access() was
+ entryPtr->d_name instead of nativeEntry which failed when trying to
+ check access for files in other than the current directory. [Bug
+ 475941, reported by Georgios Petasis]
2001-10-25 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* unix/tclUnixChan.c: Added stateUpdated member to struct TtyState.
- (TtyCloseProc,TtySetOptionProc,TtyInit): Use stateUpdated member
- of TtyState to decide whether it is necessary to reset a serial
- port when Tcl closes it. Blindly resetting can cause Tcl to be
- sent an unexpected SIGTSTP when it is executing in the background
- [Bug 471374, reported by Chris Nelson]
+ (TtyCloseProc,TtySetOptionProc,TtyInit): Use stateUpdated member of
+ TtyState to decide whether it is necessary to reset a serial port when
+ Tcl closes it. Blindly resetting can cause Tcl to be sent an
+ unexpected SIGTSTP when it is executing in the background [Bug 471374,
+ reported by Chris Nelson]
-2001-10-22 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+2001-10-22 Andreas Kupries <andreas_kupries@users.sourceforge.net>
- * doc/ObjectType.3: Minor documentation fix, reported by David
- N. Welton <davidw@users.sourceforge.net> directly to me.
+ * doc/ObjectType.3: Minor documentation fix, reported by David N.
+ Welton <davidw@users.sourceforge.net> directly to me.
2001-10-22 Vince Darley <vincentdarley@users.sourceforge.net>
- * win/tclWinFCmd.c: fix to stop test suite from hanging process
- under some versions of WinNT. [Bug #466102] (Kevin Kenny)
-
+ * win/tclWinFCmd.c: fix to stop test suite from hanging process under
+ some versions of WinNT. [Bug 466102] (Kevin Kenny)
+
2001-10-18 Jeff Hobbs <jeffh@ActiveState.com>
- * tests/clock.test (clock-8.1):
- * generic/tclDate.c (RelativeMonth):
- * generic/tclGetDate.y (RelativeMonth): corrected off-by-one-day
- error in clock scan with relative months and years during swing
- hours. [Bug #413397, Patch #414024] (lavana)
+ * tests/clock.test (clock-8.1):
+ * generic/tclDate.c (RelativeMonth):
+ * generic/tclGetDate.y (RelativeMonth): corrected off-by-one-day error
+ in clock scan with relative months and years during swing hours. [Bug
+ 413397, Patch 414024] (lavana)
2001-10-18 Vince Darley <vincentdarley@users.sourceforge.net>
- * generic/tclIOUtil.c: fix to bug in Tcl_FSChdir shown up
- by recent tclkit builds.
+ * generic/tclIOUtil.c: fix to bug in Tcl_FSChdir shown up by recent
+ tclkit builds.
2001-10-17 Jeff Hobbs <jeffh@ActiveState.com>
* unix/tclUnixPipe.c (PipeInputProc, PipeOutputProc): do immediate
- retry when error is returned with errno == EINTR.
- [Bug #415131] (leger)
+ retry when error is returned with errno == EINTR. [Bug 415131] (leger)
2001-10-16 Jeff Hobbs <jeffh@ActiveState.com>
- * unix/tclLoadAout.c (TclGuessPackageName): removed unused vars
- and fixed warnings. [Bug #446622] (lim)
+ * unix/tclLoadAout.c (TclGuessPackageName): removed unused vars and
+ fixed warnings. [Bug 446622] (lim)
2001-10-15 Miguel Sofer <msofer@users.sourceforge.net>
* generic/tclProc.c: changing a memcmp to strncmp to avoid a memory
- error detected by purify (thanks Jeff); modify style to agrre with
- the style guide.
-
-2001-10-15 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+ error detected by purify (thanks Jeff); modify style to agrre with the
+ style guide.
+
+2001-10-15 Andreas Kupries <andreas_kupries@users.sourceforge.net>
* generic/tclInt.decls (TclExpandCodeArray,TclGetInstructionTable):
- Added to internal stubs table. Tclcompiler (Tclpro project)
- needs them if used as loadable package under Windows. Changed
- signatures. We don't want to describe compiler internal
- structures in "tclInt.h".
+ Added to internal stubs table. Tclcompiler (Tclpro project) needs them
+ if used as loadable package under Windows. Changed signatures. We
+ don't want to describe compiler internal structures in "tclInt.h".
* generic/tclCompile.h: S.a. Removed function declarations.
* generic/tclCompile.c: S.a. Adapted to changed signatures.
2001-10-15 Jeff Hobbs <jeffh@ActiveState.com>
- * unix/configure:
- * unix/configure.in:
- * win/configure:
- * win/configure.in:
- * win/tcl.m4: reworked to be a little cleaner in comparison to
- each other, and to AC_SUBST even empty vars for win/tclConfig.sh
+ * unix/configure:
+ * unix/configure.in:
+ * win/configure:
+ * win/configure.in:
+ * win/tcl.m4: reworked to be a little cleaner in comparison to each
+ other, and to AC_SUBST even empty vars for win/tclConfig.sh
* generic/tclFileName.c: minor code cleanup
- * generic/tcl.h: moved #define of WIN32 to tcl.h where __WIN32__
- is defined and added #ifndef check.
+ * generic/tcl.h: moved #define of WIN32 to tcl.h where __WIN32__ is
+ defined and added #ifndef check.
* doc/open.n: moved all fconfigure option docs to fconfigure.n
* doc/fconfigure.n: added serial config options
* win/tclWinChan.c:
* win/tclWinPort.h:
- * win/tclWinSerial.c: added TIP #35 Windows enhancements for
- serial configuration. [Patch #438509] (schroedter)
+ * win/tclWinSerial.c: added TIP #35 Windows enhancements for serial
+ configuration. [Patch 438509] (schroedter)
2001-10-15 Vince Darley <vincentdarley@users.sourceforge.net>
* generic/tclFCmd.c: fix to memory leak in TclFileDeleteCmd on
certain error conditions.
* doc/FileSystem.3: fix to typo.
-
+
2001-10-12 Jeff Hobbs <jeffh@ActiveState.com>
* library/encoding/ebcdic.enc:
* tools/encoding/ebcdic.txt: EBCDIC charset mapping.
- [Patch #219323] (nijtmans)
+ [Patch 219323] (nijtmans)
* library/encoding/tis-620.enc:
* tools/encoding/tis-620.txt: TIS-620 charset mapping.
- [Patch #467423] (poonlap)
+ [Patch 467423] (poonlap)
* tests/http.test: added removeFile for outdata
- * tests/ioCmd.test: added catch around file removal, as Windows
- file locking throws errors.
+ * tests/ioCmd.test: added catch around file removal, as Windows file
+ locking throws errors.
* tests/socket.test (socket-7.2): corrected to work on Win2K.
2001-10-12 Miguel Sofer <msofer@users.sourceforge.net>
-
+
* tests/compile.test: new tests for [Bug 467523]; they are only
effective if TCL_MEM_DEBUG was set during compilation.
2001-10-11 Miguel Sofer <msofer@users.sourceforge.net>
-
+
* generic/tclLiteral.c (TclReleaseLiteral): insured that
self-referential bytecodes are properly cleaned up on interpreter
deletion [Bug 467523] (Ronnie Brunner)
2001-10-10 David Gravereaux <davygrvy@pobox.com>
- * win/tclWinPort.h: #include <winsock2.h> needed to get moved
- to after #include <windows.h> or wierd misunderstandings took
- place when -D_WIN32_WINNT=0x0400 is set for outside code that
- requires knowledge of Tcl innards. General header macro magic
- applied liberally...
+ * win/tclWinPort.h: #include <winsock2.h> needed to get moved to
+ after #include <windows.h> or wierd misunderstandings took place when
+ -D_WIN32_WINNT=0x0400 is set for outside code that requires knowledge
+ of Tcl innards. General header macro magic applied liberally...
2001-10-10 Don Porter <dgp@users.sourceforge.net>
@@ -1151,20 +1122,20 @@
2001-10-09 Jeff Hobbs <jeffh@ActiveState.com>
- * generic/tclFileName.c (Tcl_SplitPath): corrected mem leak
- intro'd with VFS code where the result obj from Tcl_FSSplitPath
- was not getting freed.
+ * generic/tclFileName.c (Tcl_SplitPath): corrected mem leak intro'd
+ with VFS code where the result obj from Tcl_FSSplitPath was not
+ getting freed.
2001-10-09 Miguel Sofer <msofer@users.sourceforge.net>
-
- * generic/tclLiteral.c: (TclReleaseLiteral) reverted previous
- patch for [Bug 467523] - cure is worse than the illness.
+
+ * generic/tclLiteral.c: (TclReleaseLiteral) reverted previous patch
+ for [Bug 467523] - cure is worse than the illness.
2001-10-05 Miguel Sofer <msofer@users.sourceforge.net>
-
+
* generic/tclLiteral.c: (TclReleaseLiteral) insured that
self-referential bytecodes are properly cleaned up on interpreter
- deletion [Bug 467523] (Ronnie Brunner)
+ deletion. [Bug 467523] (Ronnie Brunner)
2001-10-04 Jeff Hobbs <jeffh@ActiveState.com>
@@ -1217,18 +1188,18 @@
* tools/encoding/macIceland.txt:
* tools/encoding/macRoman.txt:
* tools/encoding/macTurkish.txt:
- Updated encodings with latest mappings from www.unicode.org. This
- did not include some Mac encodings that have special multi-unichar
- translations now (like symbols, dingbats and japanese). Also does
- not include big5, gb or euc* as those have different formats in
- the latest Unicode version that need new conversion tools. Not
- all related .enc files changed as some had been updates separately.
+ Updated encodings with latest mappings from www.unicode.org. This did
+ not include some Mac encodings that have special multi-unichar
+ translations now (like symbols, dingbats and japanese). Also does not
+ include big5, gb or euc* as those have different formats in the latest
+ Unicode version that need new conversion tools. Not all related .enc
+ files changed as some had been updates separately.
2001-10-03 Jeff Hobbs <jeffh@ActiveState.com>
* generic/tclEvent.c (Tcl_FinalizeThread): moved freeing of
- tclLibraryPath to before the thread exit handlers are called.
- Slight modification to change on 2001-09-24.
+ tclLibraryPath to before the thread exit handlers are called. Slight
+ modification to change on 2001-09-24.
2001-10-01 Jeff Hobbs <jeffh@ActiveState.com>
@@ -1245,45 +1216,44 @@
* generic/tclCmdIL.c:
* generic/tclCmdMZ.c:
* generic/tclParseExpr.c: removed unnecessary inclusion of
- tclCompile.h and made a small modification in (InfoBodyCmd) to
- improve the isolation of the compiler/engine subsystem.
+ tclCompile.h and made a small modification in (InfoBodyCmd) to improve
+ the isolation of the compiler/engine subsystem.
2001-09-29 Vince Darley <vincentdarley@users.sourceforge.net>
* generic/tclIOUtil.c:
- * doc/FileSystem.3: corrected and clarified documentation
- for 'Tcl_FSListVolumes(Proc)'. No code changes.
-
+ * doc/FileSystem.3: corrected and clarified documentation for
+ 'Tcl_FSListVolumes(Proc)'. No code changes.
+
2001-09-28 Miguel Sofer <msofer@users.sourceforge.net>
- * doc/FindExec.3: added a comment not to change the working
- directory before calling Tcl_GetNameOfExecutable [Bug 219215]
+ * doc/FindExec.3: added a comment not to change the working directory
+ before calling Tcl_GetNameOfExecutable. [Bug 219215]
2001-09-28 Kevin Kenny <kennykb@users.sourceforge.net>
- * generic/tclIO.c: added two more '(ClientData)' casts
- on calls to Tcl_Preserve and Tcl_Release -- ones that
- Vince apparently missed.
-
+ * generic/tclIO.c: added two more '(ClientData)' casts on calls to
+ Tcl_Preserve and Tcl_Release -- ones that Vince apparently missed.
+
2001-09-28 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* doc/lsort.n: Improved doc...
* generic/tclCmdIL.c (Tcl_LsortObjCmd, SortCompare): Made
- offset-from-end indexing work, and factored out some "magic
- numbers" for easier understanding. [Bug #465674]
+ offset-from-end indexing work, and factored out some "magic numbers"
+ for easier understanding. [Bug 465674]
* tests/cmdIL.test (cmdIL-1.26): Added test for offset-from-end
indexing for lsort.
2001-09-28 Vince Darley <vincentdarley@users.sourceforge.net>
* win/tclWinFCmd.c:
- * unix/tclUnixFCmd.c: fix to performance issue reported
- by jcw in which 'access("")' is called unnecessarily when
- normalizing any absolute path.
+ * unix/tclUnixFCmd.c: fix to performance issue reported by jcw in
+ which 'access("")' is called unnecessarily when normalizing any
+ absolute path.
* generic/tclIO.c: added '(ClientData)' cast to calls to
- Tcl_(Preserve|Release) newly introduced, fixing compile
- error on Windows.
-
+ Tcl_(Preserve|Release) newly introduced, fixing compile error on
+ Windows.
+
2001-09-27 Don Porter <dgp@users.sourceforge.net>
* doc/FileSystem.3 (Tcl_FSLoadFile):
@@ -1305,70 +1275,67 @@
* unix/tclLoadShl.c (TclpLoadFile):
* win/tclWinLoad.c (TclpLoadFile):
* win/tclWinFCmd.c (DoRemoveJustDirectory): More CONST poisoning
- fixes from the 2001-09-24 TIP 27 changes. CONST-ified
- Tcl_FSLoadFile and TclpLoadFile. Report and patch from Kevin
- Kenny. [Bug 465833]
+ fixes from the 2001-09-24 TIP 27 changes. CONST-ified Tcl_FSLoadFile
+ and TclpLoadFile. Report and patch from Kevin Kenny. [Bug 465833]
- * generic/tclIO.c (ChannelTimerProc): Added Tcl_Preserve()
- and Tcl_Release() to fix segfault introduced by the 2001-09-26
- changes. [Bug 465494]
+ * generic/tclIO.c (ChannelTimerProc): Added Tcl_Preserve() and
+ Tcl_Release() to fix segfault introduced by the 2001-09-26 changes.
+ [Bug 465494]
- * doc/TCL_MEM_DEBUG.3: Updated out-of-date reference to
- #define GUARD_SIZE.
+ * doc/TCL_MEM_DEBUG.3: Updated out-of-date reference to #define
+ GUARD_SIZE.
* doc/UpVar.3 (Tcl_UpVar,Tcl_UpVar2):
* generic/tcl.decls (Tcl_UpVar,Tcl_UpVar2):
* generic/tclInt.decls (TclFindProc,TclGetFrame):
* generic/tclInt.h (TclFindProc,TclGetFrame,TclLookupVar,
- TclPrecTraceProc,TclProcInterpProc}):
+ (TclPrecTraceProc,TclProcInterpProc}):
* generic/tclProc.c (TclGetFrame,TclFindProc):
* generic/tclVar.c (Tcl_UpVar,Tcl_UpVar2,MakeUpvar): Updated APIs in
- generic/tclProc.c and generic/tclVar.c according to the guidelines
- of TIP 27. [Patch 465442]
+ generic/tclProc.c and generic/tclVar.c according to the guidelines of
+ TIP 27. [Patch 465442]
* generic/tclDecls.h:
* generic/tclIntDecls.h: make genstubs
-2001-09-26 Andreas Kupries <andreas_kupries@users.sourceforge.net>
-
- * doc/fileevent.n: Accepted [Patch #465279] adding an example to
- the fileevent manpage. Minor modifications to get a better
- formatting. Report and patch by David N. Welton
- <davidw@users.sourceforge.net>.
-
- * The changes below fix [Bug #462317] where Expect tried to read
- more than was in the buffers and then blocked in the OS call as
- its pty channel driver provides no blockmodeproc through which
- the OS could be notified of blocking-behaviour. Because of this
- the general I/O core has to take more care than usual to
- preserve the semantics of non-blocking channels.
-
- The problem was reported by "Kevin O'Gorman"
- <kevin@kosmanor.com>.
-
- * generic/tclIO.c (Tcl_ReadRaw): Do not read from the driver if
- the channel is non-blocking and the fileevent causing the read
- was generated by a timer. We do not know if there is data
- available from the OS. Instead of going to the OS for more and
- potentially blocking we simply signal EWOULDBLOCK to the higher
- levels to cause the system to wait for true fileevents.
- (GetInput): Same as before.
- (ChannelTimerProc): Added set and clear of CHANNEL_TIMER_FEV.
-
- * generic/tclIO.h (CHANNEL_TIMER_FEV): New flag for channels. Is
- set if a fileevent was generated by a timer, the channel is not
- blocking and the driver did not provide a blockmodeproc. In that
- case the I/O core has to be especially careful about going to
- the driver for more data.
+2001-09-26 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * doc/fileevent.n: Accepted [Patch 465279] adding an example to the
+ fileevent manpage. Minor modifications to get a better formatting.
+ Report and patch by David N. Welton <davidw@users.sourceforge.net>.
+
+ * The changes below fix [Bug 462317] where Expect tried to read more
+ than was in the buffers and then blocked in the OS call as its pty
+ channel driver provides no blockmodeproc through which the OS could be
+ notified of blocking-behaviour. Because of this the general I/O core
+ has to take more care than usual to preserve the semantics of
+ non-blocking channels.
+
+ The problem was reported by "Kevin O'Gorman" <kevin@kosmanor.com>.
+
+ * generic/tclIO.c (Tcl_ReadRaw): Do not read from the driver if the
+ channel is non-blocking and the fileevent causing the read was
+ generated by a timer. We do not know if there is data available from
+ the OS. Instead of going to the OS for more and potentially blocking
+ we simply signal EWOULDBLOCK to the higher levels to cause the system
+ to wait for true fileevents.
+ (GetInput): Same as before.
+ (ChannelTimerProc): Added set and clear of CHANNEL_TIMER_FEV.
+
+ * generic/tclIO.h (CHANNEL_TIMER_FEV): New flag for channels. Is set
+ if a fileevent was generated by a timer, the channel is not blocking
+ and the driver did not provide a blockmodeproc. In that case the I/O
+ core has to be especially careful about going to the driver for more
+ data.
2001-09-26 Don Porter <dgp@users.sourceforge.net>
* doc/SplitPath.3 (Tcl_GetPathType):
* generic/tcl.decls (Tcl_GetPathType):
* generic/tclFileName.c (Tcl_GetPathType):
- * win/tclWinFile.c (TclpMatchInDirectory, NativeStat): Vince
- Darley reports the 2001-09-24 TIP 27 changes left the win
- directory CONST poisoned. These changes should fix that.
+ * win/tclWinFile.c (TclpMatchInDirectory, NativeStat): Vince Darley
+ reports the 2001-09-24 TIP 27 changes left the win directory CONST
+ poisoned. These changes should fix that.
* generic/tclDecls.h: make genstubs
@@ -1378,17 +1345,17 @@
* generic/tclInt.h (TclGetLong deleted):
* generic/tcl.decls:
* generic/tclInt.decls:
- * generic/tclGet.c: Updated APIs in generic/tclGet.c
- according to the guidelines of TIP 27. [Patch 464674]
+ * generic/tclGet.c: Updated APIs in generic/tclGet.c according to the
+ guidelines of TIP 27. [Patch 464674]
- * generic/tclDecls.h:
+ * generic/tclDecls.h:
* generic/tclIntDecls.h: make genstubs
2001-09-25 Miguel Sofer <msofer@users.sourceforge.net>
* generic/tclVar.c: removed comments referring to unused flag
- TCL_PARSE_PART1.
-
+ TCL_PARSE_PART1.
+
2001-09-24 Don Porter <dgp@users.sourceforge.net>
* doc/Concat.3:
@@ -1400,37 +1367,34 @@
* generic/tclEncoding.c (OpenEncodingFile):
* generic/tclMain.c (Tcl_Main):
* generic/tclUtil.c:
- * unix/tclLoadDl.c (TclpLoadFile): Updated APIs in
- generic/tclUtil.c according to the guidelines of TIP 27.
- [Patch 464553]
+ * unix/tclLoadDl.c (TclpLoadFile): Updated APIs in generic/tclUtil.c
+ according to the guidelines of TIP 27. [Patch 464553]
- * generic/tclDecls.h:
+ * generic/tclDecls.h:
* generic/tclIntDecls.h: make genstubs
2001-09-24 Andreas Kupries <andreas_kupries@users.sourceforge.net>
- * The change below fixes [Bug #464380]. The bug was reported by
- Ronnie Brunner <rbrunner@users.sourceforge.net>. He also
- provided the patch.
-
- * generic/tclEvent.c (Tcl_Finalize): Moved release of
- 'tclLibraryPath' to Tcl_FinalizeThread.
- (Tcl_FinalizeThread): See above, new place for release of
- 'tclLibraryPath'.
+ The change below fixes [Bug 464380]. The bug was reported by Ronnie
+ Brunner <rbrunner@users.sourceforge.net>. He also provided the patch.
+
+ * generic/tclEvent.c (Tcl_Finalize): Moved release of 'tclLibraryPath'
+ to Tcl_FinalizeThread.
+ (Tcl_FinalizeThread): See above, new place for release of
+ 'tclLibraryPath'.
2001-09-24 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* tools/encoding/cp1252.txt: File was missing part of the encoding
- [euro, ZCaron and zcaron].
+ [euro, ZCaron and zcaron].
- * doc/OpenFileChnl.3: Add docs for Tcl_OutputBuffered; remove some
- old changebars.
+ * doc/OpenFileChnl.3: Add docs for Tcl_OutputBuffered; remove some old
+ changebars.
2001-09-21 Jeff Hobbs <jeffh@ActiveState.com>
- * generic/tclExecute.c (TclExecuteByteCode): corrected
- INST_STR_CMP else case for strings to pass true utf char length
- to Tcl_UtfNCmp.
+ * generic/tclExecute.c (TclExecuteByteCode): corrected INST_STR_CMP
+ else case for strings to pass true utf char length to Tcl_UtfNCmp.
2001-09-20 Jeff Hobbs <jeffh@ActiveState.com>
@@ -1439,30 +1403,30 @@
* win/tclWinSock.c (SocketThread): corrected pointer cast for _WIN64.
* win/tclWinNotify.c: removed unnecessary winsock include (it is
- already in from tclWinPort.h).
+ already in from tclWinPort.h).
- * win/tclWinPort.h: changed winsock.h include to winsock2.h.
- Reverses change from 2000-11-16, but is necessary for WIN64.
- Extensions should comply with defined OS words, or use #ifndef.
+ * win/tclWinPort.h: changed winsock.h include to winsock2.h. Reverses
+ change from 2000-11-16, but is necessary for WIN64. Extensions should
+ comply with defined OS words, or use #ifndef.
2001-09-20 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * tests/socket.test: removed dependence on being run from same dir
- as remote.tcl, which only now needs to be in the same dir as
- this file. [Bug #219326]
+ * tests/socket.test: removed dependence on being run from same dir as
+ remote.tcl, which only now needs to be in the same dir as this file.
+ [Bug 219326]
2001-09-19 Jeff Hobbs <jeffh@ActiveState.com>
* generic/tclTest.c (TestcmdtokenCmd): corrected pointer
- storage/retrieval for 64bit machines.
+ storage/retrieval for 64bit machines.
* generic/tclCmdAH.c (Tcl_FormatObjCmd):
- * generic/tclScan.c (Tcl_ScanObjCmd): corrected handling of format
- and scan on 64-bit machines. [Bug #412696] (rmax)
+ * generic/tclScan.c (Tcl_ScanObjCmd): corrected handling of format and
+ scan on 64-bit machines. [Bug 412696] (rmax)
* unix/configure: regen'ed
- * unix/tcl.m4: added --enable-64bit support for HP-11 with the
- 64-bit kernel.
+ * unix/tcl.m4: added --enable-64bit support for HP-11 with the 64-bit
+ kernel.
* tests/basic.test:
* tests/cmdInfo.test: improved skip reporting of missing commands
@@ -1471,10 +1435,10 @@
* tests/winPipe.test: removed obsolete cat16 tests
- * generic/tclExecute.c (TclExecuteByteCode): fixed invalid usage
- of valuePtr in TRACE_WITH_OBJ in INST_EVAL_STK case. [Bug #462594]
- Changed INST_STR_CMP instruction to promote to Unicode strings
- only when one of the strings is already of Unicode type.
+ * generic/tclExecute.c (TclExecuteByteCode): fixed invalid usage of
+ valuePtr in TRACE_WITH_OBJ in INST_EVAL_STK case. [Bug 462594] Changed
+ INST_STR_CMP instruction to promote to Unicode strings only when one
+ of the strings is already of Unicode type.
* generic/tclExecute.c (TclExecuteByteCode):
* generic/tclCompile.c (instructionTable):
@@ -1486,77 +1450,75 @@
* tests/{for.test,foreach.test,if.test,while.test}:
* generic/tclCompCmds.c (TclCompileForCmd, TclCompileForeachCmd,
TclCompileIfCmd, TclCompileWhileCmd): Corrected the overaggressive
- compiling of loop bodies enclosed in ""s. [Bug #219166] (msofer)
+ compiling of loop bodies enclosed in ""s. [Bug 219166] (msofer)
2001-09-19 Miguel Sofer <msofer@users.sourceforge.net>
-
- * generic/tclExecute.c: insured that execution stack errors are
- also detected at abnormal returns.
+
+ * generic/tclExecute.c: insured that execution stack errors are also
+ detected at abnormal returns.
2001-09-19 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* doc/socket.n: Added documentation to mention what happens when a
- server socket is created with port=0. Removed an old change bar,
- and no new change bar because Tcl has always behaved this way as
- it is really a poorly-documented standards-defined OS feature.
+ server socket is created with port=0. Removed an old change bar, and
+ no new change bar because Tcl has always behaved this way as it is
+ really a poorly-documented standards-defined OS feature.
* tests/util.test (util-8.1): Test derived from code to detect the
- problem, but the test always works in the C locale, so beware if
- you are maintaining the code.
- * generic/tclUtil.c (TclNeedSpace): Rewrote to be UTF-8 aware.
- [Bug 411825, but not that patch which would have added extra
- spaces if there was a real non-ASCII space involved. ]
+ problem, but the test always works in the C locale, so beware if you
+ are maintaining the code.
+ * generic/tclUtil.c (TclNeedSpace): Rewrote to be UTF-8 aware. [Bug
+ 411825, but not that patch which would have added extra spaces if
+ there was a real non-ASCII space involved.]
-2001-09-18 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+2001-09-18 Andreas Kupries <andreas_kupries@users.sourceforge.net>
* generic/tclIOCmd.c (Tcl_PutsObjCmd): Rewritten to have saner and
- faster argument handling. Fixes bug #123552. Patch provided by
- Donal K. Fellows <fellowsd@cs.man.ac.uk>: #402564.
+ faster argument handling. [Bug 123552], [Patch 402564] (fellows)
2001-09-18 Don Porter <dgp@users.sourceforge.net>
* unix/configure: Regen.
- * unix/tcl.m4 (SC_CONFIG_CFLAGS): On Linux, disable inlining when
- one of the compat/*.c routines is to be linked in. [Patch 440891]
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): On Linux, disable inlining when one
+ of the compat/*.c routines is to be linked in. [Patch 440891]
2001-09-17 Jeff Hobbs <jeffh@ActiveState.com>
- * generic/tcl.h: removed forced #define USE_TCLALLOC 1 for
- Windows. This means the native system allocator will be used by
- default. This should be binary and source compatible with
- extensions, as Tcl_Alloc is a properly stubbed function.
+ * generic/tcl.h: removed forced #define USE_TCLALLOC 1 for Windows.
+ This means the native system allocator will be used by default. This
+ should be binary and source compatible with extensions, as Tcl_Alloc
+ is a properly stubbed function.
2001-09-17 Miguel Sofer <msofer@users.sourceforge.net>
-
- * generic/tclExecute.c: corrected small bug in [Patch 456668] -
- the varFramePtr was not restored in one possible exit.
+
+ * generic/tclExecute.c: corrected small bug in [Patch 456668] - the
+ varFramePtr was not restored in one possible exit.
2001-09-17 Miguel Sofer <msofer@users.sourceforge.net>
-
+
* doc/tclvars.n:
* generic/tclCompile.c:
* generic/tclCompile.h:
* generic/tclExecute.c:
* generic/tclProc.c: disabled all compile and execution tracing
- functionality in standard builds; TCL_COMPILE_DEBUG is now
- necessary to enable it. [Bug 451858]
+ functionality in standard builds; TCL_COMPILE_DEBUG is now necessary
+ to enable it. [Bug 451858]
2001-09-14 Andreas Kupries <andreas_kupries@users.sourceforge.net>
- * doc/gets.n:
- * doc/read.n:
- * doc/puts.n:
- * doc/flush.n:
- * doc/fconfigure.n:
- * doc/flush.n:
- * doc/eof.n:
- * doc/seek.n:
- * doc/tell.n:
- * doc/close.n:
- * doc/fileevent.n: Added references to the Tcl standard
- channels. Item [219250], reported by David LeBlanc
- <whisper@oz.net>. Thanks to Christopher Nelson
- <chris@pinebush.com> for doing editorial work.
+ * doc/gets.n:
+ * doc/read.n:
+ * doc/puts.n:
+ * doc/flush.n:
+ * doc/fconfigure.n:
+ * doc/flush.n:
+ * doc/eof.n:
+ * doc/seek.n:
+ * doc/tell.n:
+ * doc/close.n:
+ * doc/fileevent.n: Added references to the Tcl standard channels. Item
+ [219250], reported by David LeBlanc <whisper@oz.net>. Thanks to
+ Christopher Nelson <chris@pinebush.com> for doing editorial work.
2001-09-13 Andreas Kupries <andreas_kupries@users.sourceforge.net>
@@ -1565,56 +1527,52 @@
* win/makefile.bc:
* win/makefile.vc:
* library/dde/pkgIndex.tcl: Fixed version numbers from bogus tcl
- versions to independent versions for dde and registry packages.
+ versions to independent versions for dde and registry packages.
2001-09-13 Jeff Hobbs <jeffh@ActiveState.com>
* tests/regexp.test (regexp-20.1):
* generic/tclCmdMZ.c (Tcl_RegsubObjCmd): had to adjust fix from
- 2001-08-06 to actually duplicate the objects in certain cases.
- This is really a place where feather would have been essential.
- [Bug #461322]
+ 2001-08-06 to actually duplicate the objects in certain cases. This is
+ really a place where feather would have been essential. [Bug 461322]
* generic/tclUtf.c (Tcl_UtfPrev): corrected to return the proper
- location when the middle of a UTF-8 byte was passed in.
- [Tk Bug #450504]
+ location when the middle of a UTF-8 byte was passed in [Tk Bug 450504]
* ChangeLog.1999:
* ChangeLog: broke changes from 199x into ChangeLog.1999 to reduce
- size of the main ChangeLog.
+ size of the main ChangeLog.
2001-09-13 Andreas Kupries <andreas_kupries@users.sourceforge.net>
* tests/ioCmd.test: Changed the computation of the result for
- iocmd-8.1[123] so that the tests work for single- and
- multi-process execution of the testsuite. Depending on the
- choice of the user stdout is a tty or not and thus reports
- different channel options. Fixes [460993] reported by Don
- Porter.
+ iocmd-8.1[123] so that the tests work for single- and multi-process
+ execution of the testsuite. Depending on the choice of the user stdout
+ is a tty or not and thus reports different channel options. Fixes
+ [460993] reported by Don Porter.
2001-09-13 Miguel Sofer <msofer@users.sourceforge.net>
- * doc/ParseCmd.3:
+ * doc/ParseCmd.3:
* generic/tcl.decls:
* generic/tclCmdMZ.c (Tcl_SubstObjCmd):
* generic/tclDecls.h:
* generic/tclParse.c:
* generic/tclStubInit.c:
- * tests/parse.test: Deprecate the use of Tcl_EvalTokens, replaced
- by the new Tcl_EvalTokensStandard. The new function performs the
- same duties but adheres to the standard return convention for Tcl
+ * tests/parse.test: Deprecate the use of Tcl_EvalTokens, replaced by
+ the new Tcl_EvalTokensStandard. The new function performs the same
+ duties but adheres to the standard return convention for Tcl
evaluations; the deprecated function could only return TCL_OK or
- TCL_ERROR, which caused [Bug 219384] and [Bug 455151].
- This patch implements [TIP 56].
-
+ TCL_ERROR, which caused [Bug 219384] and [Bug 455151]. This patch
+ implements [TIP 56].
+
2001-09-12 Mo DeJong <mdejong@users.sourceforge.net>
* unix/configure: Regen.
- * unix/tcl.m4: Invert the logic that checks for $GCC.
- Instead of checking for "$GCC" = "no" we check for
- "$GCC" != "yes" or simply swap the true and false
- blocks of code in an if statement. That way if
- GCC is set to "" everything will still work. [Bug 460991]
+ * unix/tcl.m4: Invert the logic that checks for $GCC. Instead of
+ checking for "$GCC" = "no" we check for "$GCC" != "yes" or simply swap
+ the true and false blocks of code in an if statement. That way if GCC
+ is set to "" everything will still work. [Bug 460991]
2001-09-12 Don Porter <msofer@users.sourceforge.net>
@@ -1622,8 +1580,8 @@
* tests/lsearch.test:
* tests/namespace.test:
* tests/rename.test:
- * tests/split.test: Corrected tests to better isolate tests in
- one file from influencing tests in other files. [Bug 460591]
+ * tests/split.test: Corrected tests to better isolate tests in one
+ file from influencing tests in other files. [Bug 460591]
2001-09-12 Miguel Sofer <msofer@users.sourceforge.net>
@@ -1633,181 +1591,170 @@
2001-09-11 Andreas Kupries <andreas_kupries@users.sourceforge.net>
* doc/OpenFileChnl.3: Added documentation for Tcl_WriteRaw and
- Tcl_ReadRaw [#414929].
-
- * doc/CrtChannel.3: Added documentation for Tcl_ChannelBuffered
- and Tcl_GetTopChannel [#414929].
+ Tcl_ReadRaw [Bug 414929].
+
+ * doc/CrtChannel.3: Added documentation for Tcl_ChannelBuffered and
+ Tcl_GetTopChannel [Bug 414929].
- * The changes below are a fix for [219253].
+ * The changes below are a fix for [Bug 219253].
* tests/socket.test: Removed _most_ instances of hardwired port
- numbers for listening sockets. Remaining are the ports in all
- tests with constraint 'doTestsWithRemoteServer'. These seem to
- be designed for a more controlled environment and are usually
- skipped when running the testsuite.
+ numbers for listening sockets. Remaining are the ports in all tests
+ with constraint 'doTestsWithRemoteServer'. These seem to be designed
+ for a more controlled environment and are usually skipped when running
+ the testsuite.
- * tests/io.test: Removed all instances of hardwired port numbers
- for listening sockets.
+ * tests/io.test: Removed all instances of hardwired port numbers for
+ listening sockets.
2001-09-10 Jeff Hobbs <jeffh@ActiveState.com>
- * generic/tclEvent.c (TclInExit): Corrected handling of tsd in
- late stages of finalization. [Bug #419449] (darley)
+ * generic/tclEvent.c (TclInExit): Corrected handling of tsd in late
+ stages of finalization. [Bug 419449] (darley)
* tests/stack.test:
* generic/tclInterp.c (AliasObjCmd): Check the numLevels to ensure
- that we aren't hitting some alias loop condition. [Bug #443184]
+ that we aren't hitting some alias loop condition. [Bug 443184]
2001-09-10 Mo DeJong <mdejong@users.sourceforge.net>
* unix/configure: Regen.
- * unix/tcl.m4 (SC_CONFIG_CFLAGS): Don't include . characters
- in the Tcl library name when building on FreeBSD 3.X and later
- systems. [Patch 450725]
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): Don't include . characters in the
+ Tcl library name when building on FreeBSD 3.X and later systems.
+ [Patch 450725]
2001-09-10 Andreas Kupries <andreas_kupries@users.sourceforge.net>
* doc/tclsh.1:
- * doc/Tcl_Main.3:
- * doc/CrtChannel.3:
- * doc/OpenFileChnl.3:
+ * doc/Tcl_Main.3:
+ * doc/CrtChannel.3:
+ * doc/OpenFileChnl.3:
* doc/GetStdChan.3: Enhanced the manpages with cross-references to
- the new manpage and more explanations how these functions deal
- with the standard channels in various situations.
+ the new manpage and more explanations how these functions deal with
+ the standard channels in various situations.
- * doc/StdChannels.3: New manpage describing handling of the
- standard channels by the Tcl library [402725].
+ * doc/StdChannels.3: New manpage describing handling of the standard
+ channels by the Tcl library. [Bug 402725]
2001-09-10 Don Porter <dgp@users.sourceforge.net>
- * unix/mkLinks (Tcl_FSLink): Updated to reflect 2001-08-23
- file system changes.
+ * unix/mkLinks (Tcl_FSLink): Updated to reflect 2001-08-23 file system
+ changes.
* unix/tclLoadShl.c: Added #include of tclInt.h; access to Tcl
- internals, notably TclpUnloadFile(), is required. Thanks to
- Bob Techentin for report and patch. [Bug 459305]
+ internals, notably TclpUnloadFile(), is required. Thanks to Bob
+ Techentin for report and patch. [Bug 459305]
* generic/tclInitScript.h (initScript):
* win/tclWinInit.c (TCL_REGISTRY_KEY, TclpSetVariables): Removed
- vestiges of Tcl's old initialization from registry variables.
- [Bug 455645]
+ vestiges of Tcl's old initialization from registry variables. [Bug
+ 455645]
2001-09-10 Andreas Kupries <andreas_kupries@users.sourceforge.net>
- * generic/tclInt.decls: Also added 'TclWinFlushDirtyChannels' to
- the internal platform specific stub table.
+ * generic/tclInt.decls: Also added 'TclWinFlushDirtyChannels' to the
+ internal platform specific stub table.
* win/tclWinFile.c (TclpObjStat): Now added the call to
- 'TclWinFlushDirtyChannels' to this function. I don't know where
- my head was last thursday (2001-09-06), but the call was
- actually added to 'TclpObjChdir', i.e. the implementation of
- [cd]. Corrected this now. Thanks to Vince Darley for spotting
- this.
+ 'TclWinFlushDirtyChannels' to this function. I don't know where my
+ head was last thursday (2001-09-06), but the call was actually added
+ to 'TclpObjChdir', i.e. the implementation of [cd]. Corrected this
+ now. Thanks to Vince Darley for spotting this.
2001-09-10 Miguel Sofer <msofer@users.sourceforge.net>
* generic/tclProc.c:
- * tests/proc.test: made [proc] bytecompile a no-op for procs
- defined with _args_ as single argument and an empty body.
- [FQ 451441]
-
+ * tests/proc.test: made [proc] bytecompile a no-op for procs defined
+ with _args_ as single argument and an empty body. [FRQ 451441]
+
2001-09-09 Mo DeJong <mdejong@users.sourceforge.net>
* unix/Makefile.in:
- * win/Makefile.in: Use () around variable name
- instead of {}. Use TCLTEST variable directly
- instead of depending on the tcltest alias.
+ * win/Makefile.in: Use () around variable name instead of {}. Use
+ TCLTEST variable directly instead of depending on the tcltest alias.
2001-09-09 David Gravereaux <davygrvy@pobox.com>
* generic/tcl.h:
- * generic/tclPlatDecls.h: Reminder from David Cuthbert <dacut@kanga.org>
- that I hadn't finished the Borland compatibility stuff.
- [Patch: 436116]
+ * generic/tclPlatDecls.h: Reminder from David Cuthbert
+ <dacut@kanga.org> that I hadn't finished the Borland compatibility
+ stuff. [Patch 436116]
2001-09-09 Mo DeJong <mdejong@users.sourceforge.net>
- * tests/cmdAH.test: Modify cmdAH-20.5 and cmdAH-24.8
- to display the file atime or mtime results if
- the test fails.
+ * tests/cmdAH.test: Modify cmdAH-20.5 and cmdAH-24.8 to display the
+ file atime or mtime results if the test fails.
2001-09-08 David Gravereaux <davygrvy@pobox.com>
* win/mkd.bat:
- * win/rmd.bat: made these text files, text files again.
- [Patch: 451333]
+ * win/rmd.bat: made these text files, text files again. [Patch 451333]
2001-09-08 Mo DeJong <mdejong@users.sourceforge.net>
* win/mkd.bat:
- * win/rmd.bat:
- Apply binary property (cvs admin -kb) to files and convert
- to CRLF linefeed format to fix the VC++ build. [Bug #219409]
+ * win/rmd.bat: Apply binary property (cvs admin -kb) to files and
+ convert to CRLF linefeed format to fix the VC++ build. [Bug 219409]
2001-09-08 Vince Darley <vincentdarley@users.sourceforge.net>
- * generic/tclInt.h:
+ * generic/tclInt.h:
* generic/tclFCmd.c:
* doc/FileSystem.3:
- * generic/tclIOUtil.c: removed Tcl_FSCopyFile fallback
- to channel copying, since the channels will not have
- access to interpreters and the channel copying currently
- requires an interp. Code which required cross-platform
- copies always has interpreters, so that solves the problem.
- Fixes bug in TclKit.
-
+ * generic/tclIOUtil.c: removed Tcl_FSCopyFile fallback to channel
+ copying, since the channels will not have access to interpreters and
+ the channel copying currently requires an interp. Code which required
+ cross-platform copies always has interpreters, so that solves the
+ problem. Fixes bug in TclKit.
+
2001-09-07 David Gravereaux <davygrvy@pobox.com>
- * win/tcl.m4: Added -link50compat option so a VC6 linker makes
- a VC5 (pre sp3) compatible import library.
- [Bug: 219257]
+ * win/tcl.m4: Added -link50compat option so a VC6 linker makes a VC5
+ (pre sp3) compatible import library. [Bug 219257]
2001-09-07 Mo DeJong <mdejong@users.sourceforge.net>
* win/tclWinThrd.c (TclpThreadExit): Cast status argument to
- _endthreadex to unsigned instead of DWORD to match the Win32
- function prototype.
+ _endthreadex to unsigned instead of DWORD to match the Win32 function
+ prototype.
2001-09-06 Andreas Kupries <andreas_kupries@users.sourceforge.net>
- * All the changes below serve to fix bug [219148] which reports a
- 80x performance hit for file I/O on Win* systems. On my system
- it was closer to a 120x hit. Problem report by Uwe Traum <no
- email address available>.
+ * All the changes below serve to fix bug [219148] which reports a 80x
+ performance hit for file I/O on Win* systems. On my system it was
+ closer to a 120x hit. Problem report by Uwe Traum <no email address
+ available>.
- The fix goes like this: The obstacle is 'FlushFileBuffers',
- executed whenever Tcl writes data to the OS, as Tcl has to wait
- for the disk to complete I/O, and disks are slow. We remove that
- obstacle. This opens another problem, [file size] reports back
- wrong numbers. So for [file size] we add the call back in. As
- optimization we keep track of the channels which were written to
- and flush only these.
+ The fix goes like this: The obstacle is 'FlushFileBuffers', executed
+ whenever Tcl writes data to the OS, as Tcl has to wait for the disk to
+ complete I/O, and disks are slow. We remove that obstacle. This opens
+ another problem, [file size] reports back wrong numbers. So for [file
+ size] we add the call back in. As optimization we keep track of the
+ channels which were written to and flush only these.
* win/tclWinFile.c (TclpObjStat): Added a call to
- 'TclWinFlushDirtyChannels'. This ensures that [file size] and
- related commands report the correct size of a file even if Tcl
- has recently written to it. Unixoid OS's always report the
- correct size even for files with pending data, but Win*
- syssystem don't. They only report what is actually on disk.
+ 'TclWinFlushDirtyChannels'. This ensures that [file size] and related
+ commands report the correct size of a file even if Tcl has recently
+ written to it. Unixoid OS's always report the correct size even for
+ files with pending data, but Win* syssystem don't. They only report
+ what is actually on disk.
- * win/tclWinInt.h: Added declaration of
- 'TclWinFlushDirtyChannels', making it available to other parts
- of the tcl core.
+ * win/tclWinInt.h: Added declaration of 'TclWinFlushDirtyChannels',
+ making it available to other parts of the tcl core.
* win/tclWinChan.c (TclWinFlushDirtyChannels): New, internal,
- procedure. Goes through the list of open file channels and
- forces the OS to flush its file buffers for all which were
- written to since the last call of this function. This is an
- expensive operation as Tcl has to wait for the OS to complete
- actual writes to the disk.
+ procedure. Goes through the list of open file channels and forces the
+ OS to flush its file buffers for all which were written to since the
+ last call of this function. This is an expensive operation as Tcl has
+ to wait for the OS to complete actual writes to the disk.
- (FileInfo): Added dirty flag required by the procedure above.
+ (FileInfo): Added dirty flag required by the procedure above.
- (FileOutputProc): Removed flushing of file buffers, setting the
- dirty flag instead. This means that the previously incurred
- delays do not happen anymore.
+ (FileOutputProc): Removed flushing of file buffers, setting the dirty
+ flag instead. This means that the previously incurred delays do not
+ happen anymore.
- (TclWinOpenFileChannel): Added initialization of 'dirty' flag.
+ (TclWinOpenFileChannel): Added initialization of 'dirty' flag.
2001-09-06 Jeff Hobbs <jeffh@ActiveState.com>
@@ -1815,48 +1762,48 @@
* tests/http.test:
* library/http/pkgIndex.tcl:
* library/http/http.tcl (geturl): correctly get charset parameter
- and convert text according to specified encoding (if known). RFC
- iso8859-1 is used by default. Also recognize Content-encoding to
- see if we should do binary translation. Added a CYA -binary
- switch for the cases that were missed. [Bug #219211 #219399]
+ and convert text according to specified encoding (if known). RFC
+ iso8859-1 is used by default. Also recognize Content-encoding to see
+ if we should do binary translation. Added a CYA -binary switch for the
+ cases that were missed. [Bugs 219211, 219399]
* tests/ioUtil.test: changed to make better use of constraints and
remove knownBug constraints that weren't valid.
2001-09-06 Don Porter <dgp@users.sourceforge.net>
- * tests/unixInit.test (unixInit-3.2): Updated test to support
- newer HP-UX releases that properly report euc-jp as the system
- encoding for Japanese. Bug report and patch verification by Bob
- Techentin. [Bug 453883]
+ * tests/unixInit.test (unixInit-3.2): Updated test to support newer
+ HP-UX releases that properly report euc-jp as the system encoding for
+ Japanese. Bug report and patch verification by Bob Techentin. [Bug
+ 453883]
* doc/http.n:
* library/http/*.tcl:
* tools/tcl.wse.in:
* tools/tclmin.wse:
* unix/Makefile.in:
- * win/{Mm}akefile.*: Updated http package to version 2.4,
- reflecting the new features just added.
+ * win/{Mm}akefile.*: Updated http package to version 2.4, reflecting
+ the new features just added.
2001-09-06 Vince Darley <vincentdarley@users.sourceforge.net>
- * generic/tclTest.c: tests of old-fs hooks no longer cause problems
- in threaded builds. Also removed unused unload proc.
+ * generic/tclTest.c: tests of old-fs hooks no longer cause problems in
+ threaded builds. Also removed unused unload proc.
* generic/tcl.decls:
- * generic/tclIOUtilc: added Tcl_FSMountsChanged so that a vfs
- can inform the filesystem that the filesystem epoch must be
- changed (since cached filesystems may now be incorrect). Fixes
- problem running tclvfs extension.
- * library/tcltest/tcltest.tcl: if tests aren't in a native
- filesystem, then don't use pipes to run them. [Bug 458741]
-
+ * generic/tclIOUtilc: added Tcl_FSMountsChanged so that a vfs can
+ inform the filesystem that the filesystem epoch must be changed (since
+ cached filesystems may now be incorrect). Fixes problem running tclvfs
+ extension.
+ * library/tcltest/tcltest.tcl: if tests aren't in a native filesystem,
+ then don't use pipes to run them. [Bug 458741]
+
2001-09-06 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * generic/tcl.decls (479 generic):
- * generic/tclIO.c (Tcl_Seek,Tcl_Tell,Tcl_OutputBuffered): Added
- public function to return the size of the output buffer and
- reworked other channel functions to use this shared functionality
- and that of Tcl_InputBuffered() too. [TIP#49, Rolf Schroedter]
+ * generic/tcl.decls (479 generic):
+ * generic/tclIO.c (Tcl_Seek,Tcl_Tell,Tcl_OutputBuffered): Added public
+ function to return the size of the output buffer and reworked other
+ channel functions to use this shared functionality and that of
+ Tcl_InputBuffered() too. [TIP#49, Rolf Schroedter]
2001-09-05 David Gravereaux <davygrvy@pobox.com>
@@ -1864,39 +1811,36 @@
support.
* win/tclWinPipe.c:
- * win/tclWinPort.h: More Borland compatibility fixes. Changed
- EDQUOT #define from 49 to 69. Borland had a clash as it was already
- using this number. Upon advice from Helmut Giese, EDQUOT has been
- found in other header files #defined as 69.
- [Patch: 436116]
+ * win/tclWinPort.h: More Borland compatibility fixes. Changed EDQUOT
+ #define from 49 to 69. Borland had a clash as it was already using
+ this number. Upon advice from Helmut Giese, EDQUOT has been found in
+ other header files #defined as 69. [Patch 436116]
* win/.cvsignore: A few more glob patterns added.
* win/makefile.bc (new): Borland lives once more! rejoice..
* generic/tclAlloc.c: Small Borland compatibility fix.
- * win/tclWinTime.c: More Borland compatibility fixes.
- [Patch: 436116]
+ * win/tclWinTime.c: More Borland compatibility fixes. [Patch 436116]
2001-09-05 Vince Darley <vincentdarley@users.sourceforge.net>
- * tests/winFCmd.test: made notWin2000 constraint false if not
- running on Windows at all.
-
+ * tests/winFCmd.test: made notWin2000 constraint false if not running
+ on Windows at all.
+
2001-09-04 David Gravereaux <davygrvy@pobox.com>
- * win/tclWinThrd.c: Revisited _beginthreadex() stuff. Instead
- of assuming a c-runtime implimentation of _beginthreadex normal,
- I reversed the logic to not assume, and use when is by explicitly
+ * win/tclWinThrd.c: Revisited _beginthreadex() stuff. Instead of
+ assuming a c-runtime implimentation of _beginthreadex normal, I
+ reversed the logic to not assume, and use when is by explicitly
needing to add runtimes that support it such as Borland.
* generic/tcl.h:
- * generic/tclPlatDecls.h: Borland compatibility change so
- ClientData was properly typed as a void* and TCHAR would not be
- defined twice.
+ * generic/tclPlatDecls.h: Borland compatibility change so ClientData
+ was properly typed as a void* and TCHAR would not be defined twice.
- * generic/tcl.h: Removed a small mistake from before. Changes to
- the EXTERN macro for proper Borland compatibility will have to see
- a TIP. What's this with the MS compiler:
+ * generic/tcl.h: Removed a small mistake from before. Changes to the
+ EXTERN macro for proper Borland compatibility will have to see a TIP.
+ What's this with the MS compiler:
__declspec(dllexport) int func (int a, int b);
@@ -1908,115 +1852,110 @@
2001-09-04 Don Porter <dgp@users.sourceforge.net>
- * compat/strtod.c (strtod): Fixed failure to handle expressions
- like 3eq2 and failure to set errno on overflow. [Bug 440894]
+ * compat/strtod.c (strtod): Fixed failure to handle expressions like
+ 3eq2 and failure to set errno on overflow. [Bug 440894]
2001-09-04 Miguel Sofer <msofer@users.sourceforge.net>
* generic/tclProc.c:
- * tests/proc.test: made [proc] check that formal args have
- simple names [Bug 458548]
+ * tests/proc.test: made [proc] check that formal args have simple
+ names. [Bug 458548]
2001-09-04 Vince Darley <vincentdarley@users.sourceforge.net>
- Minor bug fixes in filesystem, plus small vfs changes as a
- result of enabling the test filesystem to work properly.
+ Minor bug fixes in filesystem, plus small vfs changes as a result of
+ enabling the test filesystem to work properly.
* tests/fileName.test: ensure new test cleans up after itself
- * doc/filename.n:
- * generic/tclFileName.c: improved Mac path handling and document
- why [Bug: 421842] on Windows handling of UNC paths is not valid.
- Documentation and code now much clearer on what is and is not a
- UNC path.
+ * doc/filename.n:
+ * generic/tclFileName.c: improved Mac path handling and document why
+ [Bug 421842] on Windows handling of UNC paths is not valid.
+ Documentation and code now much clearer on what is and is not a UNC
+ path.
* doc/FileSystem.3:
* unix/tclUnixPipe.c:
* generic/tclFCmd.c:
- * generic/tclIOUtil.c: fixed error message, fixed [Bug: 453512]
- about dangerous use of tmpnam, replaced with mkstemp.
- Documented all the changes.
- * generic/tclTest.c: made test vfs fully functional as a
- 'reporting filesystem'.
+ * generic/tclIOUtil.c: fixed error message, fixed [Bug 453512] about
+ dangerous use of tmpnam, replaced with mkstemp. Documented all the
+ changes.
+ * generic/tclTest.c: made test vfs fully functional as a 'reporting
+ filesystem'.
* generic/tcl.stubs:
* generic/tcl.h:
- * generic/tclInt.h:
+ * generic/tclInt.h:
* generic/tclIOUtil.c:
* doc/file.n:
- * various platform-specific 'TclpLoadFile': fixed comments about
- unload behaviour, and completed objectification of loading.
- Required change to Tcl_Filesystem lookup table, so incompatible
- with 8.4a3, but not older versions of Tcl. The change also
- allows 'link' and 'reporting' filesystems to function correctly
- when loading files. Implementation of 'file delete -force'
- copes with case where cwd is inside the directory. Moved
- overlooked Tcl_FSGetPathType from internal to external API.
- Made sure filesystems which are registered and then unregistered
- are only freed when all references to them are gone.
+ * various platform-specific 'TclpLoadFile': fixed comments about
+ unload behaviour, and completed objectification of loading. Required
+ change to Tcl_Filesystem lookup table, so incompatible with 8.4a3, but
+ not older versions of Tcl. The change also allows 'link' and
+ 'reporting' filesystems to function correctly when loading files.
+ Implementation of 'file delete -force' copes with case where cwd is
+ inside the directory. Moved overlooked Tcl_FSGetPathType from internal
+ to external API. Made sure filesystems which are registered and then
+ unregistered are only freed when all references to them are gone.
Documented changes.
- * unix/tclUnixFCmd.c: when deleting directories recursively,
- make sure permissions are ok. Together with the above, this
- fixes [Bug: 219139]
- * tests/winFCmd.test: differentiated test results for win2k
- versus not. This fixes [Bug: 219239]
- * tests/fCmd.test: added tests for 'file delete -force' where
- the cwd is inside, and when permissions are inadequate.
-
+ * unix/tclUnixFCmd.c: when deleting directories recursively, make sure
+ permissions are ok. Together with the above, this fixes [Bug 219139]
+ * tests/winFCmd.test: differentiated test results for win2k versus
+ not. This fixes [Bug: 219239]
+ * tests/fCmd.test: added tests for 'file delete -force' where the cwd
+ is inside, and when permissions are inadequate.
+
2001-09-04 Miguel Sofer <msofer@users.sourceforge.net>
- * generic/tclCompile.c: fixed incorrect operands for INST_LIST
- [Bug: 458241] (David Cuthbert, dacut@users.sourceforge.net)
+ * generic/tclCompile.c: fixed incorrect operands for INST_LIST [Bug
+ 458241] (David Cuthbert, dacut@users.sourceforge.net)
2001-09-03 Jeff Hobbs <jeffh@ActiveState.com>
- * generic/tclExecute.c (TclExecuteByteCode): fixed missing comma
- in debug macro.
+ * generic/tclExecute.c (TclExecuteByteCode): fixed missing comma in
+ debug macro.
2001-09-03 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * doc/ExprLongObj.3: Fixed error in documentation of argument type
- to Tcl_ExprObj [Bug: 457435]
+ * doc/ExprLongObj.3: Fixed error in documentation of argument type to
+ Tcl_ExprObj [Bug 457435]
2001-09-02 David Gravereaux <davygrvy@pobox.com>
* win/tclWinThrd.c: Portability fix for Cygwin who's c-runtime,
not surprisingly, doesn't have the MSVCRT specific _beginthreadex /
- _endthreadex pair. This might have to be revisited for proper
- Borland, lcc32, Watcom and other support as well.
- [Patch: 444255]
+ _endthreadex pair. This might have to be revisited for proper Borland,
+ lcc32, Watcom and other support as well. [Patch 444255]
* win/tclWinThrd.c: Moved FinalizeConditionEvent() proto to within
the main #ifdef TCL_THREADS block to avoid mingw warning about it
being there but unused.
- * win/makefile.vc: Added -Zl (zee el) to tclStubLib.c compile line
- to make sure the tclstub84.lib static library is built without
- requiring a specific C-runtime library at link-time for the end-use
- developer. It has been noted on c.l.t that this trips many first
- time users trying to make extensions.
- [Patch: 403533]
+ * win/makefile.vc: Added -Zl (zee el) to tclStubLib.c compile line to
+ make sure the tclstub84.lib static library is built without requiring
+ a specific C-runtime library at link-time for the end-use developer.
+ It has been noted on c.l.t that this trips many first time users
+ trying to make extensions. [Patch 403533]
2001-08-31 Jeff Hobbs <jeffh@ActiveState.com>
* generic/tclInt.h: added TclCompileListCmd header
* generic/tclBasic.c: added TclCompileListCmd compile proc
- * generic/tclCompCmds.c (TclCompileListCmd): function to compile
- the 'list' command at parse time.
- * generic/tclExecute.c (TclExecuteByteCode): definition of
- INST_LIST bytecode.
+ * generic/tclCompCmds.c (TclCompileListCmd): function to compile the
+ 'list' command at parse time.
+ * generic/tclExecute.c (TclExecuteByteCode): definition of INST_LIST
+ bytecode.
- * doc/StringObj.3: added words of warning to use Tcl_ResetResult
- with the Tcl_Append* functions.
+ * doc/StringObj.3: added words of warning to use Tcl_ResetResult with
+ the Tcl_Append* functions.
* tests/compile.test: added compile-11.* interp result checks
- * generic/tclUtil.c (TclGetIntForIndex): added Tcl_ResetResult
- before Tcl_AppendStringsToObj to prevent shared object crash when
- called from bcc instruction. The Tcl_Append* calls that append to
- the result object that are invoked by bcc insts must remember to
- call Tcl_ResetResult because the bcc doesn't do this for us.
- [Bug #456892]
+ * generic/tclUtil.c (TclGetIntForIndex): added Tcl_ResetResult before
+ Tcl_AppendStringsToObj to prevent shared object crash when called from
+ bcc instruction. The Tcl_Append* calls that append to the result
+ object that are invoked by bcc insts must remember to call
+ Tcl_ResetResult because the bcc doesn't do this for us. [Bug 456892]
2001-08-30 Jeff Hobbs <jeffh@ActiveState.com>
- * generic/tclIndexObj.c: fixed some casting problems that upset
- Crays. [Bug #419528] (andreasen)
+ * generic/tclIndexObj.c: fixed some casting problems that upset Crays.
+ [Bug 419528] (andreasen)
2001-08-30 Don Porter <dgp@users.sourceforge.net>
@@ -2024,120 +1963,116 @@
2001-08-30 Miguel Sofer <msofer@users.sourceforge.net>
- * generic/tclExecute.c: allow cached fully-qualified command names
- to be usable from different namespaces within the same interpreter
- without forcing a new lookup. This speeds up scripts that pass
- command names in variables ("this" in some OO packages).
- [Patch 456668].
+ * generic/tclExecute.c: allow cached fully-qualified command names to
+ be usable from different namespaces within the same interpreter
+ without forcing a new lookup. This speeds up scripts that pass command
+ names in variables ("this" in some OO packages). [Patch 456668]
2001-08-30 Vince Darley <vincentdarley@users.sourceforge.net>
- Further fs updates. After examining the most common Tcl
- extensions (TclX, BLT, Tk, TclPro, Mktclapp), it has been
- determined that only TclpGetCwd and the Access/Stat/Open
- insert/delete hooks of the internal fs functions are ever used.
- The remaining functions from Tcl's internal interfaces have
- therefore been removed, since Tcl now exports a more suitable
- public API (Tcl_FS...)
-
+ Further fs updates. After examining the most common Tcl extensions
+ (TclX, BLT, Tk, TclPro, Mktclapp), it has been determined that only
+ TclpGetCwd and the Access/Stat/Open insert/delete hooks of the
+ internal fs functions are ever used. The remaining functions from
+ Tcl's internal interfaces have therefore been removed, since Tcl now
+ exports a more suitable public API (Tcl_FS...)
+
* generic/tclInt.stubs:
- * generic/tclInt.h: updated for removed internal functions.
- Some new internal functions have been put in tclInt.h (and
- not exported in the stub table because good public equivalents
- exist).
- * generic/tclTest.c: some test functions used the internal private
- APIs. These tests have been retained, but modified to use
- public APIs. Also objectified the internal filesystem tests.
- * win/tclWinFile.c: removed TclpStat, TclpAccess and refactored
- code to use NativeAccess, NativeStat. This should speed up
- stat, access and glob commands.
- * win/tclWinFCmd.c: removed all TclpCopy/Rename/Delete
- File/Directory string-based procedures which aren't used any more.
- Improved efficiency of some other procedures. Ensure that filename
- conversions with a NULL interp do not crash Tcl.
+ * generic/tclInt.h: updated for removed internal functions. Some new
+ internal functions have been put in tclInt.h (and not exported in the
+ stub table because good public equivalents exist).
+ * generic/tclTest.c: some test functions used the internal private
+ APIs. These tests have been retained, but modified to use public APIs.
+ Also objectified the internal filesystem tests.
+ * win/tclWinFile.c: removed TclpStat, TclpAccess and refactored code
+ to use NativeAccess, NativeStat. This should speed up stat, access and
+ glob commands.
+ * win/tclWinFCmd.c: removed all TclpCopy/Rename/Delete File/Directory
+ string-based procedures which aren't used any more. Improved
+ efficiency of some other procedures. Ensure that filename conversions
+ with a NULL interp do not crash Tcl.
* mac/tclMacFCmd.c: wrapped long lines and cleaned up
- TclpObjNormalizePath, removed all TclpCopy/Rename/Delete
+ TclpObjNormalizePath, removed all TclpCopy/Rename/Delete
File/Directory string-based procedures which aren't used any more.
* mac/tclMacFile.c: removed obsolete TclpStat, TclpAccess, TclpChdir,
etc.
* unix/tclUnixFCmd.c: removed use of TclpAccess, removed all
TclpCopy/Rename/Delete File/Directory string-based procedures which
aren't used any more.
- * unix/tclUnixFile.c: removed obsolete TclpStat, TclpAccess, TclpChdir,
- etc.
+ * unix/tclUnixFile.c: removed obsolete TclpStat, TclpAccess,
+ TclpChdir, etc.
* tcl(Unix|Mac|Win)Chan.c: objectified TclpOpenFileChannel.
* various 'load' implementations all objectified.
* generic/tclFileName.c: removed redundant code.
* generic/tclIOUtil.c: removed TclStat, TclAccess, TclpListVolumes.
- Fix to MatchInDirectory at the root of a volume. Also improved
- some documentation, and improved default path joining behaviour
- for virtual filesystems, especially regarding '~'.
+ Fix to MatchInDirectory at the root of a volume. Also improved some
+ documentation, and improved default path joining behaviour for virtual
+ filesystems, especially regarding '~'.
* tests/fileName.test: added tests to check for bugs fixed above.
* doc/FileName.3: improved documentation
-
+
2001-08-30 David Gravereaux <davygrvy@pobox.com>
* generic/tclAsync.c:
* generic/tclEvent.c:
* generic/tclInt.h: Improper cleanup of asyncMutex in tclAsync.c
- repaired. TclFinalizeSynchronization() was trying to remove a
- registered mutex that was dumped earlier when the TSD it was stored
- in was cleared. This was only surfacing on *nix. Windows was being
- masked by mutexes not actually being returned to the system! That
- was repaired in a previous patch. Needed to add a private
+ repaired. TclFinalizeSynchronization() was trying to remove a
+ registered mutex that was dumped earlier when the TSD it was stored in
+ was cleared. This was only surfacing on *nix. Windows was being masked
+ by mutexes not actually being returned to the system! That was
+ repaired in a previous patch. Needed to add a private
TclFinalizeAsync() to tclAsync.c and called from Tcl_FinalizeThread().
- Pheww.. Is this done yet?
- [Bug: 414419] requested by Rob Ratcliff <rrr6399@futuretek.com>
+ Pheww.. Is this done yet? [Bug 414419] requested by Rob Ratcliff
+ <rrr6399@futuretek.com>
2001-08-28 Jeff Hobbs <jeffh@ActiveState.com>
* generic/tclCompCmds.c (TclPushVarName): noted 'static' defn.
- [Bug #453872]
+ [Bug 453872]
2001-08-26 Don Porter <dgp@users.sourceforge.net>
* library/auto.tcl (tcl_findLibrary):
* tests/unixInit.test (unixInit-2.{1,9}):
* unix/tclUnixInit.c (TclpInitLibraryPath):
- * win/tclWinInit.c (TclpInitLibraryPath): Corrected
- inconsistency between the search path for script libraries and
- the directory name $DISTNAME into which distributions built
- by 'make test' unpack. [Bug 455642]
+ * win/tclWinInit.c (TclpInitLibraryPath): Corrected inconsistency
+ between the search path for script libraries and the directory name
+ $DISTNAME into which distributions built by 'make test' unpack. [Bug
+ 455642]
2001-08-24 Jeff Hobbs <jeffh@ActiveState.com>
* tests/stringComp.test: added string-1.3
* generic/tclCompCmds.c (TclCompileStringCmd): changed to return
TCL_OUT_LINE_COMPILE instead of TCL_ERROR when compiling and an
- unknown string method is called. This is necessary as the string
+ unknown string method is called. This is necessary as the string
command may be never called, or not until 'string' is redefined.
2001-08-24 Vince Darley <vincentdarley@users.sourceforge.net>
* doc/glob.n: documented windows-style path issue with glob.
- [Bug: 219392]
+ [Bug 219392]
* doc/filename.n: documented windows path/file length limitation.
- [Bug: 454597]
+ [Bug 454597]
2001-08-24 Don Porter <dgp@users.sourceforge.net>
- * tests/unixInit.test (unixInit-2.9): Corrected expected result
- to match Tcl's quirky construction of its init library path.
+ * tests/unixInit.test (unixInit-2.9): Corrected expected result to
+ match Tcl's quirky construction of its init library path.
2001-08-23 Andreas Kupries <andreas_kupries@users.sourceforge.net>
- * win/tclWinPipe.c (BuildCommandLine): Fixed tcl Bug
- [432499]. Part of the code used the non-absolute path to the
- executable to determine quoting. This failed if the absolute
- path contained spaces, but the application name itself not. This
- bug caused no trouble on Win NT 5, but does for other variants
- in the Win* family. Report and fix due to Ken Poole
- <kenpoole@users.sourceforge.net>.
+ * win/tclWinPipe.c (BuildCommandLine): Fixed [Bug 432499]. Part of the
+ code used the non-absolute path to the executable to determine
+ quoting. This failed if the absolute path contained spaces, but the
+ application name itself not. This bug caused no trouble on Win NT 5,
+ but does for other variants in the Win* family. Report and fix due to
+ Ken Poole <kenpoole@users.sourceforge.net>.
2001-08-23 Jeff Hobbs <jeffh@ActiveState.com>
* unix/configure:
- * unix/tcl.m4: added QNX-6 build support. [Bug #219410] (loverso)
+ * unix/tcl.m4: added QNX-6 build support. [Bug 219410] (loverso)
* unix/tclUnixFCmd.c:
* generic/tclIOUtil.c:
@@ -2145,97 +2080,93 @@
2001-08-23 Vince Darley <vincentdarley@users.sourceforge.net>
- Variety of small filesystem and vfs issues fixed or improved.
- The new fs code allows many new opportunities for efficiency
- improvements through the objectified API. The main changes
- integrated here are such efficiency improvements. Some
- limitations of the original implementation have also now been
- lifted. Meanwhile a variety of fs bugs (some old, some new)
- have also been fixed.
-
- * generic/tclFileName.c: Made Tcl_FSSplitPath more efficient,
- and removed some static string-based procedures which are no
- longer used. Much more objectification. Tcl_FSJoinPath
- is now very efficient and more aware of virtual filesystems.
- Clarified where the Mac-specific code attempts to interpret
- Unix-style paths. Modified TclDoGlob to use lstat not
- access to fix [Bug: 434876, L. Virden]
+ Variety of small filesystem and vfs issues fixed or improved. The new
+ fs code allows many new opportunities for efficiency improvements
+ through the objectified API. The main changes integrated here are such
+ efficiency improvements. Some limitations of the original
+ implementation have also now been lifted. Meanwhile a variety of fs
+ bugs (some old, some new) have also been fixed.
+
+ * generic/tclFileName.c: Made Tcl_FSSplitPath more efficient, and
+ removed some static string-based procedures which are no longer used.
+ Much more objectification. Tcl_FSJoinPath is now very efficient and
+ more aware of virtual filesystems. Clarified where the Mac-specific
+ code attempts to interpret Unix-style paths. Modified TclDoGlob to use
+ lstat not access to fix [Bug 434876] (L. Virden)
+
* tcl(Win|Unix|Mac)FCmd.c:
* tcl(Win|Unix|Mac)File.c: replaced TclpListVolumes with
- TclpObjListVolumes with different signature, updated code due
- to more efficient signature of Tcl_FSGetTranslatedPath. Used
- cached native paths where possible to improve efficiency --
- this was completed on MacOS, but on Unix and Win the traversal
- functions make the task much more complex, so there are still
- some improvements possible there. Removed unused
- TclpNormalizePath which had been left in tclWinFCmd.c.
- Objectified all 'file attributes' functions. Fixed the new
- [Bug:451571, Bruce Stephens] which is most obvious on Unix,
- but could occur on MacOS or Windows. This bug actually existed
- in Tcl 8.3.x but was only made obvious by the recent filesystem
- overhaul when the code was exercised more heavily.
- * tests/fileName.test: Three new tests to exercise the above bug,
- and make sure it is fixed correctly.
- * unix/tclUnixFile.c: avoid panic in glob when a link
- doesn't point anywhere. It would probably be good to define
- exactly what Tcl should do in circumstances like these, and
- make sure mac/win/unix all behave accordingly. [Bug: 417111,
- Hemang Lavana]. Also fixed misleading/obsolete comment in the code.
- * generic/tcl.stubs: changed signature of Tcl_FSGetTranslatedPath
- and added Tcl_FSGetTranslatedStringPath.
+ TclpObjListVolumes with different signature, updated code due to more
+ efficient signature of Tcl_FSGetTranslatedPath. Used cached native
+ paths where possible to improve efficiency -- this was completed on
+ MacOS, but on Unix and Win the traversal functions make the task much
+ more complex, so there are still some improvements possible there.
+ Removed unused TclpNormalizePath which had been left in tclWinFCmd.c.
+ Objectified all 'file attributes' functions. Fixed the new [Bug
+ 451571, Bruce Stephens] which is most obvious on Unix, but could occur
+ on MacOS or Windows. This bug actually existed in Tcl 8.3.x but was
+ only made obvious by the recent filesystem overhaul when the code was
+ exercised more heavily.
+ * tests/fileName.test: Three new tests to exercise the above bug, and
+ make sure it is fixed correctly.
+ * unix/tclUnixFile.c: avoid panic in glob when a link doesn't point
+ anywhere. It would probably be good to define exactly what Tcl should
+ do in circumstances like these, and make sure mac/win/unix all behave
+ accordingly. [Bug 417111] (Hemang Lavana). Also fixed
+ misleading/obsolete comment in the code.
+ * generic/tcl.stubs: changed signature of Tcl_FSGetTranslatedPath and
+ added Tcl_FSGetTranslatedStringPath.
These changes allow further optimisations in the FS code.
- * generic/tcl.h: changed signature of Tcl_FSListVolumes so that
- it doesn't require a Tcl interpreter plus result. Renamed
- Tcl_FSReadLink to Tcl_FSLink with additional argument so
- we can support making links in the future. [Patch: 450340]
- * generic/tclInt.h:
- added declaration for TclpObjListVolumes. Objectified
- internal call signatures for 'file attributes' functions, and
- added an internal objectified get path type function.
- * generic/tclIOUtil.c: added the moved function TclpListVolumes
- which calls platform specific code (needed for backwards
- compatibility), and improved efficiency of parts of the FS
- (particularly file normalization). Much less copying and
- memory allocation is required now. added new GetPathType
- so that changes in 'file volumes' can actually affect files'
- types, and objectified more code. Made current code work
- with test suite artificially changing current platform.
+ * generic/tcl.h: changed signature of Tcl_FSListVolumes so that it
+ doesn't require a Tcl interpreter plus result. Renamed Tcl_FSReadLink
+ to Tcl_FSLink with additional argument so we can support making links
+ in the future. [Patch: 450340]
+ * generic/tclInt.h: added declaration for TclpObjListVolumes.
+ Objectified internal call signatures for 'file attributes' functions,
+ and added an internal objectified get path type function.
+ * generic/tclIOUtil.c: added the moved function TclpListVolumes which
+ calls platform specific code (needed for backwards compatibility), and
+ improved efficiency of parts of the FS (particularly file
+ normalization). Much less copying and memory allocation is required
+ now. added new GetPathType so that changes in 'file volumes' can
+ actually affect files' types, and objectified more code. Made current
+ code work with test suite artificially changing current platform.
Added 'static' keywords where required.
* generic/tclIO.c:
- * generic/tclTest.c: Added 'static' keywords, fixing
- [Bug: 453872, Bob Techentin]
- * generic/tclCmdAH.c: file command implementation updated for
- API changes, removed unnecessary special-case SplitPath static
- function, since it no longer helps prevent code duplication.
- Moved setting of interpreter result to each individual location
- that actually required it, to avoid very large code separation
- between reading and setting the result.
- * doc/FileSystem.3: updated documentation for the new or
- changed APIs, and clarified some issues.
+ * generic/tclTest.c: Added 'static' keywords, fixing [Bug 453872] (Bob
+ Techentin)
+ * generic/tclCmdAH.c: file command implementation updated for API
+ changes, removed unnecessary special-case SplitPath static function,
+ since it no longer helps prevent code duplication. Moved setting of
+ interpreter result to each individual location that actually required
+ it, to avoid very large code separation between reading and setting
+ the result.
+ * doc/FileSystem.3: updated documentation for the new or changed APIs,
+ and clarified some issues.
* doc/SplitPath.3: added pointer to newer APIs in FileSystem.3
- * doc/filename.n: clarified current implementation of tilde
- support on Mac/Win. [Bug:453514, Sergey Kuzmin]
- * doc/glob.n: improved documentation for '-directory' and '-path'
+ * doc/filename.n: clarified current implementation of tilde support on
+ Mac/Win. [Bug 453514] (Sergey Kuzmin)
+ * doc/glob.n: improved documentation for '-directory' and '-path'
options.
-
- There are now many private, obsolete, platform-specific 'Tclp'
- string-based filesystem APIs which could be removed. We should
- check whether any of these are used by extensions and, at least
- in Tcl 9, remove them.
-
- The above changes signify a ***POTENTIAL INCOMPATIBILITY***
- with 8.4a3, since signatures of two functions in the new API
- have changed, but not with older versions of Tcl.
+
+ There are now many private, obsolete, platform-specific 'Tclp'
+ string-based filesystem APIs which could be removed. We should check
+ whether any of these are used by extensions and, at least in Tcl 9,
+ remove them.
+
+ The above changes signify a ***POTENTIAL INCOMPATIBILITY*** with
+ 8.4a3, since signatures of two functions in the new API have changed,
+ but not with older versions of Tcl.
2001-08-23 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * generic/tclBinary.c (FormatNumber): Extract a long from the
- object and not an int, to stop [binary format] from being unable
- to format some input numbers on architectures where sizeof(int) is
- less than sizeof(long) (particularly Alpha.) [tiprender Bug #441861]
+ * generic/tclBinary.c (FormatNumber): Extract a long from the object
+ and not an int, to stop [binary format] from being unable to format
+ some input numbers on architectures where sizeof(int) is less than
+ sizeof(long) (particularly Alpha). [tiprender Bug 441861]
- * tests/format.test: Converted conditional execution of tests into
- a test constraint.
+ * tests/format.test: Converted conditional execution of tests into a
+ test constraint.
2001-08-22 Jeff Hobbs <jeffh@ActiveState.com>
@@ -2243,90 +2174,88 @@
* win/makefile.vc: updated install target for dde1.2
* doc/dde.n: fixed dde man page (which was totally incorrect).
* tests/winDde.test:
- * win/tclWinDde.c (Tcl_DdeObjCmd): added -binary option to dde
- request command to allow for returning binary data. [Bug #227482]
+ * win/tclWinDde.c (Tcl_DdeObjCmd): added -binary option to dde request
+ command to allow for returning binary data. [Bug 227482]
Updated dde to 1.2
- * tests/tcltest.test: added unixExecs constraint to files that
- used 'grep' in the test. [Bug #453143]
+ * tests/tcltest.test: added unixExecs constraint to files that used
+ 'grep' in the test. [Bug 453143]
+
+ * library/tcltest/tcltest.tcl: fixed stdio constraint test. [Patch
+ 454050] (stanton)
+ Simplified unixExecs constraint test.
- * library/tcltest/tcltest.tcl: fixed stdio constraint test.
- [Patch #454050] (stanton)
- Simplified unixExecs constraint test.
-
2001-08-22 Don Porter <dgp@users.sourceforge.net>
- * tests/ioUtil.test (ioUtil-3.*): Corrected errors in tests
- revealed by fix of overagressive compiler. [Bug 451200]
+ * tests/ioUtil.test (ioUtil-3.*): Corrected errors in tests revealed
+ by fix of overagressive compiler. [Bug 451200]
2001-08-21 Miguel Sofer <msofer@users.sourceforge.net>
* generic/tclCompCmds.c:
- * tests/compile.test: Fixed overagressive compilation of [catch]:
- it was catching errors at substitution time. [Bug #219184]
-
+ * tests/compile.test: Fixed overagressive compilation of [catch]: it
+ was catching errors at substitution time. [Bug 219184]
+
2001-08-21 Jeff Hobbs <jeffh@ActiveState.com>
- * tests/tcltest.test (tcltest-12.2): fixed test that would break
- when env vars weren't Tcl list friendly [Patch #454046] (stanton)
+ * tests/tcltest.test (tcltest-12.2): fixed test that would break when
+ env vars weren't Tcl list friendly [Patch 454046] (stanton)
2001-08-20 Jeff Hobbs <jeffh@ActiveState.com>
- * library/http/http.tcl (geturl): added port number to Host:
- header to comply with HTTP/1.1 spec (RFC 2068). [Bug #452217]
+ * library/http/http.tcl (geturl): added port number to Host: header to
+ comply with HTTP/1.1 spec (RFC 2068). [Bug 452217]
2001-08-16 David Gravereaux <davygrvy@pobox.com>
* tools/tcl.wse.in:
* tools/tcl.hpj.in:
* win/tcl.hpj.in: Removed -kb storage in CVS to ensure these text
- files are checked-out in the translation mode CVS is in. Setting
- these as binary as part of an effort to make sure they are always
- in CRLF, no matter what the CVS translation, is bypassing how CVS
- works and is confusing.
+ files are checked-out in the translation mode CVS is in. Setting these
+ as binary as part of an effort to make sure they are always in CRLF,
+ no matter what the CVS translation, is bypassing how CVS works and is
+ confusing.
- * tools/genStubs.tcl: Removed LF-only output. Having to reconvert
- back to CRLF before committing to CVS was giving me a headache.
- [Bug: 451333]
+ * tools/genStubs.tcl: Removed LF-only output. Having to reconvert
+ back to CRLF before committing to CVS was giving me a headache. [Bug
+ 451333]
* win/makefile.vc: replaced $(WINDIR) with $(include32) for the
- .rc.res inference rule. winver.h wasn't getting included.
- [Bug: 445630]
+ .rc.res inference rule. winver.h wasn't getting included. [Bug 445630]
2001-08-14 Miguel Sofer <msofer@users.sourceforge.net>
* generic/tclBasic.c: make the intial maxNestingDepth of an
- interpreter be MAX_NESTING_DEPTH instead of a hardwired value
- [Bug: 232564]
+ interpreter be MAX_NESTING_DEPTH instead of a hardwired value. [Bug
+ 232564]
2001-08-13 Miguel Sofer <msofer@users.sourceforge.net>
- * tests/trace.test: Corrected test numbers [Bug: 449794]
+ * tests/trace.test: Corrected test numbers. [Bug 449794]
2001-08-12 Mo DeJong <mdejong@redhat.com>
* unix/configure: Regen.
* unix/configure.in:
- * unix/tcl.m4: Use GCC variable set by AC_PROG_CC instead
- of defining our own using_gcc variable.
+ * unix/tcl.m4: Use GCC variable set by AC_PROG_CC instead of defining
+ our own using_gcc variable.
2001-08-11 Vince Darley <vincentdarley@users.sourceforge.net>
Variety of small issues introduced by the vfs code fixed:
* generic/tclIOUtil.c: uninitialised read.
- * generic/tclFCmd.c: possible memory leak in file delete
- with error condition.
+ * generic/tclFCmd.c: possible memory leak in file delete with error
+ condition.
2001-08-10 Miguel Sofer <msofer@users.sourceforge.net>
- * generic/tclVar.c:
+ * generic/tclVar.c:
* tests/trace.test: Insure that [array] traces work correctly for
- undefined variables [Bug: 449094]
+ undefined variables. [Bug 449094]
2001-08-09 Mo DeJong <mdejong@redhat.com>
- * unix/Makefile.in: Delete the unused getcwd.o
- target. This fixes bug #440942.
+ * unix/Makefile.in: Delete the unused getcwd.o target. [Bug 440942]
2001-08-08 Don Porter <dgp@users.sourceforge.net>
@@ -2340,8 +2269,8 @@
* library/reg/pkgIndex.tcl:
* library/tcltest/tcltest.tcl:
* library/tcltest/pkgIndex.tcl: Added checks for package dependencies.
- Bumped patchlevels of changed packages: http 2.3.2, msgcat 1.2.2,
- opt 0.4.3, tcltest 2.0.1. [Patch 448931]
+ Bumped patchlevels of changed packages: http 2.3.2, msgcat 1.2.2,
+ opt 0.4.3, tcltest 2.0.1. [Patch 448931]
* README:
* generic/tcl.h:
@@ -2351,9 +2280,9 @@
* unix/tcl.spec:
* win/README.binary:
* win/configure:
- * win/configure.in: Bumped up patchlevel to 8.4a4 to distinguish
- CVS snapshots from the 8.4a3 release. This does not necessarily
- mean there will be an 8.4a4 release. [Bug 448938].
+ * win/configure.in: Bumped up patchlevel to 8.4a4 to distinguish CVS
+ snapshots from the 8.4a3 release. This does not necessarily mean there
+ will be an 8.4a4 release. [Bug 448938]
2001-08-06 Jeff Hobbs <jeffh@ActiveState.com>
@@ -2361,64 +2290,63 @@
* changes:
* README:
- * mac/README:
+ * mac/README:
* unix/README:
* win/README.binary: updated for 8.4a3 release
- * generic/tclFileName.c (Tcl_FSSplitPath): update to Tcl style
- guide.
+ * generic/tclFileName.c (Tcl_FSSplitPath): update to Tcl style guide.
- * generic/tclFCmd.c (FileCopyRename): fixed mem leak in
- introduction of vfs code where a new Tcl_Obj wasn't freed.
+ * generic/tclFCmd.c (FileCopyRename): fixed mem leak in introduction
+ of vfs code where a new Tcl_Obj wasn't freed.
- * generic/tclCmdMZ.c (Tcl_RegexpObjCmd, Tcl_RegsubObjCmd):
- reordered the retrieval of arguments to avoid shimmering bug when
- the pattern and string referenced the same object.
+ * generic/tclCmdMZ.c (Tcl_RegexpObjCmd, Tcl_RegsubObjCmd): reordered
+ the retrieval of arguments to avoid shimmering bug when the pattern
+ and string referenced the same object.
* unix/configure: regenerated
- * unix/tcl.m4: added GNU (HURD) configuration target. (brinkmann)
- [Patch: #442974]
+ * unixE/tcl.m4: added GNU (HURD) configuration target.
+ [Patch 442974] (brinkmann)
* win/README: made note of URL for Windows compilation notes
- * win/tclWinThrd.c (TclpFinalizeMutex, TclpFinalizeCondition):
- added DeleteCriticalSection calls for cleanup [Patch: #419683]
+ * win/tclWinThrd.c (TclpFinalizeMutex, TclpFinalizeCondition): added
+ DeleteCriticalSection calls for cleanup [Patch 419683]
* unix/tclUnixPipe.c (TclpCreateTempFile): fixed use of tmpnam,
- which is dangerous. [Patch: #442636] (lim)
+ which is dangerous. [Patch 442636] (lim)
The use of tmpnam in TclpTempFileName must still be changed.
* tests/http.test (http-4.14): fixed variable error return.
- [Bug: 424252]
+ [Bug 424252]
2001-08-03 Jeff Hobbs <jeffh@ActiveState.com>
* win/configure: regenerated
* win/tcl.m4: fixed DLLSUFFIX definition to always be ${DBGX}.dll.
- This is necessary for TEA compliant builds that build shared
- against a static-built Tcl.
+ This is necessary for TEA compliant builds that build shared against a
+ static-built Tcl.
* win/Makefile.in ($(TCLSH)): added $(TCL_STUB_LIB_FILE) to build
target, otherwise it wouldn't get generated in a static build.
2001-08-06 Andreas Kupries <andreas_kupries@users.sourceforge.net>
- * generic/tclIOCmd.c (Tcl_GetsObjCmd): Applied patch from SF item
- [442665] to fix the bug reported by it. The function can corrupt
- a freed object if it is called with objc == 3. This is because
- it retrieves resultPtr and does not increment its reference
- count, but then calls Tcl_ObjSetVar2, which causes the retrieved
- resultPtr object to be released.
-
+ * generic/tclIOCmd.c (Tcl_GetsObjCmd): Applied patch from [Bug 442665]
+ to fix the bug reported by it. The function can corrupt a freed object
+ if it is called with objc == 3. This is because it retrieves resultPtr
+ and does not increment its reference count, but then calls
+ Tcl_ObjSetVar2, which causes the retrieved resultPtr object to be
+ released.
+
2001-08-06 Don Porter <dgp@users.sourceforge.net>
- * doc/tclsh.1: Added note that the tclsh program is frequently
- installed with the Tcl version numer as part of the name.
- [Patch 402725]
+ * doc/tclsh.1: Added note that the tclsh program is frequently
+ installed with the Tcl version numer as part of the name. [Patch
+ 402725]
* generic/tclPkg.c:
- * tests/pkg.test: [package forget] now forgets all of the
- package arguments it receives, not stopping when a package is
- not found. [Bug 415273]
+ * tests/pkg.test: [package forget] now forgets all of the package
+ arguments it receives, not stopping when a package is not found. [Bug
+ 415273]
2001-08-02 Jeff Hobbs <jeffh@ActiveState.com>
@@ -2428,141 +2356,133 @@
2001-08-02 Mo DeJong <mdejong@redhat.com>
* generic/tclPlatDecls.h:
- * win/tclWinPort.h:
- Revert <tchar.h> related changes made to improve
- Cygwin support on 2001-07-18. This change ended
- up breaking the VC++ build because of conflicts
- between Windows APIs and internal Tk APIs.
+ * win/tclWinPort.h: Revert <tchar.h> related changes made to improve
+ Cygwin support on 2001-07-18. This change ended up breaking the VC++
+ build because of conflicts between Windows APIs and internal Tk APIs.
2001-08-01 Jeff Hobbs <jeffh@ActiveState.com>
* unix/tclUnixFCmd.c: minor casts to eliminate warnings. (lim)
- [Patch: #440218]
+ [Patch 440218]
- * tests/parseOld.test: changed some tests that required
- testwordend to exist to skip in a proper tcltest manner.
- [Bug: #442663]
+ * tests/parseOld.test: changed some tests that required testwordend to
+ exist to skip in a proper tcltest manner. [Bug 442663]
- * library/http/http.tcl (http::mapReply): the regsub'ing of \n and
- \t to escape them was unnecessary.
+ * library/http/http.tcl (http::mapReply): the regsub'ing of \n and \t
+ to escape them was unnecessary.
2001-07-31 Vince Darley <vincentdarley@users.sourceforge.net>
Changes from TIP#17 "Redo Tcl's filesystem"
The following files were impacted:
- * doc/Access.3:
- * doc/FileSystem.3:
- * doc/OpenFileChnl.3:
- * doc/file.n:
- * doc/glob.n:
- * generic/tcl.decls:
- * generic/tcl.h:
- * generic/tclCmdAH.c:
- * generic/tclCmdIL.c:
- * generic/tclCmdMZ.c:
- * generic/tclDate.c:
- * generic/tclDecls.h:
- * generic/tclEncoding.c:
- * generic/tclFCmd.c:
- * generic/tclFileName.c:
- * generic/tclGetDate.y:
- * generic/tclIO.c:
- * generic/tclIOCmd.c:
- * generic/tclIOUtil.c:
- * generic/tclInt.decls:
- * generic/tclInt.h:
- * generic/tclIntDecls.h:
- * generic/tclLoad.c:
- * generic/tclStubInit.c:
- * generic/tclTest.c:
- * generic/tclUtil.c:
- * library/init.tcl:
- * mac/tclMacFCmd.c:
- * mac/tclMacFile.c:
- * mac/tclMacInit.c:
- * mac/tclMacPort.h:
- * mac/tclMacResource.c:
- * mac/tclMacTime.c:
- * tests/cmdAH.test:
- * tests/event.test:
- * tests/fCmd.test:
- * tests/fileName.test:
- * tests/io.test:
- * tests/ioCmd.test:
- * tests/proc-old.test:
- * tests/registry.test:
- * tests/unixFCmd.test:
- * tests/winDde.test:
- * tests/winFCmd.test:
- * unix/mkLinks:
- * unix/tclUnixFCmd.c:
- * unix/tclUnixFile.c:
- * unix/tclUnixInit.c:
- * unix/tclUnixPipe.c:
- * win/tclWinFCmd.c:
- * win/tclWinFile.c:
- * win/tclWinInit.c:
- * win/tclWinPipe.c
+ * doc/Access.3:
+ * doc/FileSystem.3:
+ * doc/OpenFileChnl.3:
+ * doc/file.n:
+ * doc/glob.n:
+ * generic/tcl.decls:
+ * generic/tcl.h:
+ * generic/tclCmdAH.c:
+ * generic/tclCmdIL.c:
+ * generic/tclCmdMZ.c:
+ * generic/tclDate.c:
+ * generic/tclDecls.h:
+ * generic/tclEncoding.c:
+ * generic/tclFCmd.c:
+ * generic/tclFileName.c:
+ * generic/tclGetDate.y:
+ * generic/tclIO.c:
+ * generic/tclIOCmd.c:
+ * generic/tclIOUtil.c:
+ * generic/tclInt.decls:
+ * generic/tclInt.h:
+ * generic/tclIntDecls.h:
+ * generic/tclLoad.c:
+ * generic/tclStubInit.c:
+ * generic/tclTest.c:
+ * generic/tclUtil.c:
+ * library/init.tcl:
+ * mac/tclMacFCmd.c:
+ * mac/tclMacFile.c:
+ * mac/tclMacInit.c:
+ * mac/tclMacPort.h:
+ * mac/tclMacResource.c:
+ * mac/tclMacTime.c:
+ * tests/cmdAH.test:
+ * tests/event.test:
+ * tests/fCmd.test:
+ * tests/fileName.test:
+ * tests/io.test:
+ * tests/ioCmd.test:
+ * tests/proc-old.test:
+ * tests/registry.test:
+ * tests/unixFCmd.test:
+ * tests/winDde.test:
+ * tests/winFCmd.test:
+ * unix/mkLinks:
+ * unix/tclUnixFCmd.c:
+ * unix/tclUnixFile.c:
+ * unix/tclUnixInit.c:
+ * unix/tclUnixPipe.c:
+ * win/tclWinFCmd.c:
+ * win/tclWinFile.c:
+ * win/tclWinInit.c:
+ * win/tclWinPipe.c:
2001-07-24 Mo DeJong <mdejong@redhat.com>
- * win/tclWinThrd.c (Tcl_CreateThread): Close Windows
- HANDLE returned by _beginthreadex. The MS documentation
- states that this handle is not closed by a later call to
- _endthreadex.
+ * win/tclWinThrd.c (Tcl_CreateThread): Close Windows HANDLE returned
+ by _beginthreadex. The MS documentation states that this handle is not
+ closed by a later call to _endthreadex.
2001-07-21 Don Porter <dgp@users.sourceforge.net>
* doc/pkgMkindex.n:
- * library/package.tcl: Corrected documentation and usage
- message of [pkg_mkIndex].
+ * library/package.tcl: Corrected documentation and usage message of
+ [pkg_mkIndex].
2001-07-18 Mo DeJong <mdejong@redhat.com>
- * generic/tclPlatDecls.h: Define TCHAR by including
- windows.h instead of tchar.h since Cygwin does not
- support the tchar.h header. Include CHECK_UNICODE_CALLS
- logic from tclWinPort.h.
- * win/tclWinPort.h: Remove CHECK_UNICODE_CALLS logic.
- Remove include of windows.h since this now done it
- tclPlatDecls.h.
+ * generic/tclPlatDecls.h: Define TCHAR by including windows.h instead
+ of tchar.h since Cygwin does not support the tchar.h header. Include
+ CHECK_UNICODE_CALLS logic from tclWinPort.h.
+ * win/tclWinPort.h: Remove CHECK_UNICODE_CALLS logic. Remove include
+ of windows.h since this now done it tclPlatDecls.h.
* win/tclWinReg.c: Remove duplicate include of windows.h.
2001-07-18 Andreas Kupries <andreas_kupries@users.sourceforge.net>
- * generic/tclIO.c: Aftermath to [SF #427196]. Squash empty buffers
- if they are smaller than the requested buffersize, to prevent
- reusage of old buffers and to honor changes in the requested
- buffersize made by the user.
+ * generic/tclIO.c: Aftermath to [Bug 427196]. Squash empty buffers if
+ they are smaller than the requested buffersize, to prevent reusage of
+ old buffers and to honor changes in the requested buffersize made by
+ the user.
2001-07-17 Mo DeJong <mdejong@redhat.com>
- * win/tclWinFile.c (TclpReadlink): Add Cygwin specific definition
- for the TclpReadlink function. This method implements reading of
- symbolic links when build with Cygwin.
+ * win/tclWinFile.c (TclpReadlink): Add Cygwin specific definition for
+ the TclpReadlink function. This method implements reading of symbolic
+ links when build with Cygwin.
2001-07-17 Mo DeJong <mdejong@redhat.com>
- * win/tclWinPort.h: Add Cygwin specific defines for environ
- and timezone variables.
+ * win/tclWinPort.h: Add Cygwin specific defines for environ and
+ timezone variables.
2001-07-17 Andreas Kupries <andreas_kupries@users.sourceforge.net>
- * generic/tclIO.c (GetInput): Fixed [SF #427196]. Memory was
- overwritten because a buffer was used after a change of the
- requested buffersize together with that requested buffersize and
- not its actual size, which was smaller. Note that the continous
- reuse of the smaller buffer negatively impacts performance. The
- system never allocates a buffer with the newly requested bigger
- buffersize.
+ * generic/tclIO.c (GetInput): Fixed [Bug 427196]. Memory was
+ overwritten because a buffer was used after a change of the requested
+ buffersize together with that requested buffersize and not its actual
+ size, which was smaller. Note that the continous reuse of the smaller
+ buffer negatively impacts performance. The system never allocates a
+ buffer with the newly requested bigger buffersize.
2001-07-16 Mo DeJong <mdejong@redhat.com>
- * generic/tcl.h: Define __WIN32__ when
- __CYGWIN__ or __MINGW32__ is defined.
- * generic/tclAlloc.c: Define caddr_t when
- compiling with VC++ or mingw. This type is
- already defined when compiling with Cygwin.
+ * generic/tcl.h: Define __WIN32__ when __CYGWIN__ or __MINGW32__ is
+ defined.
+ * generic/tclAlloc.c: Define caddr_t when compiling with VC++ or
+ mingw. This type is already defined when compiling with Cygwin.
2001-07-16 Mo DeJong <mdejong@redhat.com>
@@ -2571,9 +2491,9 @@
* win/tclWinPort.h:
* win/tclWinSerial.c:
* win/tclWinThrd.c:
- Remove unnecessary #includes of dos.h, direct.h,
- and tchar.h. This will help the Cygwin porting
- effort since these headers do not exist under Cygwin.
+ Remove unnecessary #includes of dos.h, direct.h, and tchar.h. This
+ will help the Cygwin porting effort since these headers do not exist
+ under Cygwin.
2001-07-16 Jeff Hobbs <jeffh@ActiveState.com>
@@ -2581,74 +2501,70 @@
just the TerminateThread call and waiting for termination. (jsmith)
* generic/tclCmdMZ.c: Removed extra copy of the SCAN_* macros
- #defined in generic/tclScan.c. (porter) [Bug 441230]
+ #defined in generic/tclScan.c. [Bug 441230] (porter)
2001-07-12 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* tests/unixInit.test (unixInit-2.8): Added extra constraint,
- notInstalledInTmp, to stop this test from damaging installations
- in /tmp; not much fun to have to reinstall the Tcl library every
- time you run the test suite!
+ notInstalledInTmp, to stop this test from damaging installations in
+ /tmp; not much fun to have to reinstall the Tcl library every time you
+ run the test suite!
- * tests/subst.test (subst-10.*): Updated tests to check new
- behaviour for 'break' in command substitutions.
+ * tests/subst.test (subst-10.*): Updated tests to check new behaviour
+ for 'break' in command substitutions.
(subst-1.2,subst-7.1): Error messages changed.
* doc/SubstObj.3: New file, to document Tcl_SubstObj.
- * doc/subst.n: Improved and updated documentation for 'subst' to
- help support the changed behaviour.
+ * doc/subst.n: Improved and updated documentation for 'subst' to help
+ support the changed behaviour.
* generic/tcl.decls (generic-437): Declaration for Tcl_SubstObj
* generic/tcl.h (TCL_SUBST_*): Added flags for Tcl_SubstObj.
- * generic/tclCmdMZ.c (Tcl_SubstObj,Tcl_SubstObjCmd): Divided into
- two parts to allow people to access the innards of 'subst' and
- changed the behaviour when command substitutions do a 'break' to
- be different from 'continue'. Also now works with objects, which
- allows for some nifty optimisations with variable substitutions
- and a slight improvement with command substitutions. [TIP#36]
+ * generic/tclCmdMZ.c (Tcl_SubstObj,Tcl_SubstObjCmd): Divided into two
+ parts to allow people to access the innards of 'subst' and changed the
+ behaviour when command substitutions do a 'break' to be different from
+ 'continue'. Also now works with objects, which allows for some nifty
+ optimisations with variable substitutions and a slight improvement
+ with command substitutions. [TIP#36]
2001-07-10 Mo DeJong <mdejong@redhat.com>
* unix/Makefile.in: Add AR variable for use in STLIB_LD.
* unix/configure: Regen.
- * unix/configure.in: Use STLIB_LD when defining MAKE_LIB
- and MAKE_STUB_LIB. Subst RANLIB and AR.
- * unix/tcl.m4 (SC_CONFIG_CFLAGS): Add doc comment about
- STLIB_LD command. Check ${AR} env var when setting
- STLIB_LD and delay evaluation until make time.
+ * unix/configure.in: Use STLIB_LD when defining MAKE_LIB and
+ MAKE_STUB_LIB. Subst RANLIB and AR.
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): Add doc comment about STLIB_LD
+ command. Check ${AR} env var when setting STLIB_LD and delay
+ evaluation until make time.
* win/configure: Regen.
- * win/tcl.m4 (SC_CONFIG_CFLAGS): Delay evaluation of
- ${AR} in STLIB_LD and add flags to better match the
- Unix implementation. Don't bother defining AR when
- using VC++ since it is not used.
+ * win/tcl.m4 (SC_CONFIG_CFLAGS): Delay evaluation of ${AR} in STLIB_LD
+ and add flags to better match the Unix implementation. Don't bother
+ defining AR when using VC++ since it is not used.
2001-07-06 Mo DeJong <mdejong@redhat.com>
* win/configure: Regen.
- * win/tcl.m4 (SC_CONFIG_CFLAGS): Pass -e _WinMain@16 in
- addition to the -mwindows flag to work around a problem
- with ld when it incorrectly use main() as the executable
- entry point when both WinMain() and main() are available.
+ * win/tcl.m4 (SC_CONFIG_CFLAGS): Pass -e _WinMain@16 in addition to
+ the -mwindows flag to work around a problem with ld when it
+ incorrectly use main() as the executable entry point when both
+ WinMain() and main() are available.
2001-07-06 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * tests/cmdAH.test: Added leading zero to file modes to work
- around fault in HPUX strtol() which ignores the base parameter
- [Bug #438808]
+ * tests/cmdAH.test: Added leading zero to file modes to work around
+ fault in HPUX strtol() which ignores the base parameter. [Bug 438808]
2001-07-05 Mo DeJong <mdejong@redhat.com>
- * win/Makefile.in: Subst DEPARG directly instead
- of relying on a variable. This will make Cygwin
- builds faster since an extra exec will be avoided.
+ * win/Makefile.in: Subst DEPARG directly instead of relying on a
+ variable. This will make Cygwin builds faster since an extra exec will
+ be avoided.
* win/configure: Regen.
* win/configure.in: Subst DEPARG.
- * win/tcl.m4 (SC_CONFIG_CFLAGS): Move AC_MSG_CHECKING
- after the AC_CHECK_PROG so that status messages do
- not get mixed together. Set DEPARG based on the
- results of the cygpath check so that we avoid using
- an extra exec when it is not needed. Use ac_cv_cygwin
- status flag instead of looking at the output of
- gcc -v, which works in the case where -mno-cygwin is
- set in the CFLAGS.
+ * win/tcl.m4 (SC_CONFIG_CFLAGS): Move AC_MSG_CHECKING after the
+ AC_CHECK_PROG so that status messages do not get mixed together. Set
+ DEPARG based on the results of the cygpath check so that we avoid
+ using an extra exec when it is not needed. Use ac_cv_cygwin status
+ flag instead of looking at the output of gcc -v, which works in the
+ case where -mno-cygwin is set in the CFLAGS.
2001-07-04 Jeff Hobbs <jeffh@ActiveState.com>
@@ -2663,32 +2579,30 @@
* win/Makefile.in: Remove PATHTYPE variable.
* win/configure: Regen.
* win/configure.in: Don't subst PATHTYPE.
- * win/tcl.m4 (SC_CONFIG_CFLAGS): Remove PATHTYPE
- variable. Set CYGPATH to "cygpath -w" if the
- cygpath executable is found on the path. This
- approach works for native Cygwin builds and
- cross compiles.
+ * win/tcl.m4 (SC_CONFIG_CFLAGS): Remove PATHTYPE variable. Set CYGPATH
+ to "cygpath -w" if the cygpath executable is found on the path. This
+ approach works for native Cygwin builds and cross compiles.
2001-07-03 Jeff Hobbs <jeffh@ActiveState.com>
* tests/var.test:
* generic/tclVar.c (Tcl_VariableObjCmd): added patch to check for
- number of args. [Patch #426038]
+ number of args. [Patch 426038]
* generic/tclVar.c (Tcl_GetVar2Ex): added ability to recognize
- TCL_TRACE_READS flags to cause creation of part1 in TclLookupVar
- to make sure newly created array will get read traces triggered
- appropriately. This is called by Tcl_ObjGetVar2, Tcl_GetVar, and
+ TCL_TRACE_READS flags to cause creation of part1 in TclLookupVar to
+ make sure newly created array will get read traces triggered
+ appropriately. This is called by Tcl_ObjGetVar2, Tcl_GetVar, and
Tcl_GetVar2.
- (TclSetIndexedScalar, TclSetElementOfIndexedArray): added read
- trace triggering for lappend case.
- (Tcl_LappendObjCmd): pass TCL_TRACE_READS to Tcl_ObjGetVar2 to
- trigger possible read traces for new arrays.
+ (TclSetIndexedScalar, TclSetElementOfIndexedArray): added read trace
+ triggering for lappend case.
+ (Tcl_LappendObjCmd): pass TCL_TRACE_READS to Tcl_ObjGetVar2 to trigger
+ possible read traces for new arrays.
* generic/tclExecute.c (TclExecuteByteCode): added TCL_TRACE_READS
- flag to INST_LAPPEND(_ARRAY)_STK case to trigger read traces for
- newly created arrays. Removed unnecessary #ifdef for
- TCL_COMPILE_DEBUG in INST_LOAD_SCALAR1 case.
+ flag to INST_LAPPEND(_ARRAY)_STK case to trigger read traces for newly
+ created arrays. Removed unnecessary #ifdef for TCL_COMPILE_DEBUG in
+ INST_LOAD_SCALAR1 case.
* tests/append.test:
* tests/appendComp.test: added tests for read trace triggering for
@@ -2696,98 +2610,96 @@
2001-07-03 Mo DeJong <mdejong@redhat.com>
- * tests/clock.test (clock-2.5): Adjust test so that it passes
- when the time slice is 60 msecs, now passes under Windows 98.
+ * tests/clock.test (clock-2.5): Adjust test so that it passes when the
+ time slice is 60 msecs, now passes under Windows 98.
2001-07-03 Mo DeJong <mdejong@redhat.com>
- * win/tcl.m4 (SC_CONFIG_CFLAGS): Don't pass the v flag
- to ${AR} when using gcc, verbose output is not needed.
+ * win/tcl.m4 (SC_CONFIG_CFLAGS): Don't pass the v flag to ${AR} when
+ using gcc, verbose output is not needed.
2001-07-03 Don Porter <dgp@users.sourceforge.net>
* tests/unixInit.test (unixInit-2.8): Changed test back to using
- installation layout, adding comments explaining why the test writes
- to the directories it does, and checks to avoid destroying other
- files in /tmp.
+ installation layout, adding comments explaining why the test writes to
+ the directories it does, and checks to avoid destroying other files in
+ /tmp.
2001-07-03 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* tests/unixInit.test (unixInit-1.2): Fixed faults reported in
- Bug#438070 - well, at least enough to work on Solaris - and added
+ [Bug 438070] - well, at least enough to work on Solaris - and added
comments that should make what is going on in the test clearer.
2001-07-02 Jeff Hobbs <jeffh@ActiveState.com>
* tests/util.test: added util-4.6
- * generic/tclUtil.c (Tcl_ConcatObj): Corrected walking backwards
- over utf-8 chars. [Bug #227512]
+ * generic/tclUtil.c (Tcl_ConcatObj): Corrected walking backwards over
+ utf-8 chars. [Bug 227512]
2001-07-02 Don Porter <dgp@users.sourceforge.net>
- * tests/unixInit.test (unixInit-2.8): Corrected test for all
- absolute pathnames in library path when executable is installed
- near root directory to use correct development directory layout.
- [Bug 438014]
+ * tests/unixInit.test (unixInit-2.8): Corrected test for all absolute
+ pathnames in library path when executable is installed near root
+ directory to use correct development directory layout. [Bug 438014]
- * tests/unixInit.test (unixInit-2.9):
+ * tests/unixInit.test (unixInit-2.9):
* unix/tclUnixInit.c (TclpInitLibraryPath):
* win/tclWinInit.c (TclpInitLibraryPath): Corrected buggy
- construction of search path entries relative to executable.
- Added test for bad construction. [Bug 438014]
+ construction of search path entries relative to executable. Added test
+ for bad construction. [Bug 438014]
2001-06-28 Miguel Sofer <msofer@users.sourceforge.net>
- * generic/tclNamesp.c: Correction to faulty patch from [Bug: 231259]
+ * generic/tclNamesp.c: Correction to faulty patch from [Bug 231259]
2001-06-28 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * tests/unixInit.test (unixInit-1.2): Modified so as not to
- require a local echo service, which fails on many systems which
- have that turned off for security reasons...
+ * tests/unixInit.test (unixInit-1.2): Modified so as not to require a
+ local echo service, which fails on many systems which have that turned
+ off for security reasons...
2001-06-27 Jeff Hobbs <jeffh@ActiveState.com>
* generic/tclInt.h:
* generic/tclObj.c:
* unix/Makefile.in: added a -DPURIFY mode that makes Tcl_Obj's
- allocated and free singularly (instead of in alloc in blocks and
- never free) to allow checkers like Purify to operate better.
+ allocated and free singularly (instead of in alloc in blocks and never
+ free) to allow checkers like Purify to operate better.
* library/encoding/koi8-u.enc: added koi8-u (Ukranian variant)
encoding.
* tests/subst.test:
- * generic/tclUtf.c (Tcl_UtfBackslash): Corrected backslash
- handling of multibyte utf-8 chars. [Bug #217987]
+ * generic/tclUtf.c (Tcl_UtfBackslash): Corrected backslash handling of
+ multibyte utf-8 chars. [Bug 217987]
- * generic/tclCmdIL.c (InfoProcsCmd): fixed potential mem leak in
- info procs that created objects without using them.
+ * generic/tclCmdIL.c (InfoProcsCmd): fixed potential mem leak in info
+ procs that created objects without using them.
* generic/tclCompCmds.c (TclCompileStringCmd): fixed mem leak when
string command failed to parse the subcommand.
* doc/interp.n:
- * doc/unknown.n: updated notes about what is in a safe interp.
- [Bug #218605]
+ * doc/unknown.n: updated notes about what is in a safe interp. [Bug
+ 218605]
2001-06-27 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * tests/event.test (event-11.5): Removed hard-coded port number
- which could fail on some systems. [Bug #436727]
+ * tests/event.test (event-11.5): Removed hard-coded port number which
+ could fail on some systems. [Bug 436727]
2001-06-26 Mo DeJong <mdejong@redhat.com>
* unix/Makefile.in:
- * win/Makefile.in: Add `make shell` target. This target
- will set the proper env vars before invoking tclsh
- from the build directory.
+ * win/Makefile.in: Add `make shell` target. This target will set the
+ proper env vars before invoking tclsh from the build directory.
2001-06-26 Mo DeJong <mdejong@redhat.com>
- * win/Makefile.in: Use : to separate VPATH entries. This
- works for both Cygwin builds and cross builds, the VPSEP
- variable is simply unneeded complexity.
+ * win/Makefile.in: Use : to separate VPATH entries. This works for
+ both Cygwin builds and cross builds, the VPSEP variable is simply
+ unneeded complexity.
* win/configure: Regen.
* win/configure.in: Don't subst VPSEP.
* win/tcl.m4 (SC_CONFIG_CFLAGS): Remove VPSEP variable.
@@ -2795,17 +2707,17 @@
2001-06-26 Mo DeJong <mdejong@redhat.com>
* unix/configure: Regen.
- * unix/configure.in: Fix last checkin by removing
- export since that only works in bash.
+ * unix/configure.in: Fix last checkin by removing export since that
+ only works in bash.
* win/configure: Regen.
* win/configure.in: Ditto.
2001-06-26 Mo DeJong <mdejong@redhat.com>
* unix/configure: Regen.
- * unix/configure.in: Set CFLAGS to "" if the user
- did not set CFLAGS in the env. This keeps AC_PROG_CC
- from adding "-g -O2" to the CFLAGS by default.
+ * unix/configure.in: Set CFLAGS to "" if the user did not set CFLAGS
+ in the env. This keeps AC_PROG_CC from adding "-g -O2" to the CFLAGS
+ by default.
* win/configure: Regen.
* win/configure.in: Ditto.
@@ -2813,28 +2725,27 @@
* win/configure: Regen.
* win/configure.in: Use RC_DEFINE flag from tcl.m4.
- * win/tcl.m4 (SC_CONFIG_CFLAGS): Set RC_DEFINE
- flag based on the compiler in use.
-
+ * win/tcl.m4 (SC_CONFIG_CFLAGS): Set RC_DEFINE flag based on the
+ compiler in use.
+
2001-06-25 Mo DeJong <mdejong@redhat.com>
- * win/tcl.m4 (SC_CONFIG_CFLAGS): Link to the
- imm32 library when building with mingw gcc.
+ * win/tcl.m4 (SC_CONFIG_CFLAGS): Link to the imm32 library when
+ building with mingw gcc.
2001-06-25 Mo DeJong <mdejong@redhat.com>
* win/configure: Regen.
- * win/tcl.m4 (SC_CONFIG_CFLAGS): When building with
- gcc, don't attempt to link with LD or support dllwrap.
- Simply require a recent version of Cygwin gcc or Mingw
- gcc that supports -shared. When linking, use gcc instead
- of ld since gcc automatically includes libs like -lmsvcrt.
+ * win/tcl.m4 (SC_CONFIG_CFLAGS): When building with gcc, don't attempt
+ to link with LD or support dllwrap. Simply require a recent version of
+ Cygwin gcc or Mingw gcc that supports -shared. When linking, use gcc
+ instead of ld since gcc automatically includes libs like -lmsvcrt.
2001-06-22 Mo DeJong <mdejong@redhat.com>
* win/configure: Regen.
- * win/configure.in: Add resource compiler fix from
- 8.3.3 to fix compiling with mingw.
+ * win/configure.in: Add resource compiler fix from 8.3.3 to fix
+ compiling with mingw.
2001-06-22 Mo DeJong <mdejong@redhat.com>
@@ -2843,63 +2754,61 @@
2001-06-22 Mo DeJong <mdejong@redhat.com>
- * unix/Makefile.in: Set CFLAGS to @CFLAGS@ and @CFLAGS_DEFAULT@.
- Set LDFLAGS to @LDFLAGS@ and @LDFLAGS_DEFAULT@. Add LDFLAGS_DEBUG
- and LDFLAGS_OPTIMIZE to match the way CFLAGS_DEFAULT works.
- This will support user set CFLAGS or LDFLAGS at configure time.
+ * unix/Makefile.in: Set CFLAGS to @CFLAGS@ and @CFLAGS_DEFAULT@. Set
+ LDFLAGS to @LDFLAGS@ and @LDFLAGS_DEFAULT@. Add LDFLAGS_DEBUG and
+ LDFLAGS_OPTIMIZE to match the way CFLAGS_DEFAULT works. This will
+ support user set CFLAGS or LDFLAGS at configure time.
* unix/configure: Regen.
* unix/configure.in: Don't set CFLAGS to CFLAGS_DEFAULT, instead
- subst CFLAGS_DEFAULT into the Makefile. Add AC_SUBST for CFLAGS_DEFAULT,
- LDFLAGS_DEFAULT, LDFLAGS_DEBUG, and LDFLAGS_OPTIMIZE.
- * unix/tcl.m4 (SC_ENABLE_SYMBOLS): Modify LDFLAGS_DEFAULT so that
- it uses a Makefile variable just like CFLAGS_DEFAULT.
- * win/Makefile.in: Set CFLAGS to @CFLAGS@ and @CFLAGS_DEFAULT@.
- Set LDFLAGS to @LDFLAGS@ and @LDFLAGS_DEFAULT@.
- This will support user set CFLAGS or LDFLAGS at configure time.
+ subst CFLAGS_DEFAULT into the Makefile. Add AC_SUBST for
+ CFLAGS_DEFAULT, LDFLAGS_DEFAULT, LDFLAGS_DEBUG, and LDFLAGS_OPTIMIZE.
+ * unix/tcl.m4 (SC_ENABLE_SYMBOLS): Modify LDFLAGS_DEFAULT so that it
+ uses a Makefile variable just like CFLAGS_DEFAULT.
+ * win/Makefile.in: Set CFLAGS to @CFLAGS@ and @CFLAGS_DEFAULT@. Set
+ LDFLAGS to @LDFLAGS@ and @LDFLAGS_DEFAULT@. This will support user set
+ CFLAGS or LDFLAGS at configure time.
* win/configure: Regen.
* win/configure.in: Don't set CFLAGS or LDFLAGS, instead subst
CFLAGS_DEFAULT and LDFLAGS_DEFAULT into the Makefile.
- * win/tcl.m4 (SC_ENABLE_SYMBOLS): Modify LDFLAGS_DEFAULT so that
- it uses a Makefile variable just like CFLAGS_DEFAULT.
+ * win/tcl.m4 (SC_ENABLE_SYMBOLS): Modify LDFLAGS_DEFAULT so that it
+ uses a Makefile variable just like CFLAGS_DEFAULT.
2001-06-22 Mo DeJong <mdejong@redhat.com>
* win/configure:
- * win/tcl.m4 (SC_CONFIG_CFLAGS): Don't set LDFLAGS_DEBUG
- to -g or LDFLAGS_OPTIMIZE to -O when compiling with gcc.
- These flags are not needed and can cause problems with
- the Cygwin version of ld.
+ * win/tcl.m4 (SC_CONFIG_CFLAGS): Don't set LDFLAGS_DEBUG to -g or
+ LDFLAGS_OPTIMIZE to -O when compiling with gcc. These flags are not
+ needed and can cause problems with the Cygwin version of ld.
2001-06-18 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * tests/unixInit.test (unixInit-1.2,unixInit-2.8): Added test for
- code described below, and fixed a couple of errors that caused
- problems during testing; the code to determine the installedTcl
- constraint was wrong, and test unixInit-2.8 assumed that /tmp/lib
- was free for use and could be deleted, which clashed nastily with
- my installation and made other tests fail unnecessarily!
+ * tests/unixInit.test (unixInit-1.2,unixInit-2.8): Added test for code
+ described below, and fixed a couple of errors that caused problems
+ during testing; the code to determine the installedTcl constraint was
+ wrong, and test unixInit-2.8 assumed that /tmp/lib was free for use
+ and could be deleted, which clashed nastily with my installation and
+ made other tests fail unnecessarily!
* unix/tclUnixChan.c (TtyInit,TclpOpenFileChannel,
- Tcl_MakeFileChannel,TclpGetDefaultStdChannel): Alterations so that
- the standard channels - stdin, stdout and stderr - have the
- correct type and fconfigure options. This required making the
- initialisation of serial lines a little more sophisticated to
- make the console behave correctly in interactive mode... [Bug
- #219137 and duplicates]
+ (Tcl_MakeFileChannel,TclpGetDefaultStdChannel): Alterations so that
+ the standard channels - stdin, stdout and stderr - have the correct
+ type and fconfigure options. This required making the initialisation
+ of serial lines a little more sophisticated to make the console behave
+ correctly in interactive mode... [Bug 219137 and duplicates]
2001-06-16 Don Porter <dgp@users.sourceforge.net>
* generic/tclInt.decls:
- * generic/tclInt.h:
+ * generic/tclInt.h:
* generic/tclPanic.c (Tcl_PanicVA):
* mac/tclMacAppInit.c (main):
* mac/tclMacPanic.c (TclpPanic):
* unix/tclUnixPort.h:
- * win/tclWinPort.h: Replaced TclMacSetPanic with TclpPanic
- for setting a platform-specific panic handler. TclpPanic
- is NULL on Unix and Windows. Fixes broken wish on Mac due
- to earlier patches. [Patch 415648]
-
+ * win/tclWinPort.h: Replaced TclMacSetPanic with TclpPanic for setting
+ a platform-specific panic handler. TclpPanic is NULL on Unix and
+ Windows. Fixes broken wish on Mac due to earlier patches. [Patch
+ 415648]
+
* generic/tclIntPlatDecls.h:
* generic/tclStubInit.c: `make gentubs` after above changes.
@@ -2912,9 +2821,9 @@
2001-06-12 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * tests/regexp.test (regexp-18.12):
+ * tests/regexp.test (regexp-18.12):
* generic/tclCmdMZ.c (Tcl_RegexpObjCmd): Fixed so that submatches
- that do not match always have index pair {-1 -1} [Bug #219232]
+ that do not match always have index pair {-1 -1} [Bug 219232]
2001-06-08 Don Porter <dgp@users.sourceforge.net>
@@ -2927,11 +2836,10 @@
* mac/tclMacAppInit.c (main):
* mac/tclMacBOAAppInit.c (main):
* mac/tclMacPanic.c: Modified special Mac implementations of
- Tcl_*Panic* to be exact copies of the generic implementations.
- Added TclMacSetPanic. The generic implementations should be
- used directly, rather than copies, but that requires further
- changes by someone familiar with the Mac build systems.
- [Patch 415648]
+ Tcl_*Panic* to be exact copies of the generic implementations. Added
+ TclMacSetPanic. The generic implementations should be used directly,
+ rather than copies, but that requires further changes by someone
+ familiar with the Mac build systems. [Patch 415648]
* generic/tclDecls.h:
* generic/tclIntPlatDecls.h:
@@ -2939,24 +2847,24 @@
* doc/Panic.3:
* unix/mkLinks: New file documenting Tcl_*Panic* public interfaces,
- followed by `make mklinks`. [Patch 415648, Bug 219170, Bug 414936]
+ followed by `make mklinks`. [Patch 415648, Bug 219170, Bug 414936]
2001-06-03 Jeff Hobbs <jeffh@ActiveState.com>
* generic/tclUtil.c (Tcl_DStringAppendElement): patch to save an
- extra strlen call. [Bug #428572]
+ extra strlen call. [Bug 428572]
2001-05-30 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* generic/tclExecute.c (TclExecuteByteCode): Added two casts to
- INST_STR_CMP implementation to get rid of a couple warnings from
- the SUNWspro C compiler.
-
- * generic/tclBasic.c (Tcl_GetMathFuncInfo,Tcl_ListMathFuncs):
- * generic/tclCmdIL.c (Tcl_InfoObjCmd,InfoFunctionsCmd):
- * generic/tcl.decls (generic table, positions 435+436):
- * tests/info.test:
- * doc/CrtMathFnc.3:
+ INST_STR_CMP implementation to get rid of a couple warnings from the
+ SUNWspro C compiler.
+
+ * generic/tclBasic.c (Tcl_GetMathFuncInfo,Tcl_ListMathFuncs):
+ * generic/tclCmdIL.c (Tcl_InfoObjCmd,InfoFunctionsCmd):
+ * generic/tcl.decls (generic table, positions 435+436):
+ * tests/info.test:
+ * doc/CrtMathFnc.3:
* doc/info.n: Changes due to TIP #15 "Functions to List and Detail
Math Functions"
@@ -2968,32 +2876,31 @@
* generic/regc_locale.c: updated character class range data for
Unicode v3.1.0 compliance.
- * generic/tclUniData.c: regenerated from Unicode v3.1.0 data file
- (new as of 2001-05-16). This brings Tcl to current unicode
- compliance.
+ * generic/tclUniData.c: regenerated from Unicode v3.1.0 data file (new
+ as of 2001-05-16). This brings Tcl to current unicode compliance.
* tests/utf.test: added tests to check unicode 3 compliance
* unix/Makefile.in (tclUtf.o): added tclUniData.c dependency.
- * tools/uniClass.tcl: added comments to output format and the
- script for clarification.
+ * tools/uniClass.tcl: added comments to output format and the script
+ for clarification.
- * tools/uniParse.tcl: corrected filename output and GetDelta macro
- to use 'info' as param (was 'infO')
+ * tools/uniParse.tcl: corrected filename output and GetDelta macro to
+ use 'info' as param (was 'infO')
2001-05-26 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* generic/tclVar.c (tclArraySearchType,SetArraySearchObj,
- ParseSearchId): Added code to speed up array searching by reducing
+ (ParseSearchId): Added code to speed up array searching by reducing
the amount of parsing needed for searchIds.
- * generic/tclObj.c (TclInitObjSubsystem):
- * generic/tclIndexObj.c (Tcl_GetIndexFromObjStruct):
- * generic/tclNamesp.c (TclInitNamespaceSubsystem):
+ * generic/tclObj.c (TclInitObjSubsystem):
+ * generic/tclIndexObj.c (Tcl_GetIndexFromObjStruct):
+ * generic/tclNamesp.c (TclInitNamespaceSubsystem):
* generic/tclInt.h: Moved some Tcl_ObjType initialisation to
- TclInitObjSubsystem to be with the bulk of the rest.
- [Patch 424851] Committed by Miguel Sofer <mig@utdt.edu>
+ TclInitObjSubsystem to be with the bulk of the rest. [Patch 424851]
+ Committed by Miguel Sofer <mig@utdt.edu>
2001-05-23 Jeff Hobbs <jeffh@ActiveState.com>
@@ -3015,31 +2922,29 @@
* library/encoding/iso8859-8.enc:
* library/encoding/iso8859-10.enc (new):
* library/encoding/iso8859-13.enc (new):
- * library/encoding/iso8859-14.enc (new): updated encoding tables
- based on http://www.unicode.org/Public/MAPPINGS/. (kuhn)
+ * library/encoding/iso8859-14.enc (new): updated encoding tables based
+ on http://www.unicode.org/Public/MAPPINGS/. (kuhn)
2001-05-23 Mo DeJong <mdejong@redhat.com>
- * unix/tcl.m4 (SC_PATH_TCLCONFIG): Fix comments,
- and typo in cached variable name.
+ * unix/tcl.m4 (SC_PATH_TCLCONFIG): Fix comments, and typo in cached
+ variable name.
2001-05-23 Mo DeJong <mdejong@redhat.com>
- * unix/tcl.m4 (SC_LOAD_TKCONFIG):
- Remove use of undefined TCLCONFIG variable and
- call AC_MSG_RESULT to print the checking result.
+ * unix/tcl.m4 (SC_LOAD_TKCONFIG): Remove use of undefined TCLCONFIG
+ variable and call AC_MSG_RESULT to print the checking result.
* win/tcl.m4: Ditto.
2001-05-22 Jeff Hobbs <jeffh@ActiveState.com>
* generic/tclObj.c (TclAllocateFreeObjects): simplified
- objSizePlusPadding to use sizeof(Tcl_Obj) (max)
- Corrected use of tclObjsAlloced/Freed/Shared in TCL_MEM_DEBUG
- compile.
+ objSizePlusPadding to use sizeof(Tcl_Obj) (max) Corrected use of
+ tclObjsAlloced/Freed/Shared in TCL_MEM_DEBUG compile.
2001-05-22 Miguel Sofer <msofer@users.sourceforge.net>
- * generic/tclExecute.c: removed Tcl_DuplicateObj in INST_DUP
+ * generic/tclExecute.c: removed Tcl_DuplicateObj in INST_DUP
2001-05-21 Jeff Hobbs <jeffh@ActiveState.com>
@@ -3047,13 +2952,13 @@
getting affected by Windows env handling of empty valued elements.
* unix/tcl.m4: added more common install directories in which to
- search for *Config.sh [Bug #419812]
+ search for *Config.sh. [Bug 419812]
- * tests/cmdMZ.test (cmdMZ-1.4): added notLinux constraint to test
- to prevent failure message on Linux due to OS caching bug.
+ * tests/cmdMZ.test (cmdMZ-1.4): added notLinux constraint to test to
+ prevent failure message on Linux due to OS caching bug.
- * tests/httpd (httpdRespond): added response to timeout value in
- query string.
+ * tests/httpd (httpdRespond): added response to timeout value in query
+ string.
* tests/http.test: removed unused notLinux constraint setting
@@ -3063,61 +2968,58 @@
2001-05-19 Andreas Kupries <andreas_kupries@users.sourceforge.net>
* Note that "tclbench" (see project "tcllib") was extended with
- performance benchmarks for [fcopy] too.
+ performance benchmarks for [fcopy] too.
* doc/fcopy.n: Updated to reflect the extended behaviour of 'fcopy'.
- * tests/io.test: Added tests 'io-52.9', 'io-52.10' and 'io-52.11'
- to test the handling of encodings by 'fcopy' / 'TclCopychannel'
- [Bug #209210].
+ * tests/io.test: Added tests 'io-52.9', 'io-52.10' and 'io-52.11' to
+ test the handling of encodings by 'fcopy' / 'TclCopychannel'. [Bug
+ 209210]
- * generic/tclIO.c: Split of both 'Tcl_ReadChars' and
- 'Tcl_WriteChars' into a public error checking and an internal
- working part. The public functions now use the new internal
- ones. The new functions are 'DoReadChars' and 'DoWriteChars'.
- Extended 'CopyData' to use the new functions 'DoXChars' when
- required by the encodings on the input and output channels
- [Bug #209210].
+ * generic/tclIO.c: Split of both 'Tcl_ReadChars' and 'Tcl_WriteChars'
+ into a public error checking and an internal working part. The public
+ functions now use the new internal ones. The new functions are
+ 'DoReadChars' and 'DoWriteChars'. Extended 'CopyData' to use the new
+ functions 'DoXChars' when required by the encodings on the input and
+ output channels. [Bug 209210]
2001-05-16 Jeff Hobbs <jeffh@ActiveState.com>
- * library/history.tcl (tcl::HistAdd): prevent empty calls from
- being added to the history (arndt)
+ * library/history.tcl (tcl::HistAdd): prevent empty calls from being
+ added to the history (arndt)
- * tests/error.test: updated error-1.3 message to account for
- string index being compiled at toplevel.
+ * tests/error.test: updated error-1.3 message to account for string
+ index being compiled at toplevel.
* tests/appendComp.test:
* tests/stringComp.test: new files for extended bytecode testing
* generic/tclBasic.c: added new CompileProc invocations to basic
command initialization.
* generic/tclCompCmds.c: added new compile commands for append,
- lappend, lindex and llength. Refactored set and incr compile
- commands to use new TclPushVarName function for handling the
- varname component during compilation (also used by append and
- lappend). Changed string compile command to compile toplevel code
- as well (when possible).
+ lappend, lindex and llength. Refactored set and incr compile commands
+ to use new TclPushVarName function for handling the varname component
+ during compilation (also used by append and lappend). Changed string
+ compile command to compile toplevel code as well (when possible).
* generic/tclCompile.c: added new instruction enums
* generic/tclCompile.h: added debug info for new instructions
- * generic/tclExecute.c (TclExecuteByteCode): moved elemPtr to
- toplevel var (oft-used). Added definitions for new bytecode
- instructions INST_LIST_INDEX, INST_LIST_LENGTH, INST_APPEND_SCALAR1,
+ * generic/tclExecute.c (TclExecuteByteCode): moved elemPtr to toplevel
+ var (oft-used). Added definitions for new bytecode instructions
+ INST_LIST_INDEX, INST_LIST_LENGTH, INST_APPEND_SCALAR1,
INST_APPEND_SCALAR4, INST_APPEND_ARRAY1, INST_APPEND_ARRAY4,
INST_APPEND_ARRAY_STK, INST_APPEND_STK, INST_LAPPEND_SCALAR1,
INST_LAPPEND_SCALAR4, INST_LAPPEND_ARRAY1, INST_LAPPEND_ARRAY4,
INST_LAPPEND_ARRAY_STK, INST_LAPPEND_STK.
Refactored repititious code for reuse with INST_LOAD_STK (same as
- INST_LOAD_SCALAR_STK), INST_STORE_STK (same as
- INST_STORE_SCALAR_STK).
+ INST_LOAD_SCALAR_STK), INST_STORE_STK (same as INST_STORE_SCALAR_STK).
Updated INST_STR_CMP with style of fix of 2001-04-06 Fellows
- [Bug #219201] as that fix only affected the runtime eval'ed
- "string" (string compare is normally byte-compiled now). We
- may want to back these out for speed in the future, noting the
- problems with \x00 comparisons in the docs.
+ [Bug 219201] as that fix only affected the runtime eval'ed "string"
+ (string compare is normally byte-compiled now). We may want to back
+ these out for speed in the future, noting the problems with \x00
+ comparisons in the docs.
* generic/tclInt.h: declarations for new compile commands.
* generic/tclVar.c: change TclGetIndexedScalar,
TclGetElementOfIndexedArray, TclSetElementOfIndexedArray and
- TclSetIndexedScalar to use flags. The Set functions now support
+ TclSetIndexedScalar to use flags. The Set functions now support
TCL_APPEND_ELEMENT and TCL_LIST_ELEMENT as well.
* generic/tclInt.decls:
* generic/tclIntDecls.h: minor signature changes for above.
@@ -3126,7 +3028,7 @@
2001-05-16 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * doc/console.n: Deleted. Put it in the wrong source tree! D'oh!
+ * doc/console.n: Deleted. Put it in the wrong source tree! D'oh!
2001-05-15 Jeff Hobbs <jeffh@ActiveState.com>
@@ -3136,8 +3038,8 @@
* generic/tclStringObj.c (Tcl_GetUnicodeFromObj): new function to
parallel Tcl_GetStringFromObj (fix of an API oversight).
- * unix/tclUnixPipe.c: updated pipeChannelType to
- TCL_CHANNEL_VERSION_2 type specification.
+ * unix/tclUnixPipe.c: updated pipeChannelType to TCL_CHANNEL_VERSION_2
+ type specification.
* tests/fileName.test: corrected tests not to fail on win when a
C:/test dir exists.
@@ -3146,82 +3048,80 @@
2001-05-15 Miguel Sofer <msofer@users.sourceforge.net>
- * tests/lindex.test: added test for nested braces [Patch: 423617]
+ * tests/lindex.test: added test for nested braces [Patch 423617]
2001-05-15 Miguel Sofer <msofer@users.sourceforge.net>
- * generic/tclInt.h
- * generic/tclNamesp.c: invalidate all bytecodes in a namespace if
- a new command shadows a bytecoded command.
- * tests/namespace.test
- Patched from [Bug: 231259]
+ * generic/tclInt.h:
+ * generic/tclNamesp.c: invalidate all bytecodes in a namespace if a
+ new command shadows a bytecoded command.
+ * tests/namespace.test:
+ Patched from [Bug 231259]
2001-05-15 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * doc/console.n: Created. It seems very odd to me that the
- console implementation is part of the Tcl distribution and not
- part of Tk, but given the location of the source, the
- documentation must obviously match up...
+ * doc/console.n: Created. It seems very odd to me that the console
+ implementation is part of the Tcl distribution and not part of Tk, but
+ given the location of the source, the documentation must obviously
+ match up...
2001-05-14 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * generic/tclCmdMZ.c (Tcl_StringObjCmd):
- * tests/string.test (string-4.14): Negative string indices should
- not be added as offsets to the result of [string first] but
- instead be treated as referring to the start of the string.
- [Bug: 423581]
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd):
+ * tests/string.test (string-4.14): Negative string indices should not
+ be added as offsets to the result of [string first] but instead be
+ treated as referring to the start of the string. [Bug 423581]
2001-05-11 Mo DeJong <mdejong@redhat.com>
- * unix/Makefile.in: Add a LDFLAGS variable to the
- Makefile instead of directly substing @LDFLAGS@.
+ * unix/Makefile.in: Add a LDFLAGS variable to the Makefile instead of
+ directly substing @LDFLAGS@.
* unix/configure: Regen.
- * unix/tcl.m4: Fix CFLAGS_DEFAULT so that the name
- of a Makefile variable is passed as @CFLAGS@.
- * win/Makefile.in: Move the setting of CFLAGS
- higher up in the Makefile.
+ * unix/tcl.m4: Fix CFLAGS_DEFAULT so that the name of a Makefile
+ variable is passed as @CFLAGS@.
+ * win/Makefile.in: Move the setting of CFLAGS higher up in the
+ Makefile.
* win/configure: Regen.
- * win/configure.in: Use dnl to comment out macros
- so that they are not accidently expanded.
- * win/tcl.m4: Fix CFLAGS_DEFAULT so that the name
- of a Makefile variable is passed as @CFLAGS@.
+ * win/configure.in: Use dnl to comment out macros so that they are not
+ accidently expanded.
+ * win/tcl.m4: Fix CFLAGS_DEFAULT so that the name of a Makefile
+ variable is passed as @CFLAGS@.
2001-05-07 Miguel Sofer <msofer@users.sourceforge.net>
* generic/tclExecute.c: insure different rand() seeds in different
- threads [Bug 416643]
+ threads. [Bug 416643]
2001-05-03 Jeff Hobbs <jeffh@ActiveState.com>
* tests/tcltest.test: removed extraneous 'c' (doh!) [Bug: 414031]
- * tools/tcltk-man2html.tcl: removed use of 'exec' for portability
- and fixed up code.
+ * tools/tcltk-man2html.tcl: removed use of 'exec' for portability and
+ fixed up code.
2001-05-03 Don Porter <dgp@users.sourceforge.net>
* doc/library.n:
* library/init.tcl:
- * tests/autoMkindex.t*: Modified [auto_import] to apply
- pattern matching in the [namespace import] style. [Bug 420186]
- ***POTENTIAL INCOMPATIBILITY*** for any callers of [auto_import]
- from outside Tcl that expect the pattern matching to be like that
- of [string match].
+ * tests/autoMkindex.t*: Modified [auto_import] to apply pattern
+ matching in the [namespace import] style. [Bug 420186]
+ ***POTENTIAL INCOMPATIBILITY*** for any callers of [auto_import] from
+ outside Tcl that expect the pattern matching to be like that of
+ [string match].
2001-05-03 Miguel Sofer <msofer@users.sourceforge.net>
- * generic/tclParse.c:
- * tests/namespace.test: Insure consistent behaviour of the
- [unknown] command: when a command is unknown, it is always
- processed by [::unknown], ignoring any namespace proc which
- happens to be called "unknown" [Patch #421166, Bug #420507]
+ * generic/tclParse.c:
+ * tests/namespace.test: Insure consistent behaviour of the [unknown]
+ command: when a command is unknown, it is always processed by
+ [::unknown], ignoring any namespace proc which happens to be called
+ "unknown" [Patch 421166, Bug 420507]
2001-05-02 Don Porter <dgp@users.sourceforge.net>
- * tools/genStubs.tcl: Add a package require of Tcl 8
- at the beginning of the script so that the script
- will print a descriptive error message when run
- in an old Tcl 7 shell.
+ * tools/genStubs.tcl: Add a package require of Tcl 8 at the beginning
+ of the script so that the script will print a descriptive error
+ message when run in an old Tcl 7 shell.
2001-04-27 Kevin Kenny <kennykb@crd.ge.com>
@@ -3229,10 +3129,10 @@
* generic/tclInt.h:
* generic/tclCmdIL.c:
* generic/tclProc.c:
- * generic/tclVar.c: Added another collection of missing CONSTs
- related to TclGetNamespaceForQualName.
+ * generic/tclVar.c: Added another collection of missing CONSTs related
+ to TclGetNamespaceForQualName.
* generic/tclIntDecls.h: Regenerated.
-
+
2001-04-25 Mo DeJong <mdejong@redhat.com>
* unix/configure: Regen.
@@ -3245,9 +3145,9 @@
2001-04-25 Mo DeJong <mdejong@redhat.com>
* unix/configure: Regen.
- * unix/configure.in: Use $@ in MAKE_LIB and MAKE_STUB_LIB
- commands instead of using a delayed subst variable. Replace
- instances of STUB_LIB_FILE with TCL_STUB_LIB_FILE.
+ * unix/configure.in: Use $@ in MAKE_LIB and MAKE_STUB_LIB commands
+ instead of using a delayed subst variable. Replace instances of
+ STUB_LIB_FILE with TCL_STUB_LIB_FILE.
2001-04-25 Mo DeJong <mdejong@redhat.com>
@@ -3259,19 +3159,20 @@
2001-04-25 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* tools/encoding/iso8859-15.txt:
- * library/encoding/iso8859-15.enc: Oops! Got the full encoding
- wrong. Should be fixed now...
+ * library/encoding/iso8859-15.enc: Oops! Got the full encoding wrong.
+ Should be fixed now...
* tools/encoding/iso8859-15.txt:
* library/encoding/iso8859-15.enc:
- * tools/tcl.wse.in: Added ISO 8859-15 (a.k.a. Latin-1 + Euro
- currency symbol) support.
+ * tools/tcl.wse.in: Added ISO 8859-15 (a.k.a. Latin-1 + Euro currency
+ symbol) support.
* generic/tclNamesp.c:
- * generic/tclBasic.c (TclRenameCommand): Missing CONST from
- several declarations relating to use of TclGetNamespaceForQualName
+ * generic/tclBasic.c (TclRenameCommand): Missing CONST from several
+ declarations relating to use of TclGetNamespaceForQualName
2001-04-24 Kevin B. Kenny <kennykb@acm.org>
+
* doc/AssocData.3:
* doc/CrtCommand.3:
* doc/CrtMathFnc.3:
@@ -3285,18 +3186,18 @@
* generic/tcl.h:
* generic/tclInt.decls:
* generic/tclInt.h: (TIP #27) Another round of CONST changes, this
- time adding CONST to the API's exported from tclBasic.c.
- [Patch #415179]
- ***POTENTIAL INCOMPATIBILITY*** from 8.4a2, in which Vince
- Darley's changes to command tracing were added. A const has been
- added to the type signature of one of the parameters to
- Tcl_CommandTraceProc.
+ time adding CONST to the API's exported from tclBasic.c. [Patch
+ 415179]
+ ***POTENTIAL INCOMPATIBILITY*** from 8.4a2, in which Vince Darley's
+ changes to command tracing were added. A const has been added to the
+ type signature of one of the parameters to Tcl_CommandTraceProc.
2001-04-10 Kevin B. Kenny <kennykb@acm.org>
+
* unix/tclUnixTime.c: Altered code to use memcpy instead of
structure assigments in an effort to achieve better K&R
compatibility.
-
+
2001-04-10 Kevin B. Kenny <kennykb@acm.org>
* unix/tclUnixTime.c: Fixed silly typo in calls to 'gmtime' and
@@ -3304,125 +3205,122 @@
2001-04-09 Kevin B. Kenny <kennykb@acm.org>
- * unix/tclLoadShl.c: Added DYNAMIC_PATH to the load flags so that
- the SHLIB_PATH will be searched for other libraries. [Bug #219140]
-
+ * unix/tclLoadShl.c: Added DYNAMIC_PATH to the load flags so that the
+ SHLIB_PATH will be searched for other libraries. [Bug 219140]
+
2001-04-09 Kevin B. Kenny <kennykb@acm.org>
- * unix/tcl.m4: Added _REENTRANT to Solaris build so that thread
- safe library routines are included.
+ * unix/tcl.m4: Added _REENTRANT to Solaris build so that thread safe
+ library routines are included.
* unix/configure: Re-ran 'autoconf' with changed tcl.m4
* tclUnixTime.c: Modified for thread safety of 'gmtime' and
- 'localtime' system calls [Bugs #219136 and #232558]
-
+ 'localtime' system calls. [Bugs 219136 and 232558]
+
2001-04-09 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* tests/expr.test (expr-21.*): Tests to check below fix.
* generic/tclParseExpr.c (GetLexeme): Now recognises the
non-numeric boolean literals for what they are. It no longer makes
sense for anyone to create functions with the same name as one of
- them, but this was true in 7.* as well [Bug #217777; finally!]
+ them, but this was true in 7.* as well [Bug 217777; finally!]
2001-04-07 Miguel Sofer <msofer@users.sourceforge.net>
- * generic/tclExecute.c: Avoid panic when there are extra items in
- the tcl stack [Bug #406709, Patch #414470]
+ * generic/tclExecute.c: Avoid panic when there are extra items in the
+ tcl stack. [Bug 406709, Patch 414470]
* tests/foreach.test: test to exercise the patch
2001-04-07 Miguel Sofer <msofer@users.sourceforge.net>
* doc/namespace.n: document correct functionality
* generic/tclNamesp.c: corrected behaviour of [namespace code]
- (Bug #219385, Patch #403530)
+ [Bug 219385, Patch 403530]
* library/init.tcl:
* tests/namespace-old.test: test correct functionality
* tests/namespace.test: test correct functionality
2001-04-07 Andreas Kupries <andreas_kupries@users.sourceforge.net>
- * unix/Makefile.in (checkdoc): New target, checking the
- definitions as found in the compiled library against the
- manpages to find undocumented public functionality.
+ * unix/Makefile.in (checkdoc): New target, checking the definitions as
+ found in the compiled library against the manpages to find
+ undocumented public functionality.
* unix/mkLinks: Updated to include the new manpage.
* doc/UniCharIsAlpha.3: New manpage documenting the Unicode
- character classification APIs [Bug #218720].
+ character classification APIs. [Bug 218720]
2001-04-07 Andreas Kupries <andreas_kupries@users.sourceforge.net>
* unix/mkLinks: Updated to incorporate the changes below.
* doc/StringObj.3: Added 'Tcl_AttemptSetObjLength' to the NAME
- section. [Bug #414435].
+ section. [Bug 414435]
- * doc/Alloc.3: Added both 'Tcl_AttemptAlloc' and
- 'Tcl_AttemptRealloc' to the NAME section. [Bug #414435].
+ * doc/Alloc.3: Added both 'Tcl_AttemptAlloc' and 'Tcl_AttemptRealloc'
+ to the NAME section. [Bug 414435]
* doc/Utf.3: Added both 'Tcl_UniCharCaseMatch' and
- 'Tcl_UniCharNcasecmp' to the NAME section. [Bug #414435].
+ 'Tcl_UniCharNcasecmp' to the NAME section. [Bug 414435]
2001-04-06 Don Porter <dgp@users.sourceforge.net>
* library/init.tcl:
- * tests/init.test: Modified processing of $::errorInfo by
- [unknown] when the auto-loaded command throws an error to better
- cover the tracks of auto-loading. [Bug 219280, Patch 403551]
+ * tests/init.test: Modified processing of $::errorInfo by [unknown]
+ when the auto-loaded command throws an error to better cover the
+ tracks of auto-loading. [Bug 219280, Patch 403551]
2001-04-06 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* doc/read.n: Added section on "USE WITH SERIAL PORTS" to resolve
- [Bug #219402]
+ [Bug 219402]
* tests/string.test (string-2.30): Test for this case
* generic/tclCmdMZ.c (Tcl_StringObjCmd, STR_COMPARE branch): Fixed
problem caused by Utf-rep of \x00 being more than Utf-rep of \x01
- fooling memcmp by forcing everything through Utf-based
- comparisons. Added optimizations for case where objects have a
- string/unicode-rep or a bytearray-rep (i.e. where we can perform
- comparisons on fixed-size units.) [Bug #219201]
+ fooling memcmp by forcing everything through Utf-based comparisons.
+ Added optimizations for case where objects have a string/unicode-rep
+ or a bytearray-rep (i.e. where we can perform comparisons on
+ fixed-size units). [Bug 219201]
* generic/tclUtf.c (Tcl_UtfNcmp): Corrected seriously erroneous
comment.
2001-04-05 Andreas Kupries <andreas_kupries@users.sourceforge.net>
- * doc/Macintosh.3: Removed duplicates from .SH line
- [Bug #413983].
+ * doc/Macintosh.3: Removed duplicates from .SH line. [Bug 413983]
2001-04-05 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* generic/tclCmdMZ.c (Tcl_StringObjCmd): Fixed so will compile
- with K&R compilers [Patch #413844, Bug #413847]
+ with K&R compilers. [Patch 413844, Bug 413847]
2001-04-04 Don Porter <dgp@users.sourceforge.net>
* generic/tclMain.c: Patch from Kevin Kenny to restore support of
- pre-ANSI compilers. [Bug 413846, Patch 413842]
+ pre-ANSI compilers. [Bug 413846, Patch 413842]
2001-04-04 Andreas Kupries <andreas_kupries@users.sourceforge.net>
* unix/mkLinks: Updated to contain the new manpage.
- * doc/Environment.3: New manpage, describes Tcl_PutEnv
- [Bug #219171].
+ * doc/Environment.3: New manpage, describes Tcl_PutEnv. [Bug 219171]
- * doc/Macintosh.3: New manpage describing the macintosh specific
- parts of the public API [Bug #219169].
+ * doc/Macintosh.3: New manpage describing the macintosh specific parts
+ of the public API. [Bug 219169]
2001-04-04 Jeff Hobbs <jeffh@ActiveState.com>
* unix/configure:
* unix/tcl.m4: extended test of termios vs. termio vs. sgtty to
better detect result on Linux and when certain configure
- redirections are being used. (max) [Patch #402923; Bug #227412,
- #219194]
+ redirections are being used. [Patch 402923; Bug 227412, 219194] (max)
2001-04-04 Andreas Kupries <andreas_kupries@users.sourceforge.net>
* generic/tclTest.c:
* tests/io.tests: TIP #10 followup correcting a problem with the
- original patch because of the lack of 'testthread id' for a
- non-threaded compilation.
+ original patch because of the lack of 'testthread id' for a
+ non-threaded compilation.
2001-04-04 Kevin Kenny <kennykb@acm.org>
@@ -3440,24 +3338,24 @@
* generic/tclObj.c:
* generic/tclPkg.c:
* generic/tclStringObj.c:
- * generic/tclStubLib.c:
- (TIP#27) Changed a number of Tcl API's to accept "CONST char*"
- in place of simple "char*". (kennykb) [Patch #404026]
+ * generic/tclStubLib.c: (TIP#27) Changed a number of Tcl API's to
+ accept "CONST char*" in place of simple "char*". (kennykb) [Patch
+ 404026]
2001-04-04 Jeff Hobbs <jeffh@ActiveState.com>
* generic/tclListObj.c (Tcl_SetListObj): set objPtr->length = 0 in
empty object case to maintain sanctity of Tcl_Obj bytes/length
- pairing. (porter) [Patch #405998]
+ pairing. [Patch 405998] (porter)
2001-04-03 Andreas Kupries <andreas_kupries@users.sourceforge.net>
* unix/mkLinks: Added 'Signal.3', 'Tcl_WaitPid'.
- * doc/DetachPids.3: Added description of 'Tcl_WaitPid' [Bug #219173].
+ * doc/DetachPids.3: Added description of 'Tcl_WaitPid' [Bug 219173].
* doc/Signal.3: New man page describing the public API procedures
- 'Tcl_SignalId' and 'Tcl_SignalMsg' [Bug #219172].
+ 'Tcl_SignalId' and 'Tcl_SignalMsg'. [Bug 219172]
2001-04-02 Jeff Hobbs <jeffh@ActiveState.com>
@@ -3466,7 +3364,7 @@
* win/README.binary: further notes corrections.
* win/configure:
- * win/tcl.m4 (SHLIB_LD): added -incremental:no. [Bug #219381]
+ * win/tcl.m4 (SHLIB_LD): added -incremental:no. [Bug 219381]
2001-04-01 Jeff Hobbs <jeffh@ActiveState.com>
@@ -3474,8 +3372,8 @@
* mac/README:
* win/README:
* win/README.binary:
- * unix/README: updated patchlevel information to 8.4a3 and
- updated links and notes.
+ * unix/README: updated patchlevel information to 8.4a3 and updated
+ links and notes.
* generic/tcl.h:
* tools/tcl.wse.in:
@@ -3489,18 +3387,17 @@
* generic/tclCkalloc.c (TclFinalizeMemorySubsystem): set curTagPtr
to NULL to allow for reuse.
- * generic/tclEvent.c (Tcl_Finalize): moved the tsdPtr
- initialization inside the subsystemsInitialized check to prevent
- it potentially getting called twice during finalization. (wu)
- [Patch #403532, Bug #219391]
+ * generic/tclEvent.c (Tcl_Finalize): moved the tsdPtr initialization
+ inside the subsystemsInitialized check to prevent it potentially
+ getting called twice during finalization.
+ [Patch 403532, Bug 219391] (wu)
* generic/tclThreadTest.c (Tcl_ThreadObjCmd): cast fixes
- * generic/tclTest.c (TestChannelCmd): added cast to mollify
- Windows debug build.
+ * generic/tclTest.c (TestChannelCmd): added cast to mollify Windows
+ debug build.
* win/tclWinSock.c (SocketEventProc): Fixed race condition in
- readability of socket on Windows.
- [Patch #410674, Bug #219205 #219333]
+ readability of socket on Windows. [Patch 410674, Bug 219205, 219333]
* win/tcl.m4: added imm32.lib to LIBS_GUI for Tk IME support.
@@ -3512,38 +3409,36 @@
2001-03-30 Andreas Kupries <andreas_kupries@users.sourceforge.net>
* All of the changes below belong to TIP #10 [Tcl I/O Enhancement:
- Thread-Aware Channels]. See also [Patch #403358] at SF.
+ Thread-Aware Channels]. See also [Patch 403358] at SF.
* generic/tclIO.h (struct ChannelState, line 236f): Extended the
- structure with a new field of type 'Tcl_ThreadId' to hold the id
- of the thread currently managing all channels with this state.
+ structure with a new field of type 'Tcl_ThreadId' to hold the id of
+ the thread currently managing all channels with this state.
- Note: This structure is shared by all channels in a stack of
- transformations.
+ Note: This structure is shared by all channels in a stack of
+ transformations.
- * generic/tclIO.c (Tcl_CreateChannel, lines 1058-1065): Modified
- to store the Id of the current thread in the 'ChannelState' of
- the new channel.
+ * generic/tclIO.c (Tcl_CreateChannel, lines 1058-1065): Modified to
+ store the Id of the current thread in the 'ChannelState' of the new
+ channel.
- * generic/tclIO.c (Tcl_SpliceChannel, lines 2265-2270): Modified
- in the same manner as 'Tcl_CreateChannel' as the channel will be
- managed by the current thread afterward.
+ * generic/tclIO.c (Tcl_SpliceChannel, lines 2265-2270): Modified in
+ the same manner as 'Tcl_CreateChannel' as the channel will be managed
+ by the current thread afterward.
* generic/tclIO.c (Tcl_GetChannelThread, lines 1478-1503):
- * generic/tcl.decls (Tcl_GetChannelThread, lines 1504-1506): New
- API function to retrieve the Id of the managing thread from a
- channel. Implementation and declaration.
+ * generic/tcl.decls (Tcl_GetChannelThread, lines 1504-1506): New API
+ function to retrieve the Id of the managing thread from a channel.
+ Implementation and declaration.
* generic/tclTest.c (TestChannelCmd, lines 4520-4532): Added
- subcommand 'mthread' to query a channel about its managing
- thread.
+ subcommand 'mthread' to query a channel about its managing thread.
2001-03-29 Mo DeJong <mdejong@redhat.com>
- * tests/interp.test: Print out warning when
- testinterpdelete command is not defined.
- Add tests that checks to make sure a
- child interp inherits the parent's cwd.
+ * tests/interp.test: Print out warning when testinterpdelete command
+ is not defined. Add tests that checks to make sure a child interp
+ inherits the parent's cwd.
2001-03-29 Jeff Hobbs <jeffh@gimlet.activestate.com>
@@ -3553,35 +3448,34 @@
* unix/tclUnixPipe.c (TclpCreateTempFile): prevent potential race
condition and security leak in tmp filename creation.
- (max) [Patch #402924]
+ [Patch 402924] (max)
* unix/configure:
* unix/tcl.m4: corrected IRIX-5.x config to not use -n32.
- (english) [Patch #403626]
+ [Patch 403626] (english)
- * unix/tclUnixThrd.c (Tcl_ConditionWait): fixed handling of
- timeout for threads (corrects excessive CPU usage issue for Tk on
- Unix in threaded Tcl environment). (ruppert) [Bug #411603]
+ * unix/tclUnixThrd.c (Tcl_ConditionWait): fixed handling of timeout
+ for threads (corrects excessive CPU usage issue for Tk on Unix in
+ threaded Tcl environment). [Bug 411603] (ruppert)
2001-03-29 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* doc/lsort.n: Added some notes that clarify the behaviour of
- [lsort] as well as a whole bunch of examples. [Bug #219202]
+ [lsort] as well as a whole bunch of examples. [Bug 219202]
2001-03-27 Jeff Hobbs <jeffh@gimlet.activestate.com>
- * doc/Alloc.3: corrected docs to note that Tcl_Attempt* return
- char *'s, not ints. [Bug #411388]
+ * doc/Alloc.3: corrected docs to note that Tcl_Attempt* return char
+ *'s, not ints. [Bug 411388]
* tests/regexp.test (regexp-19.1):
- * generic/tclCmdMZ.c (Tcl_RegsubObjCmd): fixed handling of nulls
- in subspec value.
+ * generic/tclCmdMZ.c (Tcl_RegsubObjCmd): fixed handling of nulls in
+ subspec value.
2001-03-26 Don Porter <dgp@users.sourceforge.net>
- * generic/tclDecls.h (Tcl_InitCustomHashTable): Correction to
- patch from 2001-01-18; tclDecls.h was not generated using
- 'make genstubs'.
+ * generic/tclDecls.h (Tcl_InitCustomHashTable): Correction to patch
+ from 2001-01-18; tclDecls.h was not generated using 'make genstubs'.
2001-03-26 Donal K. Fellows <fellowsd@cs.man.ac.uk>
@@ -3590,11 +3484,11 @@
2001-03-23 Jeff Hobbs <jeffh@activestate.com>
- * generic/tclVar.c (Tcl_ArrayObjCmd): Corrected retrieval of
- resultPtr to prevent possible corruption.
+ * generic/tclVar.c (Tcl_ArrayObjCmd): Corrected retrieval of resultPtr
+ to prevent possible corruption.
* generic/tclNamesp.c (Tcl_Import): Correctly freed a DString.
- (lavana) [Patch #403755]
+ [Patch 403755] (lavana)
2001-03-15 Donal K. Fellows <fellowsd@cs.man.ac.uk>
@@ -3603,134 +3497,131 @@
2001-03-14 Don Porter <dgp@users.sourceforge.net>
- * library/package.tcl (pkg_mkIndex): Added patch from Vince
- Darley to make [pkg_mkIndex -verbose] even more verbose.
- [Bug 219349, Patch 403529]
+ * library/package.tcl (pkg_mkIndex): Added patch from Vince Darley to
+ make [pkg_mkIndex -verbose] even more verbose. [Bug 219349, Patch
+ 403529]
2001-03-13 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * doc/info.n: Improved documentation for [info hostname].
- [Bug #403840]
+ * doc/info.n: Improved documentation for [info hostname]. [Bug 403840]
* generic/tclVar.c (Tcl_UnsetObjCmd): Made command behave as
- documented [issue remaining from bug #405769]
+ documented [issue remaining from Bug 405769]
- * generic/tclCmdMZ.c (Tcl_StringObjCmd): A missing
- {return TCL_OK;} was causing memory corruption. [Bug #408002]
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd): A missing {return TCL_OK;}
+ was causing memory corruption. [Bug 408002]
* generic/tclExecute.c (TclDeleteExecEnv, GrowEvaluationStack,
- TclExecuteByteCode): Added some casts to ClientData that are
+ (TclExecuteByteCode): Added some casts to ClientData that are
apparently needed on some architectures.
2001-03-12 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* tests/string.test: Fixed some test numberings and added a test.
- [Patch #403229]
+ [Patch 403229]
2001-03-06 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * generic/tclVar.c (Tcl_UnsetObjCmd): Rewrote argument parser to
- avoid a read off the end of the argument array that could occur
- when executing something like [unset -nocomplain] was executed.
- Improved the error message given when too few arguments are given
- (-nocomplain should obviously be *before* --, not after it) and
- also modified the test suite to take account of that and the
- documentation to use the same improvement. [Bug 405769]
+ * generic/tclVar.c (Tcl_UnsetObjCmd): Rewrote argument parser to avoid
+ a read off the end of the argument array that could occur when
+ executing something like [unset -nocomplain] was executed. Improved
+ the error message given when too few arguments are given (-nocomplain
+ should obviously be *before* --, not after it) and also modified the
+ test suite to take account of that and the documentation to use the
+ same improvement. [Bug 405769]
2001-03-02 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * generic/tclExecute.c (TclExecuteByteCode): Fixed bug that could
- pass pointers to freed memory to command implementations, which
- most obviously caused some weird behaviour with [info level], but
- could have caused problems with user code and command traces too.
- [Bug 404865, Patch 405436]
+ * generic/tclExecute.c (TclExecuteByteCode): Fixed bug that could pass
+ pointers to freed memory to command implementations, which most
+ obviously caused some weird behaviour with [info level], but could
+ have caused problems with user code and command traces too. [Bug
+ 404865, Patch 405436]
2001-02-23 msofer <msofer@users.sourceforge.net>
+
* no changes; fixing up the missing comment in the previous one.
Sorry.
2001-02-23 msofer <msofer@ant.utdt>
- * /cvsroot/tcl/tcl/tests/execute.test:
- added test for evaluation of an expression in a variable; evals once
- by compiling, second time using the previous compilation
+ * /cvsroot/tcl/tcl/tests/execute.test: added test for evaluation of an
+ expression in a variable; evals once by compiling, second time using
+ the previous compilation
2001-02-18 Kevin B. Kenny <kennykb@acm.org>
* doc/clock.n: Updated documentation to reflect the addition of
- compat/strftime.c, including the correct formatting of
- ISO-8601:1988 fiscal week number (%V).
-
+ compat/strftime.c, including the correct formatting of ISO-8601:1988
+ fiscal week number (%V).
+
2001-02-15 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* generic/tclCmdMZ.c (Tcl_SplitObjCmd): Improved efficiency of
- splitting strings into individual characters by adding hash so
- that only one Tcl_Obj per character is created. Improves
- performance of splitting of short strings and makes a huge
- difference to splitting of long strings, such as is done in the
- mime package in tcllib. [Bug #131523]
+ splitting strings into individual characters by adding hash so that
+ only one Tcl_Obj per character is created. Improves performance of
+ splitting of short strings and makes a huge difference to splitting of
+ long strings, such as is done in the mime package in tcllib. [Bug
+ 131523]
2001-01-31 Don Porter <dgp@users.sourceforge.net>
- * win/makefile.vc (install-libraries): Corrected misdirected
- install directory for the msgcat 1.2 package.
+ * win/makefile.vc (install-libraries): Corrected misdirected install
+ directory for the msgcat 1.2 package.
2001-01-30 Don Porter <dgp@users.sourceforge.net>
- * generic/tclIO.c (CopyData): Moved code that updates the count
- of how many bytes are left to copy. Corrects bug that when
- writing occurs in the background, the copy loop could be
- escaped without updating the count, causing CopyData() to try
- to copy more bytes than the toRead value originally passed to
- TclCopyChannel(), leading to hangs and misreporting of number
- of bytes copied. [Bug 118203, Patch 103432]
+ * generic/tclIO.c (CopyData): Moved code that updates the count of how
+ many bytes are left to copy. Corrects bug that when writing occurs in
+ the background, the copy loop could be escaped without updating the
+ count, causing CopyData() to try to copy more bytes than the toRead
+ value originally passed to TclCopyChannel(), leading to hangs and
+ misreporting of number of bytes copied. [Bug 118203, Patch 103432]
2001-01-18 Andreas Kupries <a.kupries@westend.com>
- * Everything below belongs together, it fixes bug #123153.
+ Everything below belongs together, it fixes [Bug 123153]
- * generic/tcl.h (line 342): A bit more explanation about the
- default value for TCL_PRESERVE_BINARY_COMPATABILITY.
+ * generic/tcl.h (line 342): A bit more explanation about the default
+ value for TCL_PRESERVE_BINARY_COMPATABILITY.
- * generic/tcl.h (line 1208): Define the macro 'Tcl_InitHashTable'
- only when TCL_PRESERVE_BINARY_COMPATIBILITY is not set
- as it kills binary compatibility to 8.3 and earlier
- versions. This is the main part of the patch/change.
+ * generic/tcl.h (line 1208): Define the macro 'Tcl_InitHashTable' only
+ when TCL_PRESERVE_BINARY_COMPATIBILITY is not set as it kills binary
+ compatibility to 8.3 and earlier versions. This is the main part of
+ the patch/change.
* generic/tcl.decls (line 1469):
* generic/tclHash.c (Tcl_InitHashTable):
* generic/tclHash.c (Tcl_InitHashTableEx):
* generic/tclObj.c (Tcl_InitObjHashTable): Changed
- 'Tcl_InitHashTableEx' to 'Tcl_InitCustomHashTable'. This change
- is more of an estethical nature, replacing the ubiquitous 'Ex'
- suffix with a more meaningful name. The introduced binary
- incompatibility is deemed acceptable as it is between alpha
- versions. Updated callers.
+ 'Tcl_InitHashTableEx' to 'Tcl_InitCustomHashTable'. This change is
+ more of an estethical nature, replacing the ubiquitous 'Ex' suffix
+ with a more meaningful name. The introduced binary incompatibility is
+ deemed acceptable as it is between alpha versions. Updated callers.
* doc/Hash.3:
* unix/mkLinks: Changed 'Tcl_InitHashTableEx' to
- 'Tcl_InitCustomHashTable'.
+ 'Tcl_InitCustomHashTable'.
2001-01-10 Donal K. Fellows <fellowsd@cs.man.ac.uk>
- * tests/winPipe.test (winpipe-1.20):
- * tests/winDde.test (createChildProcess):
- * tests/pkgMkIndex.test (pkgtest::createIndex): Removed
- assumption that paths contain no spaces which causes problems with
- both [eval] and [open |...] due to the well-known differences
- between lists and strings. Fixes bug #119406
+ * tests/winPipe.test (winpipe-1.20):
+ * tests/winDde.test (createChildProcess):
+ * tests/pkgMkIndex.test (pkgtest::createIndex): Removed assumption
+ that paths contain no spaces which causes problems with both [eval]
+ and [open |...] due to the well-known differences between lists and
+ strings. Fixes [Bug 119406]
2001-01-04 Don Porter <dgp@users.sourceforge.net>
* tests/unixInit.test:
* unix/tclUnixInit.c (TclpInitLibraryPath):
- * win/tclWinInit.c (TclpInitLibraryPath): Several entries in
- the library path ($tcl_libPath) are determined relative to the
- absolute path of the executable. When the executable is
- installed in or near the root directory of the file system,
- relative pathnames were being incorrectly generated, and in
- the worst case, memory access violations were crashing the program.
- [Bug 119416, Patch 102972]
+ * win/tclWinInit.c (TclpInitLibraryPath): Several entries in the
+ library path ($tcl_libPath) are determined relative to the absolute
+ path of the executable. When the executable is installed in or near
+ the root directory of the file system, relative pathnames were being
+ incorrectly generated, and in the worst case, memory access violations
+ were crashing the program. [Bug 119416, Patch 102972]
******************************************************************
*** CHANGELOG ENTRIES FOR 2000 IN "ChangeLog.2000" ***
diff --git a/ChangeLog.2002 b/ChangeLog.2002
new file mode 100644
index 0000000..30b8b17
--- /dev/null
+++ b/ChangeLog.2002
@@ -0,0 +1,4741 @@
+2002-12-18 David Gravereaux <davygrvy@pobox.com>
+
+ * win/makefile.vc: some uses of xcopy swapped to the @$(CPY) macro.
+ Reported by Joe Mistachkin <joe@mistachkin.com>.
+
+2002-12-17 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclNotify.c (TclFinalizeNotifier, Tcl_SetServiceMode):
+ (Tcl_ThreadAlert): Check that the stub functions are non-NULL before
+ calling them. They could be set to NULL by Tcl_SetNotifier.
+
+2002-12-16 David Gravereaux <davygrvy@pobox.com>
+
+ * generic/tclPipe.c (TclCleanupChildren):
+ * tests/winPipe.test:
+ * win/tclWinPipe.c (Tcl_WaitPid):
+ * win/tclWinTest.c: Gave Tcl_WaitPid the ability to return a Win32
+ exception code translated into a posix style SIG*. This allows [close]
+ to report "CHILDKILLED" without the meaning getting lost in a
+ truncated exit code. In TclCleanupChildren(), TclpGetPid() had to get
+ moved to before Tcl_WaitPid() as the the handle is removed from the
+ list taking away the ability to get the process id after the wait is
+ done. This shouldn't effect the unix implimentaion unless waitpid is
+ called with a pid of zero, meaning "any". I don't think it is..
+
+2002-12-13 Don Porter <dgp@users.sourceforge.net>
+
+ * unix/configure.in: Updated configure of CVS snapshots to reflect
+ * win/configure.in: the 8.4.1.1 patchlevel.
+
+ * unix/configure: autoconf
+ * win/configure autoconf
+
+2002-12-11 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclProc.c (ProcessProcResultCode): Fix failure to propagate
+ negative return codes up the call stack. [Bug 647307]
+ * tests/proc.test (proc-6.1): Test for Bug 647307
+
+ * generic/tclParseExpr.c (TclParseInteger): Return 1 for the string
+ "0x" (recognize leading "0" as an integer). [Bug 648441]
+ * tests/parseExpr.test (parseExpr-19.1): Test for Bug 648441.
+
+2002-12-09 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/tclWinThrd.c (TclpMasterUnlock):
+ * generic/tclThread.c (TclFinalizeThreadData): TclpMasterUnlock must
+ exist and be called unconditional of TCL_THREADS. [Bug 651139]
+
+2002-12-08 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinSock.c (SocketThreadExitHandler, InitSockets): Check
+ that the tsdPtr is valid before dereferencing as we call it from the
+ exit handler, too [Bug 650353]. Another WSAStartup() loaded version
+ comparison byte swap issue fixed. Although 0x0101 byte swapped is
+ still 0x0101, properly claiming which is major/minor is more correct.
+
+2002-12-06 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclStubInit.c: regen
+ * generic/tclIntPlatDecls.h: regen
+ * generic/tclInt.decls: added TclWinResetInterface
+
+ * win/tclWin32Dll.c (TclWinResetInterfaces):
+ * win/tclWinInit.c (TclpSetInitialEncodings, WinEncodingsCleanup):
+ add exit handler that resets the encoding information to a state where
+ we can reuse Tcl. Following these changes, it is possible to reuse Tcl
+ (following Tcl_FindExecutable or Tcl_CreateInterp) following a
+ Tcl_Finalize.
+
+ * generic/tclIOUtil.c (TclFinalizeFilesystem): reset statics to their
+ original values on finalize to allow reuse of the library.
+
+2002-12-04 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinPipe.c: reverted back to -r1.27 due to numerous test
+ failures that need to be resolved first. The idea was good, but the
+ details aren't.
+
+2002-12-04 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinPipe.c (Tcl_WaitPid): When a process exits with an
+ exception, pass this notice on to the caller with a SIG* code rather
+ than truncating the exit code and missing the meaning. This allows
+ TclCleanupChildren() to report "CHILDKILLED".
+
+ This has a different behavior than unix in that closing the read pipe
+ to a process sends the SIGPIPE signal which is returned as a SIGPIPE
+ exit status. On windows, we send the process a CTRL_BREAK_EVENT and
+ get back a CONTROL_C_EXIT which is documented to mean a SIGINT which
+ seems wrong as a system, but is the correct exit status.
+
+2002-12-04 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclIOUtil.c: fix to redirected 'load' in virtual filesystem
+ for some Unix systems.
+
+ * generic/tclEvent.c: the filesystem must be cleaned up before the
+ encoding subsystem because it needs access to encodings. Fixes crash
+ on exit observed in embedded applications.
+
+ * generic/tclTestObj.c: patch omitted from previous change of
+ 2002-11-13
+
+2002-12-03 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclStubLib.c (Tcl_InitStubs): prevent the cached check of
+ tclStubsPtr to allow for repeated load/unload of the Tcl dll by
+ hosting apps. [Bug 615304]
+
+2002-12-03 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclAppInit.c (sigHandler): Protect from trying to close a NULL
+ handle.
+
+ * win/tclWinPipe.c (PipeClose2Proc, TclpCreateProcess): Send a real
+ Win32 signal (CTRL_C_EVENT) when the read channel is brought down to
+ alert the child to close on its side. Start the process with
+ CREATE_NEW_PROCESS_GROUP to allow the ability to send these signals.
+ The following test case now brings down the child without the use of
+ an external [kill] command.
+
+ % set p [open "|[info name]" w+]
+ file8d5380
+ % pid $p
+ 2876
+ % close $p <- now doesn't block in Tcl_WaitPid()
+ %
+
+ * win/tclWinPipe.c (PipeClose2Proc): Changed CTRL_C_EVENT to
+ CTRL_BREAK_EVENT as it can't be ignored by the child and proved to
+ work on [open "|netstat 1" w+] where CTRL_C_EVENT didn't.
+
+2002-11-27 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinPort.h: Don't turn off winsock prototypes! TclX didn't
+ like it. Even though the core doesn't use the prototypes, do offer
+ them.
+
+ * win/tclWinSock.c: Removed shutdown() from the function table as it
+ wasn't referenced anywhere and cleaned-up some casting that that
+ wasn't needed.
+
+ * win/tclWinSock.c: WSAStartup() loaded version comparison error which
+ resulted in 2.0 looking less than 1.1.
+
+ * win/tclWinChan.c (Tcl_MakeFileChannel): return of DuplicateHandle()
+ incorrectly used. [Bug 618852]
+
+2002-11-26 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclEncoding.c (TclFinalizeEncodingSubsystem): properly
+ cleanup all encodings by using Tcl_FirstHashEntry in the while loop.
+
+ * unix/Makefile.in (valgrind): add simple valgrind target
+
+ * tests/exec.test: unset path var to allow singleproc testing
+
+ * generic/tclInterp.c (AliasCreate): preserve/release interps to
+ prevent possible FMR error in bad alias cases.
+
+2002-11-26 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinPort.h:
+ * win/tclWinSock.c: This patch does two things:
+
+ 1) Cleans-up the winsock typedefs by using the typedefs provided by
+ winsock2.h. This has no effect on how winsock is initialized; just
+ makes the source code easier to read. [Patch 561305 561301]
+
+ 2) Revamps how the socket message handler thread is brought up and
+ down to allow for cleaner exits without the use of TerminateThread().
+ TerminateThread is evil. No attempt has been made to resolve [Bug
+ 593810] which may need a new channel driver version for adding a
+ registering function within the transfered thread to init the handler
+ thread. IOW, initialization of the TSD structure is getting bypassed
+ through the thread extension's [thread::transfer] command.
+
+2002-11-26 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinConsole.c:
+ * win/tclWinPipe.c:
+ * win/tclWinSerial.c:
+ * win/tclWinSock.c:
+ * win/tclWinThrd.c:
+ * win/tclWinTime.c: General cleanup of all worker threads used by the
+ channel drivers. Eliminates the normal case where the worker thread is
+ terminated ('cept the winsock one). Instead, use kernel events to
+ signal a clean exit. Only when the worker thread is blocked on an I/O
+ call is the thread terminated. Essentially, this makes all other
+ channel worker threads behave like the PipeReaderThread() function for
+ it's cleaner exit behavior. This appears to fix [Bug 597924] but needs
+ 3rd party confirmation to close the issue.
+
+2002-11-26 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/README: Update msys build env URL. This release #4 build both
+ tcl and tk without problems.
+
+2002-11-22 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * library/init.tcl: code cleanup to reduce use of
+ * library/opt/optparse.tcl: string compare
+
+ * tests/interp.test: interp-14.4
+ * generic/tclInterp.c (TclPreventAliasLoop): prevent seg fault when
+ creating an alias command over the interp name. [Bug 641195]
+
+2002-11-18 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclUtil.c (SetEndOffsetFromAny): handle integer offset
+ after the "end-" prefix.
+
+ * generic/get.test:
+ * generic/string.test:
+ * generic/tclObj.c (SetIntFromAny, SetWideIntFromAny):
+ * generic/tclGet.c (TclGetLong, Tcl_GetInt): simplify sign handling
+ before calling strtoul(l). [Bug 634856]
+
+2002-11-18 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinThrd.c (Tcl_CreateThread/TclpThreadExit): Fixed improper
+ compiler macros that missed the VC++ compiler. This resulted in VC++
+ builds using CreateThread()/ExitThread() in place of the proper
+ _beginthreadex()/_endthreadex(). This was a large error and am
+ surprised I missed seeing it earlier.
+
+2002-11-13 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/regexpComp.test: added tests 22.*
+ * generic/tclCompCmds.c (TclCompileRegexpCmd): add left and right
+ anchoring (^ and $) recognition and check starting or ending .* to
+ extend the number of REs that can be compiled to string match or
+ string equal.
+
+2002-11-13 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclCmdMZ.c:
+ * tests/trace.test: applied patch from Hemang Levana to fix [Bug
+ 615043] in execution traces with 'return -code error'.
+
+ * generic/tclTestObj.c:
+ * tests/stringObj.test: added 'knownBug' test for [Bug 635200]
+ * generic/tclStringObj.c: corrected typos in comments
+
+ * generic/tclFileName.c:
+ * tests/fileName.test: applied patch for bug reported against tclvfs
+ concerning handling of Windows serial ports like 'com1', 'lpt3' by the
+ virtual filesystem code.
+
+ * doc/RegExp.3: clarification of the 'extendMatch' return values.
+
+2002-11-11 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclUtil.c (Tcl_Backslash): use TclUtfToUniChar.
+ (Tcl_StringCaseMatch): use TclUtfToUniChar and add further
+ optimizations for the one-byte/char case.
+
+ * generic/tclUtf.c: make use of TclUtfToUniChar macro throughout the
+ functions, and add extra optimization to Tcl_NumUtfChars for
+ one-byte/char case.
+
+ * generic/tclVar.c (DisposeTraceResult, CallVarTraces): add proper
+ static declarations.
+
+ * generic/tclStringObj.c (Tcl_GetCharLength): optimize for the ascii
+ char case.
+ (Tcl_GetUniChar): remove unnecessary use of Tcl_UtfToUniChar.
+ (FillUnicodeRep): Use TclUtfToUniChar.
+
+ * generic/tclHash.c (HashStringKey): move string++ lower to save an
+ instruction.
+
+ * generic/tclExecute.c (TclExecuteByteCode): improve INST_STR_CMP to
+ use memcmp in the one-byte/char case, also use direct index for
+ INST_STR_INDEX in that case.
+
+ * generic/tclEncoding.c (UtfToUtfProc, UtfToUnicodeProc):
+ (TableFromUtfProc, EscapeFromUtfProc): Use TclUtfToUniChar.
+ (UnicodeToUtfProc, TableToUtfProc): add 1-byte char optimizations for
+ Tcl_UniCharToUtf call. These improve encoded channel conversion speeds
+ by up to 20%.
+
+ * tests/split.test: added 1-char string split tests
+ * generic/tclCmdMZ.c (Tcl_SplitObjCmd): Use TclUtfToUniChar. Also
+ added a special case for single-ascii-char splits.
+ (Tcl_StringObjCmd): Use TclUtfToUniChar. For STR_RANGE, support
+ getting ranges of ByteArrays (reverts change from 2000-05-26).
+ (TraceExecutionProc) add proper static declaration.
+
+ * generic/tclInt.h: add macro version of Tcl_UtfToUniChar
+ (TclUtfToUniChar) that does the one-byte utf-char check without
+ calling Tcl_UtfToUniChar, for use by the core. This brings notable
+ speedups for primarily ascii string handling.
+
+ * generic/tcl.h (TCL_PATCH_LEVEL): bump to 8.4.1.1 for patchlevel
+ only. This interim number will only be reflected by [info patchlevel].
+
+2002-11-11 Kevin Kenny <kennykb@acm.org>
+
+ * doc/Tcl.n: Corrected indentation of the new language. Oops.
+
+2002-11-10 Kevin Kenny <kennykb@acm.org>
+
+ * doc/Tcl.n: Added language to the Endekalogue to make it clear that
+ substitutions always take place from left to right. [Bug 635644]
+
+2002-11-06 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * changes: Note TclInExit TclInThreadExit changes.
+ * generic/tclEvent.c (TclInExit, TclInThreadExit): Split out
+ functionality of TclInExit to make it clear which one should be called
+ in each situation.
+ * generic/tclInt.decls: Declare TclInThreadExit.
+ * generic/tclIntDecls.h: Regen.
+ * generic/tclStubInit.c: Regen.
+ * mac/tclMacChan.c (StdIOClose):
+ * unix/tclUnixChan.c (FileCloseProc):
+ * win/tclWinChan.c (FileCloseProc):
+ * win/tclWinConsole.c (ConsoleCloseProc):
+ * win/tclWinPipe.c (TclpCloseFile):
+ * win/tclWinSerial.c (SerialCloseProc): Invoke the new TclInThreadExit
+ method instead of TclInExit.
+
+2002-11-06 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/configure: Regen.
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): Generate a fatal configure error if
+ no ar program can be found on the path. [Bug 582039]
+ * win/configure: Regen.
+ * win/configure.in: Check that AR, RANLIB, and RC are found on the
+ path when building with gcc.
+
+2002-11-03 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclAppInit.c: Calls Registry_Init() and Dde_Init() when
+ STATIC_BUILD and TCL_USE_STATIC_PACKAGES macros are set.
+
+ * win/makefile.vc:
+ * win/rules.vc: linkexten option now sets the TCL_USE_STATIC_PACKAGES
+ macro which also adds the registry and dde object files to the link
+ of the shell. [Patch 479697] Also factored some additional macros that
+ will be helpful for extension authors. Version grepping of tcl.h will
+ need to be added to complete this.
+
+ * win/buildall.vc.bat: Added more descriptive commentary.
+
+2002-11-01 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinReg.c: Changed the Tcl_PkgProvide() line to declare the
+ registry extension at version 1.1 from 1.0.
+
+2002-10-31 Andreas Kupries <andreask@activestate.com>
+
+ * library/word.tcl: Changed $tcl_platform to $::tcl_platform to avoid
+ possible scope trouble.
+
+2002-10-29 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * win/tclWinInt.h:
+ * win/tclWin32Dll.c: added comments about certain NULL function
+ pointers which will be filled in when Tcl_FindExecutable is called, so
+ that users don't report invalid bugs on this topic. (No code changes
+ at all).
+
+2002-10-29 Daniel Steffen <das@users.sourceforge.net>
+
+ * unix/tclLoadDyld.c (TclpFindSymbol): pass all dyld error messages
+ upstream [Bug 627546].
+
+2002-10-28 Andreas Kupries <andreask@activestate.com>
+
+ * library/dde/pkgIndex.tcl:
+ * library/reg/pkgIndex.tcl: Changed the hardwired debug suffix (d) to
+ the correct suffix (g).
+
+2002-10-28 Don Porter <dgp@users.sourceforge.net>
+
+ * library/auto.tcl: Converted the Mac-specific [package unknown]
+ * library/init.tcl: behavior to use a chaining mechanism to extend
+ * library/package.tcl: the default [tclPkgUnknown]. [Bug 627660]
+ * library/tclIndex: [Patch 624509] (steffen)
+
+2002-10-26 David Gravereaux <davygrvy@pobox.com>
+
+ * win/makefile.vc: xcopy on NT 4.0 doesn't support the /Y switch
+ (overwrite). Added logic to handle this. [Bug 618019]
+
+2002-10-23 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclInt.h: Removed definitions of obsolete HistoryEvent and
+ HistoryRev structures (the history mechanism has been written in Tcl
+ for some time now.)
+
+2002-10-22 Jeff Hobbs <jeffh@ActiveState.com>
+
+ *** 8.4.1 TAGGED FOR RELEASE ***
+
+ * changes: updated for 8.4.1 release
+
+ * win/Makefile.in: removed @MEM_DEBUG_FLAGS@ subst.
+ * win/configure: regen
+ * win/configure.in: removed SC_ENABLE_MEMDEBUG call
+ * win/tcl.m4: replaced SC_ENABLE_MEMDEBUG with a more intelligent
+ SC_ENABLE_SYMBOLS that takes yes|no|mem|compile|all as options now.
+
+2002-10-22 Daniel Steffen <das@users.sourceforge.net>
+
+ * library/auto.tcl (tcl_findLibrary):
+ * library/package.tcl (tclPkgUnknown): on macosx, search inside the
+ Resources/Scripts subdirectory of any potential package directory.
+ * macosx/Tcl.pbproj/project.pbxproj: add standard Frameworks dirs to
+ TCL_PACKAGE_PATH make argument.
+ * unix/tclUnixInit.c (TclpSetVariables): on macosx, add embedded
+ framework dirs to tcl_pkgPath: @executable_path/../Frameworks and
+ @executable_path/../PrivateFrameworks (if they exist), as well as the
+ dirs in DYLD_FRAMEWORK_PATH (if set). [Patch 624509]
+ use standard MAXPATHLEN instead of literal 1024
+
+2002-10-22 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/StringObj.3, doc/Object.3: Documented that Tcl_Obj's standard
+ string form is a modified UTF-8; apparently, this was not mentioned
+ anywhere in the main docs, and lead to [Bug 624919].
+
+2002-10-21 Daniel Steffen <das@users.sourceforge.net>
+
+ * macosx/Tcl.pbproj/project.pbxproj: bumped version to 8.4.1
+ * generic/tcl.h: Added reminder comment to edit
+ macosx/Tcl.pbproj/project.pbxproj when version number changes.
+
+2002-10-18 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * library/reg/pkgIndex.tcl:
+ * win/configure:
+ * win/configure.in:
+ * win/Makefile.in:
+ * win/makefile.vc:
+ * win/makefile.bc: Updated to reg1.1
+
+ * doc/registry.n: Added support for broadcasting changes to the
+ * tests/registry.test: registry Environment. Noted proper code in the
+ * win/tclWinReg.c: docs. [Patch 625453]
+
+ * unix/Makefile.in (dist): add any mac/tcl*.sea.hqx files
+
+2002-10-17 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclVar.c: Fixed code that check for proper # of args to
+ * tests/var.test: [array names]. Added test. [Bug 624755]
+
+2002-10-16 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/configure: add workaround for cygwin windres
+ * win/tcl.m4 (SC_CONFIG_CFLAGS): problem. [Patch 624010] (howell)
+
+2002-10-15 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * README: added archives.tcl.tk note
+
+ * unix/configure:
+ * unix/tcl.m4: Correct AIX-5 ppc build flags. Correct HP 11 64-bit gcc
+ building. [Patch 601051] (martin)
+
+2002-10-15 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclCmdMZ.c:
+ * tests/trace.test: applied patch from Hemang Levana to fix [Bug
+ 615043] in execution traces with idle tasks firing.
+
+2002-10-14 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclEnv.c (Tcl_PutEnv): correct possible mem leak. [Patch
+ 623269] (brouwers)
+
+2002-10-11 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tcl.h: Need a different strategy through the maze of
+ #defines to let people building with Cygwin build correctly. Also made
+ some comments less misleading...
+
+2002-10-10 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * README: fixed minor nits [Bug 607776] (virden)
+
+ * win/configure:
+ * win/tcl.m4: enable USE_THREAD_ALLOC (new threaded allocator) by
+ default in cygwin configure on Windows.
+
+2002-10-10 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/Tcl.n: Clarified that namespace separators are legal in the
+ variable names during $-subtitution. [Bug 615139]
+
+ * doc/regexp.n: Typo correction. Thanks Ronnie Brunner. [Bug 606826]
+
+2002-10-10 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * unix/tclLoadAout.c
+ * unix/tclLoadDl.c
+ * unix/tclLoadDld.c
+ * unix/tclLoadDyld.c
+ * unix/tclLoadNext.c
+ * unix/tclLoadOSF.c
+ * unix/tclLoadShl.c
+ * win/tclWinLoad.c: allow either full paths or simply dll names to be
+ specified when loading files (the latter will be looked up by the OS
+ on your PATH/LD_LIBRARY_PATH as appropriate). Fixes [Bug 611108]
+
+2002-10-09 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/README: doc'ed --enable-symbols options.
+ * unix/Makefile.in: removed @MEM_DEBUG_FLAGS@ subst.
+ * unix/configure: regen
+ * unix/configure.in: removed SC_ENABLE_MEMDEBUG call
+ * unix/tcl.m4: replaced SC_ENABLE_MEMDEBUG with a more intelligent
+ SC_ENABLE_SYMBOLS that takes yes|no|mem|compile|all as options now.
+
+2002-10-09 Kevin B. Kenny <kennykb@acm.org>
+
+ * win/tclWinTime.c: Added code to set an exit handler that terminates
+ the thread that calibrates the performance counter, so that the thread
+ won't outlive unloading the Tcl DLL. [Bug 620735]
+
+2002-10-09 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/binary.n: More clarification of [binary scan]'s behaviour.
+
+2002-10-09 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tclIntDecls.h: fixed botched regen.
+
+2002-10-09 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tclInt.decls: made TclSetPreInitScript() declaration
+ generic as it is used on mac & aqua as well.
+ * generic/tclIntDecls.h:
+ * generic/tclStubInit.c: regen.
+ * generic/tclCompile.h: added prototype for TclCompileVariableCmd.
+
+ * mac/tclMacPort.h: removed incorrect <fcntl.h> definitions and
+ obsolete <stat.h> definitions.
+ * mac/tclMacChan.c: removed obsolete GetOpenMode() and replaced
+ associated constants with the <fcntl.h> analogues (they existing defs
+ were inconsistent with <fcntl.h> which was causing havoc when
+ Tcl_GetOpenMode was used instead of private GetOpenMode).
+
+ * mac/tclMacFCmd.c: removed GenerateUniqueName(), use equivalent (and
+ identically named) routine from MoreFiles instead.
+
+ * mac/tclMacLoad.c: CONSTification, fixes to Vince's last changes.
+
+ * mac/tclMacFile.c:
+ * mac/tclMacTest.c:
+ * mac/tclMacUnix.c: CONSTification.
+
+ * mac/tclMacOSA.c: CONSTification, sprintf fixes, UH 3.4.x changes;
+ fix for missing autoname token from TclOSACompileCmd. (bdesgraupes)
+ * mac/AppleScript.html(AppleScript delete): doc fix. (bdesgraupes)
+
+ * mac/tcltkMacBuildSupport.sea.hqx: updated MoreFiles to 1.5.3,
+ updated build instructions for 8.4.
+ * mac/tclMacProjects.sea.hqx: rebuilt archive.
+
+2002-10-09 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/Alloc.3: Added a note to mention that attempting to allocate a
+ zero-length block can return NULL. [Tk Bug 619544]
+
+2002-10-04 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/binary.n: Doc improvements [Patch 616480]
+
+ * tests/fCmd.test, tests/winFCmd.test:
+ * tools/eolFix.tcl, tools/genStubs.tcl: [file exist] -> [file exists]
+ Thanks to David Welton.
+
+2002-10-03 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/tcltest.n: fixed typo [Bug 618018]. Thanks to "JJM".
+
+2002-10-03 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * tools/man2help2.tcl:
+ * tests/http.test, tests/httpd, tests/httpold.test:
+ * tests/env.test, tests/binary.test, tests/autoMkindex.test:
+ * library/init.tcl, library/http/http.tcl: [info exist] should really
+ be [info exists]. [Bug 602566]
+
+ * doc/lsearch.n: Better specification of what happens when -sorted is
+ mixed with other options. [Bug 617816]
+
+2002-10-01 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclProc.c (TclCreateProc): mask out VAR_UNDEFINED for
+ precompiled locals to support 8.3 precompiled code.
+ (Tcl_ProcObjCmd): correct 2002-09-26 fix to look for tclProcBodyType.
+
+2002-10-01 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/socket.n: Mentioned that ports may be specified as serivce names
+ as well as integers. [Bug 616843]
+
+2002-09-30 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclCompCmds.c (TclCompileRegexpCmd): correct the checking
+ for bad re's that didn't terminate the re string. Resultant compiles
+ were correct, but much slower than necessary.
+
+2002-09-29 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclAppInit.c: Added proper exiting conditions using Win32
+ console signals. This handles the existing lack of a Ctrl+C exit to
+ call exit handlers when built for thread support. Also, properly
+ handles exits from other conditions such as CTRL_CLOSE_EVENT,
+ CTRL_LOGOFF_EVENT, and CTRL_SHUTDOWN_EVENT signals. In all cases,
+ exit handlers will be called. [Bug 219355]
+
+ * win/makefile.vc: Added missing tclThreadAlloc.c to the build rules
+ and defines USE_THREAD_ALLOC when TCL_THREADS is defined to get the
+ new behavior by default.
+
+2002-09-27 Don Porter <dgp@users.sourceforge.net>
+
+ * README: Bumped to version 8.4.1 to avoid confusion of
+ * generic/tcl.h: CVS snapshots with the actual 8.4.0 release.
+ * tools/tcl.wse.in:
+ * unix/configure.in:
+ * unix/tcl.spec:
+ * win/configure.in:
+
+ * unix/configure: autoconf
+ * win/configure:
+
+2002-09-26 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/configure: regen.
+ * unix/tcl.m4: improve AIX-4/5 64bit compilation support.
+
+ * generic/tclProc.c (Tcl_ProcObjCmd): correct overeager optimization
+ of noop proc to handle the precompiled case. (sofer)
+
+ * unix/ldAix (nmopts): add -X32_64 to make it work for 32 or 64bit
+ mode compilation.
+
+ * library/encoding/koi8-u.enc: removed extraneous spaces that confused
+ encoding reader. [Bug 615115]
+
+ * unix/Makefile.in: generate source dists with -src designator and do
+ not generate .Z anymore (just .gz and .zip).
+
+2002-09-18 Mumit Khan <khan@nanotech.wisc.edu>
+
+ Added basic Cygwin support.
+
+ * win/tcl.m4 (SC_PATH_TCLCONFIG): Support one-tree build.
+ (SC_PATH_TKCONFIG): Likewise.
+ (SC_PROG_TCLSH): Likewise.
+ (SC_CONFIG_CFLAGS): Assume real Cygwin port and remove -mno-cygwin
+ flags. Add -mwin32 to extra_cflags and extra_ldflags. Remove ``-e
+ _WinMain@16'' from LDFLAGS_WINDOW.
+ * win/configure.in: Allow Cygwin build.
+ (SEH test): Define to be 1 instead of empty value.
+ (EXCEPTION_DISPOSITION): Add test.
+ * win/configure: Regenerate.
+
+ * generic/tcl.h: Don't explicitly define __WIN32__ for Cygwin, let the
+ user decide whether to use Windows or POSIX personality.
+ (TCL_WIDE_INT_TYPE, TCL_LL_MODIFIER, struct Tcl_StatBuf): Define for
+ Cygwin.
+ * generic/tclEnv.c (Tcl_CygwinPutenv): putenv replacement for Cygwin.
+ * generic/tclFileName.c (Tcl_TranslateFileName): Convert POSIX to
+ native format.
+ (TclDoGlob): Likewise.
+ * generic/tclPlatDecls.h (TCHAR): Define for Cygwin.
+ * win/tclWinPort.h (putenv, TclpSysAlloc, TclpSysFree,
+ (TclpSysRealloc): Define for Cygwin.
+
+2002-09-26 Daniel Steffen <das@users.sourceforge.net>
+
+ * macosx/Makefile: preserve environment value of INSTALL_ROOT. When
+ embedding only use deployment build. Force relink before embedded
+ build to ensure new linker flags are picked up.
+
+ * macosx/Tcl.pbproj/project.pbxproj: add symbolic links to debug lib,
+ stub libs and tclConfig.sh in framework toplevel. Configure target
+ dependency fix. Fix to 'clean' action. Added private tcl headers to
+ framework. Install tclsh symbolic link. Html doc build works when no
+ installed tclsh available. Made html doc structure in framework more
+ like in Apple frameworks.
+
+2002-09-24 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * unix/tcl.m4 (SC_TCL_64BIT_FLAGS): Yet more robust 64-bit value
+ detection to close [Bug 613117] on more systems.
+
+ * generic/tclCompile.c (TclPrintSource): More CONSTifying.
+ * generic/tclExecute.c (EvalStatsCmd): Object-ify to reduce warnings.
+ Thanks to 'CoderX2' on the chat for bringing this to my attention...
+
+ * unix/tcl.m4: Forgot to define TCL_WIDE_INT_IS_LONG at the
+ appropriate moment. I believe this is the cause of [Bug 613117]
+
+ * doc/lset.n: Changed 'list' to 'varName' for consistency with lappend
+ documentation. Thanks to Glenn Jackman [Bug 611719]
+
+2002-09-22 Don Porter <dgp@users.sourceforge.net>
+
+ * library/tcltest/tcltest.tcl: Corrected [puts -nonewline] within
+ test bodies. Thanks to Harald Kirsch. [Bug 612786, Patch 612788] Also
+ corrected reporting of body return code. Thanks to David Taback [Bug
+ 611922]
+ * library/tcltest/pkgIndex.tcl: Bump to version 2.2.1.
+ * tests/tcltest.test: added tests for these bugs.
+
+2002-09-15 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/configure: Regen.
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): Add PEEK_XCLOSEIM define under
+ Linux. This is used by Tk to double check that an X input context is
+ cleaned up before it is closed.
+
+2002-09-12 David Gravereaux <davygrvy@pobox.com>
+
+ * win/coffbase.txt: Added BLT to the virtual base address listings
+ table should BLT's build tools decide to use it.
+
+2002-09-12 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tcl.h:
+ * mac/tclMacApplication.r:
+ * mac/tclMacLibrary.r:
+ * mac/tclMacResource.r: unified use of the two equivalent resource
+ compiler header inclusion defines RC_INVOKED and RESOURCE_INCLUDED,
+ now use RC_INVOKED throughout.
+
+2002-09-10 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/README: Add note about building extensions with the same
+ compiler Tcl was built with. [Tk Bug 592096]
+
+2002-09-10 Daniel Steffen <das@users.sourceforge.net>
+
+ * macosx/Tcl.pbproj/project.pbxproj: disabled building html
+ documentation during embedded build.
+
+2002-09-10 Daniel Steffen <das@users.sourceforge.net>
+
+ * unix/Makefile.in: added DYLIB_INSTALL_DIR variable for macosx and
+ set it to default value ${LIB_RUNTIME_DIR}
+ * unix/tcl.m4 (Darwin): use DYLIB_INSTALL_DIR instead of
+ LIB_RUNTIME_DIR in the -install_name argument to ld.
+ * unix/configure: regen.
+
+ * macosx/Tcl.pbproj/project.pbxproj:
+ * macosx/Makefile: added support for building Tcl as an embedded
+ framework, i.e. using an dyld install_name containing
+ @executable_path/../Frameworks via the new DYLIB_INSTALL_DIR
+ unix/Makefile variable.
+
+2002-09-10 Jeff Hobbs <jeffh@ActiveState.com>
+
+ *** 8.4.0 TAGGED FOR RELEASE ***
+
+2002-09-06 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/file.n: Format correction, and clarified [file normalize]
+ returns an absolute path.
+
+ * doc/tcltest.n: Added examples section, as long promised.
+
+2002-09-06 Reinhard Max <max@suse.de>
+
+ * tests/tcltest.test: Added nonRoot flag to tests 8.3, 8.4, and 8.12.
+
+2002-09-05 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/tcltest.n: Clarified phrasing.
+
+ * generic/tclBasic.c (TclRenameCommand,CallCommandTraces):
+ * tests/trace.test (trace-27.1): Corrected memory leak when a rename
+ trace deleted the command being traced. Test added. Thanks to Hemang
+ Lavana for the fix. [Bug 604609]
+
+ * generic/tclVar.c (TclDeleteVars): Corrected logic for setting the
+ TCL_INTERP_DESTROYED flag when calling variable traces. [Tk Bug 605121]
+
+2002-09-04 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclVar.c (DeleteArray): leak plug [Bug 604239]. Thanks to
+ dkf and dgp for the long and difficult discussion in the chat.
+
+2002-09-03 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclVar.c (Tcl_UpVar2): code cleanup to not use goto
+
+ * unix/configure: remove -pthread from LIBS on FreeBSD in thread
+ * unix/tcl.m4: enabled build. [Bug 602849]
+
+2002-09-03 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclInterp.c (AliasCreate): a Tcl_Obj was leaked on error
+ return from TclPreventAliasLoop.
+
+2002-09-03 Daniel Steffen <das@users.sourceforge.net>
+
+ * macosx/Tcl.pbproj/project.pbxproj: Bumped version number to 8.4.0
+ and updated copyright info.
+
+2002-09-03 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclVar.c (Tcl_UpVar2): a Tcl_Obj was being leaked on error
+ return from TclGetFrame.
+
+2002-09-03 Don Porter <dgp@users.sourceforge.net>
+
+ * changes: Updated changes for 8.4.0 release.
+
+2002-09-02 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/tclUnixFile.c (TclpObjLink): removed unnecessary/unfreed extra
+ native char*.
+
+ * unix/tclUnixChan.c (Tcl_MakeTcpClientChannel): make sure to init
+ flags field of TcpState ptr to 0.
+
+ * unix/configure:
+ * unix/tcl.m4: added 64-bit gcc compilation support on HP-11.
+ [Patch 601051] (martin)
+
+ * README: Bumped version number to 8.4.0
+ * generic/tcl.h:
+ * tools/tcl.wse.in:
+ * unix/configure:
+ * unix/configure.in:
+ * unix/tcl.spec:
+ * win/README.binary:
+ * win/configure:
+ * win/configure.in:
+
+ * generic/tclInterp.c (SlaveCreate): make sure that the memory and
+ checkmem commands are initialized in non-safe slave interpreters when
+ TCL_MEM_DEBUG is used. [Bug 583445]
+
+ * win/tclWinConsole.c (ConsoleCloseProc): only wait on writable pipe
+ if there was something to write. This may prevent infinite wait on
+ exit.
+
+ * tests/exec.test: marked exec-18.1 unixOnly until the Windows
+ incompatability (in the test, not the core) can be resolved.
+
+ * tests/http.test (http-3.11): added close $fp that was causing an
+ error on Windows because the file was not closed before deleting.
+
+ * unix/tclUnixInit.c (Tcl_MacOSXGetLibraryPath): made this static
+ function only appear when HAVE_CFBUNDLE is defined.
+
+2002-08-31 Daniel Steffen <das@users.sourceforge.net>
+
+ * unix/tcl.m4: added TK_SHLIB_LD_EXTRAS analogue of existing
+ TCL_SHLIB_LD_EXTRAS for linker settings only used when linking Tk.
+
+ * unix/configure: regen
+
+2002-08-31 Daniel Steffen <das@users.sourceforge.net>
+
+ *** macosx-8-4-branch merged into the mainline [Patch 602770] ***
+
+ * generic/tcl.decls: added new macosx specific entry to stubs table.
+
+ * tools/genStubs.tcl: added generation of platform guards for
+ macosx. This is a little more complex than it seems, because MacOS X
+ IS "unix" plus a little bit, for the purposes of Tcl. BUT
+ unfortunately, Tk uses "unix" to mean X11. So added platform keys for
+ macosx (the little added to "unix"), "aqua" and "x11" to distinguish
+ these for Tk.
+
+ * generic/tcl.h: added a #ifnded RESOURCE_INCLUDED so that tcl.h can
+ be passed to the resource compiler.
+
+ * generic/tcl.h:
+ * generic/tclNotify.c: added a few Notifier procs, to be able to
+ modify more bits of the Tcl notifier dynamically. Required to get Mac
+ OS X Tk to live on top of the Tcl Unix threaded notifier. Changes the
+ size of the Tcl_NotifierProcs structure, but doesn't move any elements
+ around.
+
+ * unix/tclUnixNotfy.c: moved the call to Tcl_ConditionNotify till
+ AFTER we are done mucking with the pointer swap. Fixes cases where the
+ thread waiting on the condition wakes & accesses the waitingListPtr
+ before it gets reset, causing a hang.
+
+ * library/auto.tcl (tcl_findLibrary): added checking the directories
+ in the tcl_pkgPath for library files on macosx to enable support of
+ the standard Mac OSX library locations.
+
+ * unix/Makefile.in:
+ * unix/configure.in:
+ * unix/tcl.m4: added MAC_OSX_DIR. Added PLAT_OBJS to the OBJS: there
+ are some MacOS X specific files now for Tcl, and when I get the
+ resource & applescript stuff ported over, and restore support for
+ FindFiles, etc, there will be a few more. Added LD_LIBRARY_PATH_VAR
+ configure variable to avoid having to set all possible LD_LIBRARY_PATH
+ analogues on all platforms. LD_LIBRARY_PATH_VAR is "LD_LIBRARY_PATH"
+ by default, "LIBPATH" on AIX, "SHLIB_PATH" on HPUX and
+ "DYLD_LIBRARY_PATH" on Mac OSX. Added configure option to package Tcl
+ as a framework on Mac OSX.
+
+ * macosx/tclMacOSXBundle.c (new): support for finding Tcl extension
+ packaged as 'bundles' in the standard Mac OSX library locations.
+
+ * unix/tclUnixInit.c: added support for findig the tcl script library
+ inside Tcl packaged as a framework on Mac OSX.
+
+ * macosx/Tcl.pbproj/jingham.pbxuser (new):
+ * macosx/Tcl.pbproj/project.pbxproj (new): project for Apple's
+ ProjectBuilder IDE.
+
+ * macosx/Makefile (new): simple makefile for building the project from
+ the command line via the ProjectBuilder tool 'pbxbuild'.
+
+ * unix/configure:
+ * generic/tclStubInit.c:
+ * generic/tclPlatDecls.h: regen
+
+2002-08-29 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * win/tclWinThrd.c (TclpFinalizeThreadData, TclWinFreeAllocCache):
+ Applied patch for [Bug 599428], provided by Miguel Sofer
+ <msofer@users.sourceforge.net>.
+
+2002-08-28 David Gravereaux <davygrvy@pobox.com>
+
+ * generic/tclEnv.c:
+ * unix/configure.in:
+ * win/tclWinPort.h: putenv() on some systems copies the buffer rather
+ than taking reference to it. This causes memory leaks and is know to
+ effect mswindows (msvcrt) and NetBSD 1.5.2 . This patch tests for this
+ behavior and turns on -DHAVE_PUTENV_THAT_COPIES=1 when approriate.
+ Thanks to David Welton for assistance. [Bug 414910]
+
+ * unix/configure: regen'd
+
+2002-08-28 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/eval.n: Added mention of list command and corrected "SEE ALSO".
+
+ * unix/configure.in: Cache handling of ac_cv_type_socklen_t was wrong.
+ [Bug 600931] reported by John Ellson. Fixed by putting the brackets
+ where they belong.
+
+2002-08-26 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclCompCmds.c: fix for [Bug 599788] (error in element name
+ causing segfault), reported by Tom Wilkason. Fixed by copying the
+ tokens instead of the source string.
+
+2002-08-26 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclThreadAlloc.c: small optimisation, reducing the new
+ allocator's overhead.
+
+2002-08-23 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclObj.c (USE_THREAD_ALLOC): fixed leak [Bug 597936]. Thanks
+ to Zoran Vasiljevic.
+
+2002-08-23 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclThreadAlloc.c (USE_THREAD_ALLOC): moving objects between
+ caches as a block, instead of one-by-one.
+
+2002-08-22 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclBasic.c:
+ * generic/tclCmdMZ.c: fix for freed memory r/w in delete traces [Bug
+ 589863], patch by Hemang Lavana.
+
+2002-08-20 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * win/Makefile.in (CFLAGS):
+ * unix/Makefile.in (MEM_DEBUG_FLAGS): Added usage of @MEM_DEBUG_FLAGS@.
+ * win/configure.in:
+ * unix/configure.in: Added usage of SC_ENABLE_MEMDEBUG.
+ * win/tcl.m4:
+ * unix/tcl.m4: Added macro SC_ENABLE_MEMDEBUG. Allows a user of
+ configure to (de)activate memory validation and debugging
+ (TCL_MEM_DEBUG). No need to modify the makefile anymore.
+
+2002-08-20 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCkalloc.c: CONSTified MemoryCmd and CheckmemCmd.
+
+ * README: Bumped version number to 8.4b3 to distinguish
+ * generic/tcl.h: HEAD from the 8.4b2 release.
+ * tools/tcl.wse.in:
+ * unix/configure.in:
+ * unix/tcl.spec:
+ * win/README.binary:
+ * win/configure.in:
+
+ * unix/configure: autoconf
+ * win/configure:
+
+ * library/http/http.tcl: Corrected installation directory of
+ * library/msgcat/msgcat.tcl: the package tcltest 2.2. Added
+ * library/opt/optparse.tcl: comments in other packages to remind
+ * library/tcltest/tcltest.tcl: that installation directories need
+ * unix/Makefile.in: updates to match increasing version
+ * win/Makefile.in: numbers. [Bug 597450]
+ * win/makefile.bc:
+ * win/makefile.vc:
+
+2002-08-19 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * unix/tclUnixTest.c (TestfilehandlerCmd): Changed readable/writable
+ to the more common readable|writable. Fixes [Bug 596034] reported by
+ Larry Virden <lvirden@users.sourceforge.net>.
+
+2002-08-16 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * tests/fCmd.test: Added test to make sure that the cause of the
+ problem is detectable with an unpatched Tcl.
+ * doc/ObjectType.3: Added note on the root cause of this problem to
+ the documentation, since it is possible for user code to trigger this
+ sort of behaviour too.
+ * generic/tclIOUtil.c (SetFsPathFromAny): Objects should only have
+ their old representation deleted when we know that we are about to
+ install a new one. This stops a weird TclX bug under Linux with
+ certain kinds of memory debugging enabled which essentally came down
+ to a double-free of a string.
+
+2002-08-14 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclInt.h:
+ * generic/tclObj.c: (code cleanup) factored the parts in the macros
+ TclNewObj() / TclDecrRefCount() into a common part for all
+ memory allocators and two new macros TclAllocObjStorage() /
+ TclFreeObjStorage() that are specific to each allocator and fully
+ describe the differences. Removed allocator-specific code from
+ tclObj.c by using the macros.
+
+2002-08-12 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclCmdMZ.c: fixing UMR in delete traces, [Bug 589863].
+
+2002-08-08 David Gravereaux <davygrvy@pobox.com>
+
+ * tools/man2help.tcl: Fixed $argv handling bug where if -bitmap wasn't
+ specified $argc was off by one.
+
+2002-08-08 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * tests/uplevel.test: added 6.1 to test [uplevel] with shadowed
+ commands [Bug 524383]
+
+ * tests/subst.test: added 5.8-10 as further tests for [Bug 495207]
+
+2002-08-08 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/README: Noted removal of defs.tcl.
+
+2002-08-08 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * doc/lsearch.n: corrected lsearch docs to use -inline in examples.
+
+ *** 8.4b2 TAGGED FOR RELEASE ***
+
+ * tests/fCmd.test:
+ * tests/unixFCmd.test: updated tests for new link copy behavior.
+ * generic/tclFCmd.c (CopyRenameOneFile): changed the behavior to
+ follow links to endpoints and copy that file/directory instead of just
+ copying the surface link. This means that trying to copy a link that
+ has no endpoint (danling link) is an error. [Patch 591647] (darley)
+ (CopyRenameOneFile): this is currently disabled by default until
+ further issues with such behavior (like relative links) can be
+ handled correctly.
+
+ * tests/README: slight wording improvements
+
+2002-08-07 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * docs/BoolObj.3: added description of valid string reps for a
+ boolean object. [Bug 584794]
+ * generic/tclObj.c: optimised Tcl_GetBooleanFromObj and
+ SetBooleanFromAny to avoid parsing the string rep when it can be
+ avoided. [Bugs 584650, 472576]
+
+2002-08-07 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclCompile.h:
+ * generic/tclObj.c: making tclCmdNameType static ([Bug 584567], Don
+ Porter).
+
+2002-08-07 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclObj.c (Tcl_NewObj): added conditional code for
+ USE_THREAD_ALLOC; objects allocated through Tcl_NewObj() were
+ otherwise being leaked. [Bug 587488] reported by Sven Sass.
+
+2002-08-06 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tclInt.decls:
+ * unix/tclUnixThrd.c: Added stubs and implementations for
+ non-threaded build for the tclUnixThrd.c procs TclpReaddir,
+ TclpLocaltime, TclpGmtime and TclpInetNtoa. Fixes link errors in
+ stubbed & threaded extensions that include tclUnixPort.h and use any
+ of the procs readdir, localtime, gmtime or inet_ntoa (e.g. TclX 8.4)
+ [Bug 589526]
+ * generic/tclIntPlatDecls.h:
+ * generic/tclStubInit.c: Regen.
+
+2002-08-05 Don Porter <dgp@users.sourceforge.net>
+
+ * library/tcltest/tcltest.tcl: The setup and cleanup scripts are now
+ * library/tcltest/pkgIndex.tcl: skipped when a test is skipped, fixing
+ * tests/tcltest.test: [Bug 589859]. Test for bug added, and
+ corrected tcltest package bumped to version 2.2.
+
+ * generic/tcl.decls: Restored Tcl_Concat to return (char *). Like
+ * generic/tclDecls.h: Tcl_Merge, it transfers ownership of a dynamic
+ * generic/tclUtil.c: allocated string to the caller.
+
+2002-08-04 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/CmdCmplt.3: Applied Patch 585105 to fully CONST-ify all
+ * doc/Concat.3: remaining public interfaces of Tcl. Notably,
+ * doc/CrtCommand.3: the parser no longer writes on the string it
+ * doc/CrtSlave.3: is parsing, so it is no longer necessary for
+ * doc/CrtTrace.3: Tcl_Eval() to be given a writable string. Also
+ * doc/Eval.3: the refactoring of the Tcl_*Var* routines by
+ * doc/ExprLong.3: by Miguel Sofer is included, so that the
+ * doc/LinkVar.3: "part1" argument for them no longer needs to
+ * doc/ParseCmd.3: be writable either.
+ * doc/SetVar.3:
+ * doc/TraceVar.3:
+ * doc/UpVar.3: Compatibility support has been enhanced so
+ * generic/tcl.decls: that a #define of USE_NON_CONST will remove
+ * generic/tcl.h: all possible source incompatibilities with the
+ * generic/tclBasic.c: 8.3 version of the header file(s). The new
+ * generic/tclCmdMZ.c: #define of USE_COMPAT_CONST now does what
+ * generic/tclCompCmds.c:USE_NON_CONST used to do -- disable only those
+ * generic/tclCompExpr.c:new CONST's that introduce irreconcilable
+ * generic/tclCompile.c: incompatibilities.
+ * generic/tclCompile.h:
+ * generic/tclDecls.h: Several bugs are also fixed by this patch.
+ * generic/tclEnv.c: [Bugs 584051,580433] [Patches 585105,582429]
+ * generic/tclEvent.c:
+ * generic/tclInt.decls:
+ * generic/tclInt.h:
+ * generic/tclIntDecls.h:
+ * generic/tclInterp.c:
+ * generic/tclLink.c:
+ * generic/tclObj.c:
+ * generic/tclParse.c:
+ * generic/tclParseExpr.c:
+ * generic/tclProc.c:
+ * generic/tclTest.c:
+ * generic/tclUtf.c:
+ * generic/tclUtil.c:
+ * generic/tclVar.c:
+ * mac/tclMacTest.c:
+ * tests/expr-old.test:
+ * tests/parseExpr.test:
+ * unix/tclUnixTest.c:
+ * unix/tclXtTest.c:
+ * win/tclWinTest.c:
+
+2002-08-01 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclExecute.c: bugfix (reading freed memory). Testsuite
+ passed on linux/i386, compile-13.1 hung on linux/alpha.
+
+2002-08-01 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclExecute.c: added a reference count for the complete
+ execution stack, instead of Tcl_Preserve/Tcl_Release.
+
+2002-08-01 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * generic/tclCkalloc.c (TclFinalizeMemorySubsystem): Don't lock the
+ ckalloc mutex before invoking the Tcl_DumpActiveMemory function since
+ it also locks the same mutex. This code is only executed when "memory
+ onexit filename" has been executed and Tcl is compiled with
+ -DTCL_MEM_DEBUG.
+
+2002-08-01 Reinhard Max <max@suse.de>
+
+ * win/tclWinPort.h: The windows headers don't provide socklen_t, so we
+ have to do it.
+
+2002-07-31 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclInt.h (USE_THREAD_ALLOC): for unshared objects,
+ TclDecrRefCount now frees the internal rep before the string rep -
+ just like the non-macro Tcl_DecrRefCount/TclFreeObj [Bug 524802]. For
+ the other allocators the fix was done on 2002-03-06.
+
+2002-07-31 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclInterp.c: signed/unsigned comparison warning fixed
+ (Vince Darley).
+
+2002-07-31 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * unix/tcl.m4 (SC_BUGGY_STRTOD): Enabled caching of test results.
+
+ * unix/tcl.m4 (SC_BUGGY_STRTOD): Solaris 2.8 still has a buggy
+ strtod() implementation; make sure we detect it.
+
+ * tests/expr.test (expr-22.*): Marked as non-portable because it seems
+ that these tests have an annoying tendency to fail in unexpected ways.
+ [Bugs 584825, 584950, 585986]
+
+2002-07-30 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * tests/io.test:
+ * generic/tclIO.c (WriteChars): Added flag to break out of loop if
+ nothing of the input is consumed at all, to prevent infinite looping
+ of called with a non-UTF-8 string. Fixes Bug 584603 (partially). Added
+ new test "io-60.1". Might need additional changes to Tcl_Main so that
+ unprintable results are printed as binary data.
+
+2002-07-29 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/Makefile.in: Use CC_SEARCH_FLAGS instead of LD_SEARCH_FLAGS
+ when linking with ${CC}.
+ * unix/configure: Regen.
+ * unix/configure.in: Don't subst CC_SEARCH_FLAGS or LD_SEARCH_FLAGS
+ since this is now done in tcl.m4.
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): Document and set CC_SEARCH_FLAGS
+ whenever LD_SEARCH_FLAGS is set. [Patch 588290]
+
+2002-07-29 Reinhard Max <max@suse.de>
+
+ * unix/tcl.m4 (SC_SERIAL_PORT): Fixed detection for cases when
+ configure's stdin is not a tty.
+
+ * unix/tclUnixPort.h:
+ * generic/tclIOSock.c: Changed size_t to socklen_t in
+ socket-related function calls.
+
+ * unix/configure.in: Added test and fallback definition
+ for socklen_t.
+
+ * unix/configure: generated.
+
+2002-07-29 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclObj.c: fixed a comment
+
+ * generic/tcl.h:
+ * generic/tclBasic.c:
+ * generic/tclInterp.c: added the new flag TCL_EVAL_INVOKE to the
+ interface of the Tcl_Eval* functions, removing the
+ TCL_EVAL_NO_TRACEBACK added yesterday: alias invocations not only
+ require no tracebacks, but also look up the command name in the global
+ scope - see new test interp-9.4
+ * tests/interp.test: added 9.3 to test for safety of aliases to hidden
+ commands, 9.4 to test for correct command lookup scope.
+
+2002-07-29 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/regc_locale.c (cclass): [[:xdigit:]] is only a defined
+ concept on western characters, so should not allow any unicode digit,
+ and hence number of ranges in [[:xdigit:]] is fixed.
+ * tests/reg.test: Added test to detect the bug.
+ * generic/regc_cvec.c (newcvec): Corrected initial size value in
+ character vector structure. [Bug 578363] Many thanks to
+ pvgoran@users.sf.net for tracking this down.
+
+2002-07-28 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tcl.h:
+ * generic/tclBasic.c: added the new flag TCL_EVAL_NO_TRACEBACK to the
+ interface of the Tcl_Eval* functions. Modified the error message for
+ too many nested evaluations.
+ * generic/tclInterp.h: changed the Alias struct to be of variable
+ length and store the prefix arguments directly (instead of a pointer
+ to a Tcl_Obj list). Made AliasObjCmd call Tcl_EvalObjv instead of
+ TclObjInvoke - thus making aliases trigger execution traces [Bug
+ 582522].
+ * tests/interp.test:
+ * tests/stack.test: adapted to the new error message.
+ * tests/trace.test: added tests for aliases firing the exec traces.
+
+2002-07-27 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/Makefile.in: Revert fix for Tcl bug 529801 since it was
+ incorrect and broke the build on other systems. Fix [Bug 587299]. Add
+ MAJOR_VERSION, MINOR_VERSION, PATCH_LEVEL, SHLIB_LD_FLAGS,
+ SHLIB_LD_LIBS, CC_SEARCH_FLAGS, LD_SEARCH_FLAGS, and LIB_FILE
+ variables to support more generic library build/install rules.
+ * unix/configure: Regen.
+ * unix/configure.in: Move AC_PROG_RANLIB into tcl.m4. Move shared
+ build test and setting of MAKE_LIB and MAKE_STUB_LIB into tcl.m4. Move
+ subst of a number of variables into tcl.m4 where they are defined.
+ * unix/tcl.m4 (SC_ENABLE_SYMBOLS, SC_CONFIG_CFLAGS): Subst vars where
+ they are defined. Add MAKE_LIB, MAKE_STUB_LIB, INSTALL_LIB, and
+ INSTALL_STUB_LIB rules to deal with the ugly details of running ranlib
+ on static libs at build and install time. Replace TCL_SHLIB_LD_EXTRAS
+ with SHLIB_LD_FLAGS and use it when building a shared library.
+ * unix/tclConfig.sh.in: Add TCL_CC_SEARCH_FLAGS.
+
+2002-07-26 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclExecute.c: fixed Tcl_Obj leak in code corresponding to
+ the macro NEXT_INST_V(x, 0, 1) [Bug 587495].
+
+2002-07-26 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclVar.c (TclObjLookupVar): leak fix and improved comments.
+
+2002-07-26 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclVar.c (TclLookupVar): removed early returns that
+ prevented the parens from being restored. Also removed goto label as
+ it was not necessary.
+
+2002-07-24 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclExecute.c:
+ * tests/expr-old.test: fix for erroneous error messages in [expr],
+ [Bug 587140] reported by Martin Lemburg.
+
+2002-07-25 Joe English <jenglish@users.sourceforge.net>
+
+ * generic/tclProc.c: fix for [Tk Bug 219218] "error handling with
+ bgerror in Tk"
+
+2002-07-24 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclExecute.c: restoring full TCL_COMPILE_DEBUG
+ functionality.
+
+2002-07-24 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/unixInit.test: relaxed unixInit-3.1 to accept iso8859-15 as a
+ valid C encoding. [Bug 575336]
+
+2002-07-24 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclExecute.c: restoring the tcl_traceCompile functionality
+ while I repair tcl_traceExec. The core now compiles and runs also
+ under TCL_COMPILE_DEBUG, but execution in the bytecode engine can
+ still not be traced.
+
+2002-07-24 Daniel Steffen <das@users.sourceforge.net>
+
+ * unix/Makefile.in:
+ * unix/configure.in: corrected fix for [Bug 529801]: ranlib only
+ needed for static builds on Mac OS X.
+ * unix/configure: Regen.
+ * unix/tclLoadDyld.c: fixed small bugs introduced by Vince,
+ implemented library unloading correctly (needs OS X 10.2).
+
+2002-07-23 Joe English <jenglish@users.sourceforge.net>
+
+ * doc/OpenFileChnl.3: (Updates from Larry Virden)
+ * doc/open.n:
+ * doc/tclsh.1: Fix section numbers in Unix man page references.
+ * doc/lset.n: In EXAMPLES section, include command to set the initial
+ value used in subsequent examples.
+ * doc/http.n: Package version updated to 2.4.
+
+2002-07-23 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/configure: Regen.
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): Enable 64 bit compilation when using
+ the native compiler on a 64 bit version of IRIX. [Bug 219220]
+
+2002-07-23 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/Makefile.in: Combine ranlib tests and avoid printing unless
+ ranlib is actually run.
+
+2002-07-23 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/tcl.m4 (SC_PATH_X): Set XINCLUDES to "" instead of "# no
+ special path needed" or "# no include files found" when x headers
+ cannot be located.
+
+2002-07-22 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclIOUtil.c: made tclNativeFilesystem static (since 07-19
+ changes removed its usage elsewhere), and added comments about its
+ usage.
+ * generic/tclLoad.c:
+ * generic/tcl.h:
+ * generic/tcl.decls:
+ * doc/FileSystem.3: converted last load-related ClientData parameter
+ to Tcl_LoadHandle opaque structure, removing a couple of casts in the
+ process.
+
+ * generic/tclInt.h: removed tclNativeFilesystem declaration since it
+ is now static again.
+
+2002-07-22 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * tests/expr.test (expr-22.*): Added tests to help detect the
+ corrected handling.
+ * generic/tclExecute.c (IllegalExprOperandType): Improved error
+ message generated when attempting to manipulate Inf and NaN values.
+ * generic/tclParseExpr.c (GetLexeme): Allowed parser to recognise
+ 'Inf' as a floating-point number. [Bug 218000]
+
+2002-07-21 Don Porter <dgp@users.sourceforge.net>
+
+ * tclIOUtil.c: Silence compiler warning. [Bug 584408].
+
+2002-07-19 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclIOUtil.c: fix to GetFilesystemRecord
+ * win/tclWinFile.c:
+ * unix/tclUnixFile.c: fix to subtle problem with links shown up by
+ latest tclkit builds.
+
+2002-07-19 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/configure:
+ * unix/configure.in:
+ * win/configure:
+ * win/configure.in: Add AC_PREREQ(2.13) in an attempt to make it more
+ clear that the configure scripts must be generated with autoconf
+ version 2.13. [Bug 583573]
+
+2002-07-19 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * unix/Makefile.in: fix to build on MacOS X [Bug 529801], bug report
+ and fix from jcw.
+
+2002-07-19 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * win/tclWinSerial.c (no_timeout): Made this variable static.
+
+ * generic/tclExecute.c, generic/tclCompile.c, generic/tclBasic.c:
+ * generic/tclCompile.h (builtinFuncTable, instructionTable): Added
+ prefix to these symbols because they are visible outside the Tcl
+ library.
+
+ * generic/tclCompExpr.c (operatorTable):
+ * unix/tclUnixTime.c (tmKey):
+ * generic/tclIOUtil.c (theFilesystemEpoch, filesystemWantToModify,
+ filesystemIteratorsInProgress, filesystemOkToModify): Made these
+ variables static.
+
+ * unix/tclUnixFile.c: Renamed nativeFilesystem to
+ * win/tclWinFile.c: tclNativeFilesystem and declared
+ * generic/tclIOUtil.c: it properly in tclInt.h
+ * generic/tclInt.h:
+
+ * generic/tclUtf.c (totalBytes): Made this array static and const.
+
+ * generic/tclParse.c (typeTable): Made this array static and const.
+ (Tcl_ParseBraces): Simplified error handling case so that scans are
+ only performed when needed, and flags are simpler too.
+
+ * license.terms: Added AS to list of copyright holders; it's only
+ fair for the current gatekeepers to be listed here!
+
+ * tests/cmdMZ.test: Renamed constraint for clarity. [Bug 583427]
+ Added tests for the [time] command, which was previously only
+ indirectly tested!
+
+2002-07-18 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclInt.h:
+ * generic/tcl.h:
+ * */*Load*.c: added comments on changes of 07/17 and replaced
+ clientData with Tcl_LoadHandle in all locations.
+
+ * generic/tclFCmd.c:
+ * tests/fileSystem.test: fixed a 'knownBug' with 'file attributes ""'
+ * tests/winFCmd.test:
+ * tests/winPipe.test:
+ * tests/fCmd.test:
+ * tessts/winFile.test: added 'pcOnly' constraint to some tests to make
+ for more useful 'tests skipped' log from running all tests on
+ non-Windows platforms.
+
+2002-07-17 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclBasic.c (CallCommandTraces): delete traces now receive
+ the FQ old name of the command. [Bug 582532] (Don Porter)
+
+2002-07-18 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * tests/ioUtil.test: added constraints to 1.4,2.4 so they don't run
+ outside of tcltest. [Bugs 583276, 583277]
+
+2002-07-17 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclVar.c (DupParsedVarName): nasty bug fixed, reported by
+ Vince Darley.
+
+2002-07-17 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclVar.c (TclPtrIncrVar): missing CONST in declarations,
+ inconsistent with tclInt.h. Thanks to Vince Darley for reporting, boo
+ to gcc for not complaining.
+
+2002-07-17 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclInt.h:
+ * generic/tclIOUtil.c:
+ * generic/tclLoadNone.c:
+ * unix/tclLoadAout.c:
+ * unix/tclLoadDl.c:
+ * unix/tclLoadDld.c:
+ * unix/tclLoadDyld.c:
+ * unix/tclLoadNext.c:
+ * unix/tclLoadOSF.c:
+ * unix/tclLoadShl.c:
+ * mac/tclMacLoad.c:
+ * win/tclWinLoad.c: modified to move more functionality to the generic
+ code and avoid duplication. Partial replacement of internal uses of
+ clientData with opaque Tcl_LoadHandle. A little further work still
+ needed, but significant changes are done.
+
+2002-07-17 D. Richard Hipp <drh@hwaci.com>
+
+ * library/msgcat/msgcat.tcl: fix a comment that was causing problems
+ for programs (ex: mktclapp) that embed the initialization scripts in
+ strings.
+
+2002-07-17 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclInt.decls:
+ * generic/tclIntDecls.h:
+ * generic/tclStubInit.c:
+ * generic/tclVar.c: removing the now redundant functions to access
+ indexed variables: Tcl(Get|Set|Incr)IndexedScalar() and
+ Tcl(Get|Set|Incr)ElementOfIndexedArray().
+
+2002-07-17 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclExecute.c (TclExecuteByteCode): Minor fixes to make this
+ file compile with SunPro CC...
+
+2002-07-17 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclExecute.c: modified to do variable lookup explicitly, and
+ then either inlining the variable access or else calling the new
+ TclPtr(Set|Get|Incr)Var functions in tclVar.c
+ * generic/tclInt.h: declare some functions previously local to
+ tclVar.c for usage by TEBC.
+ * generic/tclVar.c: removed local declarations; moved all special
+ accessor functions for indexed variables to the end of the file -
+ they are unused and ready for removal, but left there for the time
+ being as they are in the internal stubs table.
+
+ ** WARNING FOR BYTECODE MAINTAINERS **
+ TCL_COMPILE_DEBUG is currently not functional; will be fixed ASAP.
+
+2002-07-16 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/Makefile.in:
+ * win/Makefile.in: Add a more descriptive warning in the event `make
+ genstubs` needs to be rerun.
+
+2002-07-16 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/Makefile.in: Use dltest.marker file to keep track of when the
+ dltest package is up to date. This fixes [Bug 575768] since tcltest is
+ no longer linked every time.
+ * unix/dltest/Makefile.in: Create ../dltest.marker after a successful
+ `make all` run in dltest.
+
+2002-07-16 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/configure: Regen.
+ * unix/configure.in: Remove useless subst of TCL_BIN_DIR.
+
+2002-07-15 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclVar.c: inaccurate comment fixed
+
+2002-07-15 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclBasic.c (Tcl_AddObjErrorInfo):
+ * generic/tclExecute.c (TclUpdateReturnInfo):
+ * generic/tclInt.h:
+ * generic/tclProc.c:
+ Added two Tcl_Obj to the ExecEnv structure to hold the fully qualified
+ names "::errorInfo" and "::errorCode" to cache the addresses of the
+ corresponding variables. The two most frequent setters of these
+ variables now profit from the new variable name caching.
+
+2002-07-15 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclVar.c: refactorisation to reuse already looked-up Var
+ pointers; definition of three new Tcl_Obj types to cache variable name
+ parsing and lookup for later reuse; modification of internal functions
+ to profit from the caching.
+
+ * generic/tclInt.decls:
+ * generic/tclInt.h:
+ * generic/tclIntDecls.h:
+ * generic/tclNamesp.c: adding CONST qualifiers to variable names
+ passed to Tcl_FindNamespaceVar and to variable resolvers; adding CONST
+ qualifier to the 'msg' argument to TclLookupVar. Needed to avoid code
+ duplication in the new tclVar.c code.
+
+ * tests/set-old.test:
+ * tests/var.test: slight modification of error messages due to the
+ modifications in the tclVar.c code.
+
+2002-07-15 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/unixInit.test: Improved constraints to protect /tmp. [Bug
+ 581403]
+
+2002-07-15 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * tests/winFCmd.test: renamed 'win2000' and 'notWin2000' to more
+ appropriate constraint names.
+ * win/tclWinFile.c: updated comments to reflect 07-11 changes.
+ * win/tclWinFCmd.c: made ConvertFileNameFormat static again, since no
+ longer used in tclWinFile.c
+ * mac/tclMacFile.c: completed TclpObjLink implementation which was
+ previously lacking.
+ * generic/tclIOUtil.c: comment cleanup and code speedup.
+
+2002-07-14 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclInt.h: Removed declarations that duplicated entries
+ in the (internal) stub table.
+
+ * library/tcltest/tcltest.tcl: Corrected errors in handling of
+ configuration options -constraints and -limitconstraints.
+
+ * README: Bumped HEAD to version 8.4b2 so we can
+ * generic/tcl.h: distinguish it from the 8.4b1 release.
+ * tools/tcl.wse.in:
+ * unix/configure*:
+ * unix/tcl.spec:
+ * win/README.binary:
+ * win/configure*:
+
+2002-07-11 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * doc/file.n:
+ * win/tclWinFile.c: on Win 95/98/ME the long form of the path is used
+ as a normalized form. This is required because short forms are not a
+ robust representation. The file normalization function has been sped
+ up, but more performance gains might be possible, if speed is still an
+ issue on these platforms.
+
+2002-07-11 Don Porter <dgp@users.sourceforge.net>
+
+ * library/tcltest/tcltest.tcl: Corrected reaction to existing but
+ false ::tcl_interactive.
+
+ * doc/Hash.3: Overlooked CONST documentation update.
+
+2002-07-11 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclCkalloc.c: ckalloc() and friends take the block size as
+ an unsigned, so we should use %ud when reporting it in fprintf() and
+ panic().
+
+2002-07-11 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclCompile.c: now setting local vars undefined at compile
+ time, instead of waiting until the proc is initialized.
+ * generic/tclProc.c: use macro TclSetVarUndefined instead of directly
+ setting the flag.
+
+2002-07-11 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * tests/cmdAH.test: [file attr -perm] is Unix-only, so add [catch]
+ when not inside a suitably-protected test.
+
+2002-07-10 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * tests/unixFCmd.test, tests/fileName.test:
+ * tests/fCmd.test: Removed [exec] of Unix utilities that have
+ equivalents in standard Tcl. [Bug 579268] Also simplified some of
+ unixFCmd.test while I was at it.
+
+2002-07-10 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/tcltest.test: Greatly reduced the number of [exec]s, using
+ slave interps instead.
+ * library/tcltest/tcltest.tcl: Fixed bug uncovered in the conversion
+ where a message was written to stdout instead of [outputChannel].
+
+ * tests/basic.test: Cleaned up, constrained, and reduced the
+ * tests/compile.test: amount of [exec] usage in the test suite.
+ * tests/encoding.test:
+ * tests/env.test:
+ * tests/event.test:
+ * tests/exec.test:
+ * tests/io.test:
+ * tests/ioCmd.test:
+ * tests/regexp.test:
+ * tests/regexpComp.test:
+ * tests/socket.test:
+ * tests/tcltest.test:
+ * tests/unixInit.test:
+ * tests/winDde.test:
+ * tests/winPipe.test:
+
+2002-07-10 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * tests/cmdAH.test: Removed [exec] of Unix utilities. [Bug 579211]
+
+ * tests/expr.test: Added tests to make sure that this works.
+ * generic/tclExecute.c (ExprCallMathFunc): Functions should also be
+ able to return wide-ints. [Bug 579284]
+
+2002-07-08 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * tests/socket.test: Fixed [Bug 578164]. The original reason for the
+ was a DNS outage while running the testsuite. Changed [info hostname]
+ to 127.0.0.1 to bypass DNS, knowing that we operate on the local host.
+
+2002-07-08 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/tcltest.n: Fixed incompatibility in [viewFile].
+ * library/tcltest/tcltest.tcl: Corrected docs. Bumped to 2.2.1.
+ * library/tcltest/pkgIndex.tcl: [Bug 578163]
+
+2002-07-08 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * tests/cmdAH.test:
+ * tests/fCmd.test:
+ * tests/fileName.test: tests which rely on 'file link' need a
+ constraint so they don't run on older Windows OS. [Bug 578158]
+ * generic/tclIOUtil.c:
+ * generic/tcl.h:
+ * generic/tclInt.h:
+ * generic/tclTest.c:
+ * mac/tclMacChan.c:
+ * unix/tclUnixChan.c:
+ * win/tclWinChan.c:
+ * doc/FileSystem.3: cleaned up internal handling of
+ Tcl_FSOpenFileChannel to remove duplicate code, and make writing
+ external vfs's clearer and easier. No functionality change. Also
+ clarify that objects with refCount zero should not be passed in to the
+ Tcl_FS API, and prevent segfaults from occuring on such user errors.
+ [Bug 578617]
+
+2002-07-06 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/pkgMkIndex.test: Constrained tests of [load] package indexing
+ to those platforms where the testing shared libraries have been built.
+ [Bug 578166]
+
+2002-07-05 Don Porter <dgp@users.sourceforge.net>
+
+ * changes: added recent changes
+
+2002-07-05 Reinhard Max <max@suse.de>
+
+ * generic/tclClock.c (FormatClock): Convert the format string to UTF8
+ before calling TclpStrftime, so that non-ASCII characters don't get
+ mangled when the result string is being converted back.
+ * tests/clock.test: Added a test for that.
+
+2002-07-05 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * unix/Makefile.in (ro-test,ddd,GDB,DDD): Created new targets to
+ allow running the test suite with a read-only current directory,
+ running under ddd instead of gdb, and factored out some executable
+ names for broken sites (like mine) where gdb and ddd are installed
+ with non-standard names...
+
+ * tests/httpold.test: Altered test names to httpold-* to avoid clashes
+ with http.test, and stopped tests from failing when the current
+ directory is not writable...
+
+ * tests/event.test: Stop these tests from failing when the
+ * tests/ioUtil.test: current directory is not writable...
+ * tests/regexp.test:
+ * tests/regexpComp.test:
+ * tests/source.test:
+ * tests/unixFile.test:
+ * tests/unixNotfy.test:
+
+ * tests/unixFCmd.test: Trying to make these test-files not
+ * tests/macFCmd.test: bomb out with an error when the
+ * tests/http.test: current directory is not writable...
+ * tests/fileName.test:
+ * tests/env.test:
+
+2002-07-05 Jeff Hobbs <jeffh@ActiveState.com>
+
+ *** 8.4b1 TAGGED FOR RELEASE ***
+
+2002-07-04 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * tests/cmdMZ.test (cmdMZ-1.4):
+ * tests/cmdAH.test: More fixing of writable-current-dir assumption.
+ [Bug 575824]
+
+2002-07-04 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * tests/basic.test: Same issue as below; fixed [Bug 575817]
+
+2002-07-04 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * tests/socket.test:
+ * tests/winPipe.test:
+ * tests/pid.test: Fixed [Bug 575848]. See below for a description the
+ general problem.
+
+ * All the bugs below are instances of the same problem: The testsuite
+ assumes [pwd] = [temporaryDirectory] and writable.
+
+ * tests/iogt.test: Fixed [Bug 575860].
+ * tests/io.test: Fixed [Bug 575862].
+ * tests/exec.test:
+ * tests/ioCmd.test: Fixed [Bug 575836].
+
+2002-07-03 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/pkg1/direct1.tcl: removed
+ * tests/pkg1/pkgIndex.tcl: removed
+ * tests/pkgMkIndex.test: Imported auxilliary files from tests/pkg1
+ into the test file pkgMkIndex.test itself. Formatting fixes.
+
+ * unix/Makefile.in: removed tests/pkg/* from `make dist`
+
+ * tests/pkg/circ1.tcl: removed
+ * tests/pkg/circ2.tcl: removed
+ * tests/pkg/circ3.tcl: removed
+ * tests/pkg/global.tcl: removed
+ * tests/pkg/import.tcl: removed
+ * tests/pkg/pkg1.tcl: removed
+ * tests/pkg/pkg2_a.tcl: removed
+ * tests/pkg/pkg2_b.tcl: removed
+ * tests/pkg/pkg3.tcl: removed
+ * tests/pkg/pkg4.tcl: removed
+ * tests/pkg/pkg5.tcl: removed
+ * tests/pkg/pkga.tcl: removed
+ * tests/pkg/samename.tcl: removed
+ * tests/pkg/simple.tcl: removed
+ * tests/pkg/spacename.tcl: removed
+ * tests/pkg/std.tcl: removed
+ * tests/pkgMkIndex.test: Fixed [Bug 575857] where this test file
+ expected to be able to write to [file join [testsDirectory] pkg]. Part
+ of the fix was to import several auxilliary files into the test file
+ itself.
+
+ * tests/main.test: Cheap fix for [Bugs 575851, 575858]. Avoid
+ * tests/tcltest.test: non-writable . by [cd [temporaryDirectory]].
+
+ * library/auto.tcl: Fix [tcl_findLibrary] to be sure it sets $varName
+ only if a successful library script is found. [Bug 577033]
+
+2002-07-03 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclCompCmds.c (TclCompileCatchCmd): return
+ TCL_OUT_LINE_COMPILE instead of TCL_ERROR: let the failure happen at
+ runtime so that it can be caught [Bug 577015].
+
+2002-07-02 Joe English <jenglish@users.sourceforge.net>
+
+ * doc/tcltest.n: Markup fixes, spellcheck.
+
+2002-07-02 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/tcltest.n: more refinements of the documentation.
+
+ * library/tcltest/tcltest.tcl: Added trace to be sure the stdio
+ constraint is updated whenever the [interpreter] changes.
+
+ * doc/tcltest.n: Reverted [makeFile] and [viewFile] to
+ * library/tcltest/tcltest.tcl: their former behavior, and documented
+ * tests/cmdAH.test: it. Corrected misspelling of hook
+ * tests/event.test: procedure. Restored tests.
+ * tests/http.test:
+ * tests/io.test:
+
+ * library/tcltest/tcltest.tcl: Simplified logic of [GetMatchingFiles]
+ and [GetMatchingDirectories], removing special case processing.
+
+ * doc/tcltest.n: More documentation updates. Reference sections are
+ complete. Only examples need adding.
+
+2002-07-02 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * tests/fCmd.test:
+ * generic/tclCmdAH.c: clearer error msgs for 'file link', as per the
+ man page.
+
+2002-07-01 Joe English <jenglish@users.sourceforge.net>
+
+ * doc/Access.3:
+ * doc/AddErrInfo.3:
+ * doc/Alloc.3:
+ * doc/Backslash.3:
+ * doc/CrtChannel.3:
+ * doc/CrtSlave.3:
+ * doc/Encoding.3:
+ * doc/Eval.3:
+ * doc/FileSystem.3:
+ * doc/Notifier.3:
+ * doc/OpenFileChnl.3:
+ * doc/ParseCmd.3:
+ * doc/RegExp.3:
+ * doc/Tcl_Main.3:
+ * doc/Thread.3:
+ * doc/TraceCmd.3:
+ * doc/Utf.3:
+ * doc/WrongNumArgs.3:
+ * doc/binary.n:
+ * doc/clock.n:
+ * doc/expr.n:
+ * doc/fconfigure.n:
+ * doc/glob.n:
+ * doc/http.n:
+ * doc/interp.n:
+ * doc/lsearch.n:
+ * doc/lset.n:
+ * doc/msgcat.n:
+ * doc/packagens.n:
+ * doc/pkgMkIndex.n:
+ * doc/registry.n:
+ * doc/resource.n:
+ * doc/safe.n:
+ * doc/scan.n:
+ * doc/tclvars.n: Spell-check, fixed typos (Updates from Larry Virden).
+
+2002-07-01 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): Made Solaris use gcc for linking
+ when building with gcc to resolve problems with undefined symbols
+ being present when tcl library used with non-gcc linker at later
+ stage. Symbols were compiler-generated, so it is the compiler's
+ business to define them. [Bug 541181]
+
+2002-07-01 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/tcltest.n: more work in progress updating tcltest docs.
+
+ * library/tcltest/tcltest.tcl: Change [configure -match] to stop
+ treating an empty list as a list of the single pattern "*". Changed
+ the default value to [list *] so default operation remains the same.
+
+ * tests/pkg/samename.tcl: restored. needed by pkgMkIndex.test.
+
+ * library/tcltest/tcltest.tcl: restored writeability testing of
+ -tmpdir, augmented by a special exception for the deafault value.
+
+2002-07-01 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/concat.n: Documented the *real* behaviour of [concat]!
+
+2002-06-30 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/tcltest.n: more work in progress updating tcltest docs.
+
+ * tests/README: Updated the instructions on running and
+ * tests/cmdMZ.test: adding to the test suite. Also updated
+ * tests/encoding.test: several tests, mostly to correctly create
+ * tests/fCmd.test: and destroy any temporary files in the
+ * tests/info.test: [temporaryDirectory] of tcltest.
+ * tests/interp.test:
+
+ * library/tcltest/tcltest.tcl: Stopped checking for writeability of
+ -tmpdir value because no default directory can be guaranteed to be
+ writeable.
+
+ * tests/autoMkindex.tcl: removed.
+ * tests/pkg/samename.tcl: removed.
+ * tests/pkg/magicchar.tcl: removed.
+ * tests/pkg/magicchar2.tcl: removed.
+ * tests/autoMkindex.test: Updated auto_mkIndex tests to use [makeFile]
+ and [removeFile] so tests are done in [temporaryDirecotry] where write
+ access is guaranteed.
+
+ * library/tcltest/tcltest.tcl: Fixed [makeFile] and [viewFile] to
+ * tests/cmdAH.test: accurately reflect a file's contents.
+ * tests/event.test: Updated tests that depended on buggy
+ * tests/http.test: behavior. Also added warning messages
+ * tests/io.test: to "-debug 1" operations to debug test
+ * tests/iogt.test: calls to (make|remove)(File|Directory)
+
+ * unix/mkLinks: `make mklinks` on 6-27 commits.
+
+2002-06-28 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclCompile.h: modified the macro TclEmitPush to not call its
+ first argument repeatedly or pass it to other macros, [Bug 575194]
+ reported by Peter Spjuth.
+
+2002-06-28 Don Porter <dgp@users.sourceforge.net>
+
+ * docs/tcltest.n: Doc revisions in progress.
+ * library/tcltest/tcltest.tcl: Corrected -testdir default value. Was
+ not reliable, and disagreed with docs! Thanks to Hemang Lavana. [Bug
+ 575150]
+
+2002-06-28 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * unix/tclUnixThrd.c: Renamed the Tcl_Platform* #defines to TclOS*
+ * unix/tclUnixPipe.c: because they are only used internally. Also
+ * unix/tclUnixFile.c: stopped double-#def of TclOSlstat [Bug 566099,
+ * unix/tclUnixFCmd.c: post-rename]
+ * unix/tclUnixChan.c:
+ * unix/tclUnixPort.h:
+
+ * doc/string.n: Improved documentation for [string last] along lines
+ described in [Bug 574799] so it indicates that the supplied index
+ marks the end of the search space.
+
+2002-06-27 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/dde.n: Work in progress updating the documentation
+ * doc/http.n: of the packages that come bundled with
+ * doc/msgcat.n: the Tcl source distribution, notably tcltest.
+ * doc/registry.n:
+ * doc/tcltest.n:
+
+ * library/tcltest/tcltest.tcl: Made sure that the TCLTEST_OPTIONS
+ environment variablle configures tcltest at package load time.
+
+2002-06-26 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * tests/fileSystem.test:
+ * generic/tclIOUtil.c: fix to handling of empty paths "" which are not
+ claimed by any filesystem [Bug 573758]. Ensure good error messages
+ are given in all cases.
+ * tests/cmdAH.test:
+ * unix/tclUnixFCmd.c: fix to bug reported as part of [Patch 566669].
+ Thanks to Taguchi, Takeshi for the report.
+
+2002-06-26 Reinhard Max <max@suse.de>
+
+ * unix/tclUnixTime.c: Make [clock format] respect locale settings.
+ * tests/clock.test: [Bug 565880]. ***POTENTIAL INCOMPATIBILITY***
+
+2002-06-26 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * doc/CrtInterp.3:
+ * doc/StringObj.3: clarifications by Don Porter, [Bug 493995] and [Bug
+ 500930].
+
+2002-06-24 Don Porter <dgp@users.sourceforge.net>
+
+ * library/tcltest/tcltest.tcl: Corrected suppression of -verbose skip
+ * tests/tcltest.test: and start by [test -output]. Also
+ corrected test suite errors exposed by corrected code. [Bug 564656]
+
+2002-06-25 Reinhard Max <max@suse.de>
+
+ * unix/tcl.m4: New macro SC_CONFIG_MANPAGES.
+ * unix/configure.in: Added support for symlinks and compression when
+ * unix/Makefile.in: installing the manpages. [Patch 518052]
+ * unix/mkLinks.tcl: Default is still hardlinks and no compression.
+
+ * unix/mkLinks: generated
+ * unix/configure:
+
+ * unix/README: Added documentation for the new features.
+
+ * unix/tcl.m4 (SC_PATH_TCLCONFIG): Replaced ${exec_prefix}/lib by
+ ${libdir}.
+
+2002-06-25 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclUtil.c (TclGetIntForIndex): Fix of critical [Bug 533364]
+ generated when the index is bad and the result is a shared object. The
+ T_ASTO(T_GOR, ...) idiom likely exists elsewhere though. Also removed
+ some cruft that just complicated things to no advantage.
+ (SetEndOffsetFromAny): Same fix, though this wasn't on the path
+ excited by the bug.
+
+2002-06-24 Don Porter <dgp@users.sourceforge.net>
+
+ * library/tcltest/tcltest.tcl: Implementation of TIP 101. Adds abd
+ * tests/parseOld.test: exports a [configure] command from
+ * tests/tcltest.test: tcltest.
+
+2002-06-22 Don Porter <dgp@users.sourceforge.net>
+
+ * changes: updated changes file for 8.4b1 release.
+
+ * library/tcltest/tcltest.tcl: Corrections to tcltest and the Tcl
+ * tests/basic.test: test suite so that a test with options
+ * tests/cmdInfo.test: -constraints knownBug
+ * tests/compile.test: -limitConstraints 1 only tests the
+ * tests/encoding.test: knownBug tests. Mostly involves
+ * tests/env.test: replacing direct access to the
+ * tests/event.test: testConstraints array with calls to
+ * tests/exec.test: the testConstraint command (which
+ * tests/execute.test: requires tcltest version 2)
+ * tests/fCmd.test:
+ * tests/format.test:
+ * tests/http.test:
+ * tests/httpold.test:
+ * tests/ioUtil.test:
+ * tests/link.test:
+ * tests/load.test:
+ * tests/namespace.test:
+ * tests/pkgMkIndex.test:
+ * tests/reg.test:
+ * tests/result.test:
+ * tests/scan.test:
+ * tests/stack.test:
+
+2002-06-22 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * tools/tcl.wse.in (Disk Label), unix/tcl.spec (version):
+ * win/README.binary, README, win/configure.in, unix/configure.in:
+ * generic/tcl.h (TCL_RELEASE_*, TCL_PATCH_LEVEL): Bump to beta1.
+
+2002-06-21 Joe English <jenglish@users.sourceforge.net>
+
+ * generic/tclCompExpr.c:
+ * generic/tclParseExpr.c: LogSyntaxError() should reset the
+ interpreter result [Bug 550142 "Tcl_ExprObj -> abort"]
+
+2002-06-21 Don Porter <dgp@users.sourceforge.net>
+
+ * unix/Makefile.in: Updated all package install directories
+ * win/Makefile.in: to match current Major.minor versions
+ * win/makefile.bc: of the packages. Added tcltest package
+ * win/makefile.vc: to installation on Windows.
+
+ * library/init.tcl: Corrected comments and namespace style issues.
+ Thanks to Bruce Stephens. [Bug 572025]
+
+2002-06-21 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * tests/cmdAH.test: Added TIP#99 implementation of 'file
+ * tests/fCmd.test: link'. Supports creation of symbolic and
+ * tests/fileName.test: hard links in the native filesystems and
+ * tests/fileSystem.test: in vfs's, when the individual filesystem
+ * generic/tclTest.c: supports the concept.
+ * generic/tclCmdAH.c:
+ * generic/tclIOUtil.c:
+ * generic/tcl.h:
+ * generic/tcl.decls:
+ * doc/FileSystem.3:
+ * doc/file.n:
+ * mac/tclMacFile.c:
+ * unix/tclUnixFile.c:
+ * win/tclWinFile.c: Also enhanced speed of 'file normalize' on
+ Windows.
+
+2002-06-20 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclBasic.c (TclEvalObjvInternal): fix for [Bug 571385] in
+ the implementation of TIP#62 (command tracing). Vince Darley, Hemang
+ Lavana & Don Porter: thanks.
+
+2002-06-20 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclExecute.c (TclCompEvalObj): clarified and simplified the
+ logic for compilation/recompilation.
+
+2002-06-19 Joe English <jenglish@users.sourceforge.net>
+
+ * doc/file.n: Fixed indentation. No substantive changes.
+
+2002-06-19 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclCmdMZ.c (Tcl_RegexpObjCmd): get the resultPtr again as
+ the Tcl_ObjSetVar2 may cause the result to change. [Patch 558324]
+ (watson)
+
+2002-06-19 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclExecute.c (TEBC): removing unused "for(;;)" loop;
+ improved comments; re-indentation.
+
+2002-06-18 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclExecute.c (TEBC):
+ - elimination of duplicated code in the non-immediate INST_INCR
+ instructions.
+ - elimination of 103 (!) TclDecrRefCount macros. The different
+ instructions now jump back to a common "DecrRefCount zone" at the
+ top of the loop. The macro "ADJUST_PC" was replaced by two macros
+ "NEXT_INST_F" and "NEXT_INST_V" that take three params
+ (pcAdjustment, # of stack objects to discard, resultObjPtr handling
+ flag). The only instructions that retain a TclDecrRefCount are
+ INST_POP (for speed), the common code for the non-immediate
+ INST_INCR, INST_FOREACH_STEP and the two INST_LSET.
+
+ The object size of tclExecute.o was reduced by approx 20% since the
+ start of the consolidation drive, while making room for some peep-hole
+ optimisation at runtime.
+
+2002-06-18 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclExecute.c (TEBC, INST_DONE): small bug in the panic code
+ for tcl-stack corruption.
+
+2002-06-17 David Gravereaux <davygrvy@pobox.com>
+
+ Trims to support the removal of RESOURCE_INCLUDED from rc scripts from
+ [FRQ 565088].
+
+ * generic/tcl.h: moved the #ifndef RC_INVOKED start block up in the
+ file. rc scripts don't need to know thread mutexes.
+
+ * win/tcl.rc:
+ * win/tclsh.rc: removed the #define RESOURCE_INCLUDED to let the
+ built-in -DRC_INVOKED to the work.
+
+2002-06-17 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * doc/CrtTrace.3: Added TIP#62 implementation of command
+ * doc/trace.n: execution tracing [FRQ 462580] (lavana).
+ * generic/tcl.h: This includes enter/leave tracing as well
+ * generic/tclBasic.c: as inter-procedure stepping.
+ * generic/tclCmdMZ.c:
+ * generic/tclCompile.c:
+ * generic/tclExecute.c:
+ * generic/tclInt.decls:
+ * generic/tclInt.h:
+ * generic/tclIntDecls.h:
+ * generic/tclStubInit.c:
+ * generic/tclVar.c:
+ * tests/trace.test:
+
+2002-06-17 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * win/tclWinPipe.c (BuildCommandLine): Fixed [Bug 554068] ([exec] on
+ windows did not treat { in filenames well.). Bug reported by Vince
+ Darley <vincentdarley@users.sourceforge.net>, patch provided by Vince
+ too.
+
+2002-06-17 Joe English <jenglish@users.sourceforge.net>
+
+ * generic/tcl.h: #ifdef logic for K&R C backwards compatibility
+ changed to assume modern C by default. See [FRQ 565088] for full
+ details.
+
+2002-06-17 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/msgcat.n: Corrected en_UK references to en_GB. UK is not a
+ country designation recognized in ISO 3166.
+
+ * library/msgcat/msgcat.tcl: More Windows Registry locale codes from
+ Bruno Haible.
+
+ * doc/msgcat.n:
+ * library/msgcat/msgcat.tcl:
+ * library/msgcat/pkgIndex.tcl:
+ * tests/msgcat.test: Revised locale initialization to interpret
+ environment variable locale values according to XPG4, and to recognize
+ the LC_ALL and LC_MESSAGES values over that of LANG. Also added many
+ Windows Registry locale values to those recognized by msgcat. Revised
+ tests and docs. Bumped to version 1.3. Thanks to Bruno Haible for the
+ report and assistance crafting the solution. [Bug 525522, 525525]
+
+2002-06-16 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclCompile.c (TclCompileTokens): a better algorithm for the
+ previous bug fix.
+
+2002-06-16 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclCompile.c (TclCompileTokens):
+ * tests/compile.test: [Bug 569438] in the processing of dollar
+ variables; report by Georgios Petasis.
+
+2002-06-16 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclExecute.c: bug in the consolidation of the INCR_..._STK
+ instructions; the bug could not be exercised as the (faulty)
+ instruction INST_INCR_ARRAY_STK was never compiled-in (related to [Bug
+ 569438]).
+
+2002-06-14 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclExecute.c (TclExecuteByteCode): runtime peep-hole
+ optimisation of variables (INST_STORE, INST_INCR) and commands
+ (INST_INVOKE); faster check for the existence of a catch.
+ (TclExecuteByteCode): runtime peep-hole optimisation of comparisons.
+ (TclExecuteByteCode): runtime peep-hole optimisation of INST_FOREACH -
+ relies on peculiarities of the code produced by the bytecode compiler.
+
+2002-06-14 David Gravereaux <davygrvy@pobox.com>
+
+ * win/rules.vc: The test for compiler optimizations was in error.
+ Thanks goes to Roy Terry <royterry@earthlink.net> for his assistance
+ with this.
+
+2002-06-14 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/trace.n, tests/trace.test:
+ * generic/tclCmdMZ.c (Tcl_TraceObjCmd,TclTraceCommandObjCmd)
+ (TclTraceVariableObjCmd): Changed references to "trace list" to
+ "trace info" as mandated by TIP#102.
+
+2002-06-13 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclExecute.c (TclExecuteByteCode): consolidated code for the
+ conditional branch instructions.
+
+2002-06-13 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclExecute.c (TclExecuteByteCode): fixed the previous patch;
+ wouldn't compile with TCL_COMPILE_DEBUG set.
+
+2002-06-13 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclExecute.c (TclExecuteByteCode): consolidated the handling
+ of exception returns to INST_INVOKE and INST_EVAL, as well as most of
+ the code for INST_CONTINUE and INST_BREAK, in the new jump target
+ "processExceptionReturn".
+
+2002-06-13 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclExecute.c (TclExecuteByteCode): consolidated variable
+ handling opcodes, replaced redundant code with some 'goto'. All
+ store/append/lappend opcodes on the same data type now share the main
+ code; same with incr opcodes.
+ * generic/tclVar.c: added the bit TCL_TRACE_READS to the possible
+ flags to Tcl_SetVar2Ex - it causes read traces to be fired prior to
+ setting the variable. This is used in the core for [lappend].
+
+ ***NOTE*** the usage of TCL_TRACE_READS in Tcl_(Obj)?GetVar.* is not
+ documented; there, it causes the call to create the variable if it
+ does not exist. The new usage in Tcl_(Obj)?SetVar.* remains
+ undocumented too ...
+
+2002-06-13 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * tests/fCmd.test:
+ * tests/winFile.test:
+ * tests/fileSystem.test:
+ * generic/tclTest.c:
+ * generic/tclCmdAH.c:
+ * generic/tclIOUtil.c:
+ * doc/FileSystem.3:
+ * mac/tclMacFile.c:
+ * unix/tclUnixFile.c:
+ * win/tclWinFile.c: fixed up further so both compiles and actually
+ works with VC++ 5 or 6.
+ * win/tclWinInt.h:
+ * win/tclWin32Dll.c: cleaned up code and vfs tests and added tests for
+ the internal changes of 2002-06-12, to see whether WinTcl on NTFS can
+ coexist peacefully with links in the filesystem. Added new test
+ command 'testfilelink' to enable the newer code to be tested.
+ * tests/fCmd.test: (made certain tests of 'testfilelink' not run on
+ unix).
+
+2002-06-12 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * tclBasic.c (Tcl_DeleteTrace): fixed [Bug 568123] (thanks to Hemang
+ Lavana)
+
+2002-06-12 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/tclWinFile.c: corrected the symbolic link handling code to allow
+ it to compile. Added real definition of REPARSE_DATA_BUFFER (found in
+ winnt.h). Most of the added definitions appear to have correct,
+ cross-Win-version equivalents in winnt.h and should be removed, but
+ just making things "work" for now.
+
+2002-06-12 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclIOUtil.c:
+ * generic/tcl.decls:
+ * generic/tclDecls.h: made code for Tcl_FSNewNativePath agree with man
+ pages.
+
+ * doc/FileSystem.3: clarified the circumstances under which certain
+ functions are called in the presence of symlinks.
+
+ * win/tclWinFile.c:
+ * win/tclWinPort.h:
+ * win/tclWinInt.h:
+ * win/tclWinFCmd.c: Fix for Windows to allow 'file lstat', 'file
+ type', 'glob -type l', 'file copy', 'file delete', 'file normalize',
+ and all VFS code to work correctly in the presence of symlinks
+ (previously Tcl's behaviour was not very well defined). This also
+ fixes possible serious problems in all versions of WinTcl where 'file
+ delete' on a NTFS symlink could delete the original, not the symlink.
+ Note: symlinks cannot yet be created in pure Tcl.
+
+2002-06-11 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclBasic.c:
+ * generic/tclCompCmds.c:
+ * generic/tclInt.h: reverted the new compilation functions; replaced
+ by a more general approach described below.
+
+ * generic/tclCompCmds.c:
+ * generic/tclCompile.c: made *all* compiled variable access attempts
+ create an indexed variable - even get or incr without previous set.
+ This allows indexed access to local variables that are created and set
+ at runtime, for example by [global], [upvar], [variable], [regexp],
+ [regsub].
+
+2002-06-11 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * doc/global.n:
+ * doc/info.n:
+ * test/info.test:
+ * generic/tclCmdIL.c: fix for [Bug 567386], [info locals] was
+ reporting some linked variables.
+
+ * generic/tclBasic.c:
+ * generic/tclCompCmds.c:
+ * generic/tclInt.h: added compile functions for [global], [variable]
+ and [upvar]. They just declare the new local variables, the commands
+ themselves are not compiled-in. This gives a notably faster read
+ access to these linked variables.
+
+2002-06-11 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclExecute.c: optimised algorithm for exception range
+ lookup; part of [Patch 453709].
+
+2002-06-10 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * unix/tclUnixFCmd.c: fixed [Bug 566669]
+ * generic/tclIOUtil.c: improved and sped up handling of native paths
+ (duplication and conversion to normalized paths), particularly on
+ Windows.
+ * modified part of above commit, due to problems on Linux. Will
+ re-examine bug report and evaluate more closely.
+
+2002-06-07 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/tcltest.test: More corrections to test suite so that tests of
+ failing [test]s don't show up themselves as failing tests.
+
+2002-06-07 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclExecute.c: Tidied up headers in relation to float.h to
+ cut the cruft and ensure DBL_MAX is defined since doubles seem to be
+ the same size everywhere; if the assumption isn't true, the variant
+ platforms had better have run configure...
+
+ * unix/tclUnixPort.h (EOVERFLOW): Added code to define it if it
+ wasn't previously defined. Also some other general tidying and adding
+ of comments. [Bugs 563122, 564595]
+ * compat/tclErrno.h: Added definition for EOVERFLOW copied from
+ Solaris headers; I've been unable to find any uses of EFTYPE, which
+ was the error code previously occupying the slot, in Tcl, or any
+ definition of it in the Solaris headers.
+
+2002-06-06 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/dltest/Makefile.in: Remove hard coded CFLAGS=-g and add
+ CFLAGS_DEBUG, CFLAGS_OPTIMIZE, and CFLAGS_DEFAULT varaibles. [Bug
+ 565488]
+
+2002-06-06 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/tcltest.test: Corrections to test suite so that tests of
+ failing [test]s don't show up themselves as failing tests.
+
+ * tests/io.test: Fixed up namespace variable resolution issues
+ revealed by running test suite with "-singleproc 1".
+
+ * doc/tcltest.n:
+ * library/tcltest/tcltest.tcl:
+ * tests/tcltest.test: Several updates to tcltest.
+ 1) changed to lazy initialization of test constraints
+ 2) deprecated [initConstraintsHook]
+ 3) repaired badly broken [limitConstraints].
+ 4) deprecated [threadReap] and [mainThread]
+ [Patch 512214, Bug 558742, Bug 461000, Bug 534903]
+
+2002-06-06 Daniel Steffen <das@users.sourceforge.net>
+
+ * unix/tclUnixThrd.c (TclpReaddir, TclpLocaltime, TclpGmtime): added
+ mutex wrapped calls to readdir, localtime & gmtime in case their
+ thread-safe *_r counterparts are not available.
+ * unix/tcl.m4: added configure check for readdir_r
+ * unix/tcl.m4 (Darwin): set TCL_DEFAULT_ENCODING to utf-8 on MacOSX
+ (where posix file apis expect utf-8, not iso8859-1).
+ * unix/configure: regen
+ * unix/Makefile.in: set DYLD_LIBRARY_PATH in parallel to
+ LD_LIBRARY_PATH for MacOSX dynamic linker.
+ * generic/tclEnv.c (TclSetEnv): fix env var setting on MacOSX (adapted
+ from [Patch 524352] by jkbonfield).
+
+2002-06-05 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/Tcl_Main.3: Documented $tcl_rcFileName and added more
+ clarifications about the intended use of Tcl_Main(). [Bug 505651]
+
+2002-06-05 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tclFileName.c (TclGlob): mac specific fix to recent changes
+ in 'glob -tails' handling.
+ * mac/tclMacPort.h:
+ * mac/tclMacChan.c: fixed TIP#91 bustage.
+ * mac/tclMacResource.c (Tcl_MacConvertTextResource): added utf
+ conversion of text resource contents.
+ * tests/macFCmd.test (macFCmd-1.2): allow CWIE creator.
+
+2002-06-04 Don Porter <dgp@users.sourceforge.net>
+
+ * library/tcltest/tcltest.tcl:
+ * tests/init.test:
+ * tests/tcltest.test: Added more TIP 85 tests from Arjen Markus.
+ Converted tcltest.test to use a private namespace. Fixed bugs in
+ [tcltest::Eval] revealed by calling [tcltest::test] from a non-global
+ namespace, and namespace errors in init.test.
+
+2002-06-04 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/README: Update msys+mingw URL.
+
+2002-06-03 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/tcltest.n:
+ * library/tcltest/tcltest.tcl:
+ * library/tcltest/pkgIndex.tcl:
+ * tests/tcltest.test: Implementation of TIP 85. Allows tcltest users
+ to add new legal values of the -match option to [test], associating
+ each with a Tcl command that does the matching of expected results
+ with actual results of tests. Thanks to Arjen Markus. => tcltest 2.1
+ [Patch 521362]
+
+2002-06-03 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * doc/namespace.n: added description of [namepace forget] behaviour
+ for unqualified patterns. [Bug 559268]
+
+2002-06-03 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclExecute.c: reverting an accidental modification in the
+ last commit.
+
+2002-06-03 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * doc/Tcl.n: clarify the empty variable name issue ([Bug 549285]
+ reported by Tom Krehbiel, patch by Don Porter).
+
+2002-05-31 Don Porter <dgp@users.sourceforge.net>
+
+ * library/package.tcl: Fixed leak of slave interp in [pkg_mkIndex].
+ Thanks to Helmut for report. [Bug 550534]
+
+ * tests/io.test:
+ * tests/main.test: Use the "stdio" constraint to control whether an
+ [open "|[interpreter]"] is attempted.
+
+ * generic/tclExecute.c (TclMathInProgress,TclExecuteByteCode
+ (ExprCallMathFunc):
+ * generic/tclInt.h (TclMathInProgress):
+ * unix/Makefile.in (tclMtherr.*):
+ * unix/configure.in (NEED_MATHERR):
+ * unix/tclAppInit.c (matherr):
+ * unix/tclMtherr.c (removed file):
+ * win/tclWinMtherr.c (_matherr): Removed internal routine
+ TclMathInProgress and Unix implementation of matherr(). These are now
+ obsolete, dealing with very old versions of the C math library.
+ Windows version is retained in case Borland compilers require it, but
+ it is inactive. Thanks to Joe English. [Bug 474335, Patch 555635]
+
+ * unix/configure: regen
+
+2002-05-30 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclCompExpr.c:
+ * generic/tclCompile.c:
+ * generic/tclCompile.h: removed exprIsJustVarRef and
+ exprIsComparison from the ExprInfo and CompileEnv structs. These
+ were set, but not used since dec 1999 [Bug 562383].
+
+2002-05-30 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclFileName.c (TclGlob): fix to longstanding 'knownBug' in
+ fileName tests 15.2-15.4, and fix to a new Tcl 8.4 bug in certain uses
+ of 'glob -tails'.
+ * tests/fileName.test: removed 'knownBug' flag from some tests, added
+ some new tests for above bugs.
+
+2002-05-29 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/configure: regen'ed
+ * unix/configure.in: replaced bigendian check with autoconf standard
+ AC_C_BIG_ENDIAN, which defined WORDS_BIGENDIAN on bigendian systems.
+ * generic/tclUtf.c (Tcl_UniCharNcmp):
+ * generic/tclInt.h (TclUniCharNcmp): use WORDS_BIGENDIAN instead of
+ TCL_OPTIMIZE_UNICODE_COMPARE to enable memcmp alternative.
+
+ * generic/tclExecute.c (TclExecuteByteCode INST_STR_CMP):
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd): changed the case for choosing
+ the Tcl_UniCharNcmp compare to when both objs are of StringType, as
+ benchmarks show that is the optimal check (both bigendian and
+ littleendian systems).
+
+2002-05-29 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclMain.c: Removed "dummy" reference to Tcl_LinkVar. It is
+ no longer needed since Tcl_Main() now actually calls Tcl_LinkVar().
+ Thanks to Joe English for pointing that out.
+
+2002-05-29 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclExecute.c (TclExecuteByteCode):
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd): Use the macro version.
+ * generic/tclInt.h (TclUniCharNcmp): Optimised still further with a
+ macro for use in sensitive places like tclExecute.c
+
+ * generic/tclUtf.c (Tcl_UniCharNcmp): Use new flag to figure out when
+ we can use an optimal comparison scheme, and default to the old scheme
+ in other cases which is at least safe.
+ * unix/configure.in (TCL_OPTIMIZE_UNICODE_COMPARE): New optional flag
+ that indicates when we can use memcmp() to compare Unicode strings
+ (i.e. when the high-byte of a Tcl_UniChar precedes the low-byte.)
+
+2002-05-29 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclInt.decls:
+ * generic/tclIntDecls.h:
+ * generic/tclStubInit.c:
+ * generic/tclUtf.c: added TclpUtfNcmp2 private command that
+ mirrors Tcl_UtfNcmp, but takes n in bytes, not utf-8 chars. This
+ provides a faster alternative for comparing utf strings internally.
+ (Tcl_UniCharNcmp, Tcl_UniCharNcasecmp): removed the explicit end of
+ string check as it wasn't correct for the function (by doc and logic).
+
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd): reworked the string equal
+ comparison code to use TclpUtfNcmp2 as well as short-circuit for
+ equal objects or unequal length strings in the equal case.
+ Removed the use of goto and streamlined the other parts.
+
+ * generic/tclExecute.c (TclExecuteByteCode): added check for object
+ equality in the comparison instructions. Added short-circuit for !=
+ length strings in INST_EQ, INST_NEQ and INST_STR_CMP. Reworked
+ INST_STR_CMP to use TclpUtfNcmp2 where appropriate, and only use
+ Tcl_UniCharNcmp when at least one of the objects is a Unicode obj with
+ no utf bytes.
+
+ * generic/tclCompCmds.c (TclCompileStringCmd): removed error creation
+ in code that no longer throws an error.
+
+ * tests/string.test:
+ * tests/stringComp.test: added more string comparison checks.
+
+ * tests/clock.test: better qualified 9.1 constraint check for %s.
+
+2002-05-28 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclThreadAlloc.c (TclpRealloc, TclpFree): protect
+ against the case when NULL is based.
+
+ * tests/clock.test: added clock-9.1
+ * compat/strftime.c:
+ * generic/tclClock.c:
+ * generic/tclInt.decls:
+ * generic/tclIntDecls.h:
+ * unix/tclUnixTime.c: fix for Windows msvcrt mem leak caused by using
+ an env(TZ) setting trick for in clock format -gmt 1. This also makes
+ %s seem to work correctly with -gmt 1 as well as making it a lot
+ faster by avoid the env(TZ) hack. TclpStrftime now takes useGMT as an
+ arg. [Bug 559376]
+
+2002-05-28 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclIOUtil.c: fixes to Tcl_FSLoadFile when called on a file
+ inside a vfs. This should avoid leaving temporary files sitting
+ around on exit. [Bug 545579]
+
+2002-05-27 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * win/tclWinError.c: Added comment on conversion of
+ ERROR_NEGATIVE_SEEK because that is a mapping that really belongs,
+ and not a catch-all case.
+ * win/tclWinPort.h (EOVERFLOW): Should be either EFBIG or EINVAL
+ * generic/tclPosixStr.c (Tcl_ErrnoId, Tcl_ErrnoMsg): EOVERFLOW can
+ potentially be a synonym for EINVAL.
+
+2002-05-24 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ === Changes due to TIP#91 ===
+
+ * win/tclWinPort.h: Added declaration of EOVERFLOW.
+ * doc/CrtChannel.3: Added documentation of wideSeekProc.
+ * generic/tclIOGT.c (TransformSeekProc, TransformWideSeekProc):
+ Adapted to use the new channel mechanism.
+ * unix/tclUnixChan.c (FileSeekProc, FileWideSeekProc): Renamed
+ FileSeekProc to FileWideSeekProc and created new FileSeekProc which
+ has the old-style interface and which errors out with EOVERFLOW when
+ the returned file position can't fit into the return type (int for
+ historical reasons).
+ * win/tclWinChan.c (FileSeekProc, FileWideSeekProc): Renamed
+ FileSeekProc to FileWideSeekProc and created new FileSeekProc which
+ has the old-style interface and which errors out with EOVERFLOW when
+ the returned file position can't fit into the return type (int for
+ historical reasons).
+ * mac/tclMacChan.c (FileSeek): Reverted to old interface; Macs lack
+ large-file support because I can't see how to add it.
+ * generic/tclIO.c (Tcl_Seek, Tcl_Tell): Given these functions
+ knowledge of the new arrangement of channel types.
+ (Tcl_ChannelVersion): Added recognition of new version code.
+ (HaveVersion): New function to do version checking.
+ (Tcl_ChannelBlockModeProc, Tcl_ChannelFlushProc)
+ (Tcl_ChannelHandlerProc): Made these functions use HaveVersion for
+ ease of future maintainability.
+ (Tcl_ChannelBlockModeProc): Obvious lookup function.
+ * generic/tcl.h (Tcl_ChannelType): New wideSeekProc field, and
+ seekProc type restored to old interpretation.
+ (TCL_CHANNEL_VERSION_3): New channel version.
+
+2002-05-24 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * tests/winPipe.test: Applied patch for [Bug 549617]. Patch and bug
+ report by Kevin Kenny <kennykb@users.sourceforge.net>.
+
+ * win/tclWinSock.c (TcpWatchProc): Fixed [Bug 557878]. We are not
+ allowed to mess with the watch mask if the socket is a server socket.
+ I believe that the original reporter is George Peter Staplin.
+
+2002-05-21 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/configure: Regen.
+ * unix/configure.in: Invoke SC_ENABLE_SHARED before calling
+ SC_CONFIG_CFLAGS so that the SHARED_BUILD variable can be checked
+ inside SC_CONFIG_CFLAGS.
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): Pass -non_shared instead of -shared
+ to ld when configured with --disable-shared under OSF. [Bug 540390]
+
+2002-05-20 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tclInt.h: added prototype for TclpFilesystemPathType().
+ * mac/tclMacChan.c: use MSL provided creator type if available instead
+ of the default 'MPW '.
+
+2002-05-16 Joe English <jenglish@users.sf.net>
+
+ * doc/CrtObjCmd.3: Added Tcl_GetCommandFromObj, Tcl_GetCommandFullName
+ [Bugs 547987, 414921]
+
+2002-05-14 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * unix/tclUnixChan.c (TtyOutputProc): #if/#endif-ed this function out
+ to stop compiler warnings. Also much general tidying of comments in
+ this file and removal of whitespace from blank lines.
+
+2002-05-13 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * unix/tclUnixChan.c (SETBREAK): Solaris thinks ioctl() takes a signed
+ second argument, and Linux thinks ioctl() takes an unsigned second
+ argument. So need a longer definition of this macro to get neither to
+ spew warnings...
+
+2002-05-13 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclEvent.c:
+ * generic/tclIOUtil.c:
+ * generic/tclInt.h: clean up all memory allocated by the filesystem,
+ via introduction of 'TclFinalizeFilesystem'.
+ Move TclFinalizeLoad into TclFinalizeFilesystem so we can be sure it
+ is called at just the right time.
+ Fix bad comment also. [Bug 555078 and 'fs' part of 543549]
+ * win/tclWinChan.c: fix comment referring to wrong function.
+
+2002-05-10 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/load.test:
+ * tests/safe.test:
+ * tests/tcltest.test: Corrected some list-quoting issues and other
+ matters that cause tests to fail when the patch includes special
+ characters. Report from Vince Darley. [Bug 554068]
+
+2002-05-08 David Gravereaux <davygrvy@pobox.com>
+
+ * doc/file.n:
+ * tools/man2tcl.c:
+ * tools/man2help2.tcl: Thanks to Peter Spjuth
+ <peter.spjuth@space.se>, again. My prior fix for single-quote macro
+ mis-understanding was wrong. Reverted to reimpliment the 'macro2' proc
+ which handles single-quote macros and restored file.n text arrangement
+ to avoid single-quotes on the first line. Sorry for all the confusion.
+
+2002-05-08 David Gravereaux <davygrvy@pobox.com>
+
+ * tools/man2tcl.c:
+ * tools/man2help2.tcl: Proper source of macro error misunderstanding
+ single-quote as the leading macro command found and repaired.
+
+ * doc/file.n: Reverted to prior state before I messed with it.
+
+2002-05-08 Don Porter <dgp@users.sourceforge.net>
+
+ * library/tcltest/tcltest.tcl: Corrected [uplevel] quoting when
+ [source]-ing test script in subdirectories.
+ * tests/fileName.test:
+ * tests/load.test:
+ * tests/main.test:
+ * tests/tcltest.test:
+ * tests/unixInit.test: Fixes to test suite when there's a space in the
+ working path. Thanks to Kevin Kenny.
+
+2002-05-07 David Gravereaux <davygrvy@pobox.com>
+
+ -- Changes from Peter Spjuth <peter.spjuth@space.se>
+ * tools/man2tcl.c: Increased line buffer size and a bail-out if that
+ should ever be over-run.
+ * tools/man2help.tcl: Include Courier New font in rtf header.
+ * tools/man2help2.tcl: Improved handling of CS/CE fields. Use Courier
+ New for code samples and indent better.
+
+ * doc/file.n:
+ * doc/TraceCmd.3: winhelp conversion tools where understanding
+ a ' as the first character on a line to be an unknown macro.
+ Not knowing how to repair tools/man2tcl.c, I decided to rearrange
+ the text in the docs instead.
+
+2002-05-07 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclFileName.c: fix to similar segfault when using 'glob
+ -types nonsense -dir dirname -join * *'. [Bug 553320]
+
+ * doc/FileSystem.3: further documentation on vfs.
+ * tests/cmdAH.test:
+ * tests/fileSystem.test:
+ * tests/pkgMkindex.test: Fix to testsuite bugs when running out of
+ directory whose name contains '{' or '['.
+
+2002-05-07 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * tests/basic.test: Fix for [Bug 549607]
+ * tests/encoding.test: Fix for [Bug 549610]
+ These are testsuite bugs that caused failures when the filename
+ contained spaces. Report & fix by Kevin Kenny.
+
+2002-05-02 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclFileName.c: fix to freeing a bad object (i.e. segfault)
+ when using 'glob -types nonsense -dir dirname'.
+ * generic/tclWinFile.c: fix to [Bug 551306], also wrapped some long
+ lines.
+ * tests/fileName.test: added several tests for the above bugs.
+ * doc/FileSystem.3: clarified documentation on refCount requirements
+ of the object returned by the path type function.
+ * generic/tclIOUtil.c:
+ * win/tclWinFile.c:
+ * unix/tclUnixFile.c:
+ * mac/tclMacFile.c: moved TclpFilesystemPathType to the platform-
+ specific directories, so we can add missing platform-specific
+ implementations. On Windows, 'file system' now returns useful results
+ like "native NTFS", "native FAT" for that system. Unix and MacOS still
+ only return "native".
+ * doc/file.n: clarified documentation.
+ * tests/winFile.test: test for 'file system' returning correct values.
+ * tests/fileSystem.test: test for 'file system' returning correct
+ values. Clean up after failed previous test run.
+
+2002-04-26 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/configure:
+ * unix/tcl.m4: change HP-11 SHLIB_LD_LIBS from "" to ${LIBS} so that
+ the .sl knows its dependent libs.
+
+2002-04-26 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * tests/obj.test (obj-11.[56]): Test conversion to boolean more
+ thoroughly.
+ * generic/tclObj.c (SetBooleanFromAny): Was not calling an integer
+ parsing function on native 64-bit platforms! [Bug 548686]
+
+2002-04-24 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclInt.h: corrected TclRememberJoinableThread decl to use
+ VOID instead of void.
+ * generic/tclThreadJoin.c: noted that this code isn't needed on Unix.
+
+2002-04-23 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * doc/exec.n:
+ * doc/tclvars.n: doc updates [Patch 509426] (gravereaux)
+
+2002-04-24 Daniel Steffen <das@users.sourceforge.net>
+
+ * mac/tclMacResource.r: added check of TCLTK_NO_LIBRARY_TEXT_RESOURCES
+ #define to allow disabling the inclusion of the tcl library code in
+ the resource fork of Tcl executables and shared libraries.
+
+2002-04-23 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/TraceCmd.3: New file that documents Tcl_CommandTraceInfo,
+ Tcl_TraceCommand and Tcl_UntraceCommand [Bug 414927]
+
+2002-04-22 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclAlloc.c:
+ * generic/tclInt.h:
+ * generic/tclThreadAlloc.c (new):
+ * unix/Makefile.in:
+ * unix/tclUnixThrd.c:
+ * win/Makefile.in:
+ * win/tclWinInt.h:
+ * win/tclWinThrd.c: added new threaded allocator contributed by AOL
+ that significantly reduces lock contention when multiple threads are
+ in use. Only Windows and Unix implementations are ready, and the
+ Windows one may need work. It is only used by default on Unix for now,
+ and requires that USE_THREAD_ALLOC be defined (--enable-threads on
+ Unix will define this).
+
+ * generic/tclIOUtil.c (Tcl_FSRegister, Tcl_FSUnregister): corrected
+ calling of Tcl_ConditionWait to ensure that there would be a condition
+ to wait upon.
+
+ * generic/tclCmdAH.c (Tcl_FileObjCmd): added cast in FILE_SIZE.
+
+ * win/tclWinFCmd.c (DoDeleteFile): check return of setattr API calls
+ in file deletion for correct Win32 API handling.
+
+ * win/Makefile.in: correct dependencies for shell, gdb, runtest
+ targets.
+
+ * doc/clock.n:
+ * compat/strftime.c (_fmt): change strftime to correctly handle
+ localized %c, %x and %X on Windows. Added some notes about how the
+ other values could be further localized.
+
+2002-04-19 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclMain.c (Tcl_Main): Free the memory allocated for the
+ startup script path. [Bug 543549]
+
+ * library/msgcat/msgcat.tcl: [mcmax] wasn't using the caller's
+ namespace when determining the max translated length. Also made
+ revisions for better use of namespace variables and more efficient
+ [uplevel]s.
+
+ * doc/msgcat.n:
+ * library/msgcat/msgcat.tcl:
+ * library/msgcat/pkgIndex.tcl: Added [mcload] to the export list of
+ msgcat; bumped to 1.2.3. [Bug 544727]
+
+2002-04-20 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tclInt.decls:
+ * generic/tclIntPlatDecls.h:
+ * generic/tclStubInit.c:
+ * mac/tclMacFCmd.c:
+ * mac/tclMacFile.c:
+ * mac/tclMacUtil.c: Modified TclpObjNormalizePath to be alias file
+ aware, and replaced various calls to FSpLocationFrom*Path by calls to
+ new alias file aware versions FSpLLocationFrom*Path. The alias file
+ aware routines don't resolve the last component of a path if it is an
+ alias. This allows [file copy/delete] etc. to act correctly on alias
+ files. (c.f. discussion in [Bug 511666])
+
+2002-04-19 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * tests/lindex.test (lindex-3.7):
+ * generic/tclUtil.c (TclGetIntForIndex): Stopped indexes from hitting
+ wide ints. [Bug 526717]
+
+2002-04-18 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclNamesp.c:
+ * tests/info.test: [Bug 545325] info level didn't report namespace
+ eval, bug report by Richard Suchenwirth.
+
+2002-04-18 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/subst.n: Clarified documentation on handling unusual return
+ codes during substitution, and on variable substitutions implied by
+ command substitution, and vice versa. [Bug 536838]
+
+2002-04-18 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclCmdIL.c (InfoBodyCmd):
+ * tests/info.test (info-2.6): Proc bodies without string reps would
+ report as empty. [Bug 545644]
+
+ * generic/tclCmdMZ.c (Tcl_SubstObj): More clarification for comment on
+ behaviour when substitutions are not well-formed, prompted by [Bug
+ 536831]; alas, removing the ill-defined behaviour is a lot of work.
+
+2002-04-18 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclExecute.c:
+ * tests/expr-old.test: fix for [Bug 542588] (Phil Ehrens), where "too
+ large integers" were reported as "floating-point value" in [expr]
+ error messages.
+
+2002-04-17 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclEncoding.c (EscapeFromUtfProc):
+ * generic/tclIO.c (WriteChars, Tcl_Close): corrected the handling of
+ outputting end escapes for escape-based encodings.
+ [Bug 526524] (yamamoto)
+
+2002-04-17 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/tcltest.n: Removed [saveState] and [restoreState] from tcltest
+ 2 documentation, effectively deprecating them. [Bug 495660]
+ * library/tcltest/tcltest.tcl: Made separate export for commands kept
+ only for tcltest 1 compatibility.
+
+ * tests/iogt.test: Revised to run tests in a namespace, rather than
+ use the useless and buggy [saveState] and [restoreState] commands of
+ tcltest. Updated to use tcltest 2 as well. [Patch 544911]
+
+2002-04-16 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/io.test: Revised to run tests in a namespace, rather than use
+ the useless and buggy [saveState] and [restoreState] commands of
+ tcltest. Updated to use tcltest 2 as well. [Patch 544546]
+
+2002-04-15 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclProc.c:
+ * tests/proc-old.test: Improved stack trace for TCL_BREAK and
+ TCL_CONTINUE returns from procs. Patch by Don Porter [Bug 536955].
+
+ * generic/tclExecute.c:
+ * tests/compile.test: made bytecodes check for a catch before
+ returning; the compiled [return] is otherwise non-catchable. [Bug
+ 542142] reported by Andreas Kupries.
+
+2002-04-15 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/socket.test: Increased timeout values so that tests have
+ time to successfully complete even on slow/busy machines. [Bug 523470]
+
+ * doc/tcltest.n:
+ * library/tcltest/tcltest.tcl:
+ * tests/tcltest.test: Revised [tcltest::test] to return errors when
+ called with invalid syntax and to accept exactly two arguments as
+ documented. Improved error messages. [Bug 497446, Patch 513983]
+ ***POTENTIAL INCOMPATIBILITY***: Incompatible with previous tcltest
+ 2.* releases, found only in alpha releases of Tcl 8.4.
+
+2002-04-11 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclNotify.c (TclFinalizeNotifier): remove remaining
+ unserviced events on finalization.
+
+ * win/tcl.m4: Enabled COFF as well as CV style debug info with
+ --enable-symbols to allow Dr. Watson users to see function info. More
+ info on debugging levels can be obtained at:
+ http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
+
+ * tests/ioCmd.test: fixed iocmd-8.15 to have mac and unixPc variants.
+
+ * generic/tclParse.c (Tcl_ParseVar): conditionally incr obj refcount
+ to prevent possible mem leak.
+
+2002-04-08 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tcl.h: no <sys/types.h> on mac.
+ * mac/tclMacFile.c: minor fixes to Vince's changes from 03-24.
+ * mac/tclMacOSA.c:
+ * mac/tclMacResource.c: added missing Tcl_UtfToExternalDString
+ conversions of resource file names.
+ * mac/tclMacSock.c (TcpGetOptionProc): fixed bug introduced by Andreas
+ on 02-25; changed strcmp's to strncmp's so that option comparison
+ behaves like on other platforms.
+ * mac/tcltkMacBuildSupport.sea.hqx (CW Pro6 changes): added support to
+ allow Tk to hookup C library stderr/stdout to TkConsole.
+ * tests/basic.test:
+ * tests/cmdAH.test:
+ * tests/encoding.test:
+ * tests/fileSystem.test:
+ * tests/ioCmd.test: fixed tests failing on mac: check for existence of
+ [exec], changed some result strings.
+
+2002-04-06 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/tclUnixFCmd.c (Realpath): added a little extra code to
+ initialize a realpath arg when compiling in PURIFY mode in order to
+ prevent spurious purify warnings. We should really create our own
+ realpath implementation, but this will at least quiet purify for now.
+
+2002-04-05 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCmdMZ.c (Tcl_SubstObj):
+ * tests/subst.test: Corrected [subst] so that return codes TCL_BREAK
+ and TCL_CONTINUE returned by variable substitution have the same
+ effect as when those codes are returned by command substitution. [Bug
+ 536879]
+
+2002-04-03 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * library/tcltest/tcltest.tcl: added getMatchingFiles back (alias to
+ GetMatchingFiles), which was a public function in tcltest 1.0.
+
+2002-04-01 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclEnv.c:
+ * generic/tclIOUtil.c: invalidate filesystem cache when the user
+ changes env(HOME). Fixes [Bug 535621]. Also cleaned up some of the
+ documentation.
+ * tests/fileSystem.test: added test for bug just fixed.
+
+2002-04-01 Kevin Kenny <kennykb@acm.org>
+
+ * win/tclWinTime.c (Tcl_GetTime): made the checks of clock frequency
+ more permissive to cope with the fact that Win98SE is observed to
+ return 1.19318 in place of 1.193182 for the performance counter
+ frequency.
+
+2002-03-29 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclCmdMZ.c (Tcl_TraceObjCmd, TraceVarProc)
+ (TraceCommandProc, TclTraceCommandObjCmd): corrected potential
+ double-free of traces on variables by flagging in Trace*Proc that it
+ will free the var in case the eval wants to delete the var trace as
+ well. [Bug 536937] Also converted Tcl_UntraceVar -> Tcl_UntraceVar2
+ and Tcl_Eval to Tcl_EvalEx in Trace*Proc for slight efficiency
+ improvement.
+
+2002-03-29 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/AllowExc.3:
+ * generic/tclBasic.c (Tcl_EvalObjv,Tcl_EvalEx,Tcl_EvalObjEx):
+ * generic/tclCompile.h (TclCompEvalObj):
+ * generic/tclExecute.c (TclCompEvalObj,TclExecuteByteCode):
+ * tests/basic.test: Corrected problems with Tcl_AllowExceptions having
+ influence over the wrong scope of Tcl_*Eval* calls. Patch from Miguel
+ Sofer. Report from Jean-Claude Wippler. [Bug 219181]
+
+2002-03-28 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclVar.c: Refactored CallTraces to collect repeated handling
+ of its returned value into CallTraces itself.
+
+2002-03-28 David Gravereaux <davygrvy@pobox.com>
+
+ * tools/feather.bmp:
+ * tools/man2help.tcl:
+ * tools/man2help2.tcl:
+ * win/makefile.vc: More winhelp target fixups. Added a feather bitmap
+ to the non-scrollable area and changed the color to be yellow from a
+ plain white. The colors can be whatever we want them to be, but
+ thought I would start with something bold. [Bug 527941]
+
+ * doc/SetVar.3:
+ * doc/TraceVar.3:
+ * doc/UpVar.3: .AP macro syntax repair.
+
+2002-03-27 David Gravereaux <davygrvy@pobox.com>
+
+ * tools/man2help.tcl:
+ * win/makefile.vc: winhelp target now copies all needed files from
+ tools/ to a workarea under $(OUT_DIR) and builds it from there. No
+ build cruft is left in tools/ anymore. All paths used in man2help.tcl
+ are now relative to where the script is. [Bug 527941]
+
+2002-03-27 David Gravereaux <davygrvy@pobox.com>
+
+ * win/.cvsignore:
+ * win/buildall.vc.bat:
+ * win/coffbase.txt:
+ * win/makefile.vc:
+ * win/nmakehlp.c (new):
+ * win/rules.vc: First draft fix for [Bug 527941]. More changes need
+ to done to the makehelp target to get to stop leaving build files in
+ the tools/ directory. This does not address the syntax errors in the
+ man files. Having the contents of tcl.hpj(.in) inside makefile.vc
+ allows for version numbers to be replaced with macros.
+
+ The new nmakehlp.c is built by rules.vc in preprocessing and removes
+ the need to use tricky shell syntax that wasn't compatible on Win9x
+ systems. Clean targets made Win9x complient. This is a first draft
+ repair for [Bug 533862].
+
+2002-03-28 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclBasic.c (Tcl_EvalEx): passing the correct commandSize to
+ TclEvalObjvInternal. [Bug 219362], fix by David Knoll.
+
+2002-03-28 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclBasic.c (Tcl_EvalEx):
+ * tests/basic.test: avoid exceptional returns at level 0. [Bug 219181]
+
+2002-03-27 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/tcltest.n ([mainThread]):
+ * library/tcltest/tcltest.tcl:
+ * tests/tcltest.test: Major code cleanup to deal with whitespace,
+ coding conventions, and namespace issues, with several minor bugs
+ fixed in the process.
+
+ * tests/main.test: Added missing [after cancel]s.
+
+2002-03-25 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/main.test: Removed workarounds for Bug 495977.
+
+ * library/tcltest/tcltest.tcl: Keep the value of $::auto_path
+ unchanged, so that the tcltest package can test code that depends on
+ auto-loading. If a testing application needs $::auto_path pruned, it
+ should do that itself. [Bug 495726]
+ Improve the processing of the -constraints option to [test] so that
+ constraint lists can have arbitrary whitespace, and non-lists don't
+ blow things up. [Bug 495977]
+ Corrected faulty variable initialization. [Bug 534845]
+
+2002-03-25 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * doc/CrtTrace.3: small doc correction
+ * generic/tclBasic.c (Tcl_DeleteTrace): Allow NULL callback on trace
+ deletions. [Bug 534728] (Hemang Lavana)
+
+2002-03-24 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclBasic.c (Tcl_EvalObjv): replaced obscure, incorrect code
+ as described in [Bug 533907] (Don Porter).
+
+2002-03-24 Don Porter <dgp@users.sourceforge.net>
+
+ * library/tcltest/tcltest.tcl: Use [interpreter] to set/query the
+ executable currently running the tcltest package. [Bug 454050]
+
+ * library/tcltest/tcltest.tcl: Allow non-proc commands to be used as
+ the customization hooks. [Bug 495662]
+
+2002-03-24 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclFilename.c:
+ * generic/tclFCmd.c:
+ * generic/tclTest.c:
+ * generic/tcl.h:
+ * generic/tclIOUtil.c:
+ * win/tclWinFile.c:
+ * win/tclWinFCmd.c:
+ * win/tclWinPipe.c:
+ * unix/tclUnixFile.c:
+ * unix/tclUnixFCmd.c:
+ * mac/tclMacFile.c:
+ * doc/FileSystem.3:
+ * doc/file.n:
+ * tests/cmdAH.test:
+ * tests/fileName.test:
+ * tests/fileSystem.test: (new file)
+ * tests/winFCmd.test: fix [Bug 511666] and [Bug 511658], and improved
+ documentation of some aspects of the filesystem, particularly
+ 'Tcl_FSMatchInDirectory' which now might match a single file/directory
+ only, and 'file normalize' which wasn't very clear before. Removed
+ inconsistency betweens docs and the Tcl_Filesystem structure. Also
+ fixed [Bug 523217] and corrected file normalization on Unix so that
+ it expands symbolic links. Added some new tests of the filesystem
+ code (in the new file 'fileSystem.test'), and some extra tests for
+ correct handling of symbolic links. Fix to [Bug 530960] which shows up
+ on Win98. Made comparison with ".com" case insensitive in tclWinPipe.c
+
+ ***POTENTIAL INCOMPATIBILITY***: But only between alpha releases
+ (users of the new Tcl_Filesystem lookup table in Tcl 8.4a4 need to
+ handle the new way in which Tcl may call Tcl_FSMatchInDirectory, and
+ 'file normalize' on unix now behaves correctly). Only known impact is
+ with the 'tclvfs' extension.
+
+2002-03-22 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * tests/basic.test (basic-46.1): adding test for [Bug 533758], fixed
+ earlier today.
+
+2002-03-22 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/tclWinInt.h: moved undef of TCL_STORAGE_CLASS. [Bug 478579]
+
+2002-03-22 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclBasic.c (Tcl_EvalObjEx):
+ * generic/tclExecute.c (TclCompEvalObj): fixed the errorInfo for
+ return codes other than (TCL_OK, TCL_ERROR) to runLevel 0.[Bug 533758]
+ Removed the static RecordTracebackInfo(), as its functionality is
+ easily replicated by Tcl_LogCommandInfo. Bug and redundancy noted by
+ Don Porter.
+
+2002-03-21 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/expr.n: Improved documentation for ceil and floor. [Bug 530535]
+
+2002-03-20 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/SetVar.3:
+ * doc/TraceVar.3:
+ * doc/UpVar.3:
+ * generic/tcl.h (Tcl_VarTraceProc):
+ * generic/tcl.decls (Tcl_GetVar2, Tcl_SetVar2, Tcl_TraceVar2,
+ (Tcl_UnsetVar2, Tcl_UntraceVar2, Tcl_UpVar2, Tcl_VarTraceInfo2,
+ (Tcl_GetVar2Ex, TclSetVar2Ex):
+ * generic/tclCmdMZ.c (TraceVarProc):
+ * generic/tclEnv.c (EnvTraceProc):
+ * generic/tclEvent.c (VwaitVarProc):
+ * generic/tclInt.decls (TclLookupVar,TclPrecTraceProc):
+ * generic/tclLink.c (LinkTraceProc):
+ * generic/tclUtil.c (TclPrecTraceProc):
+ * generic/tclVar.c (CallTraces, MakeUpvar, VarErrMsg, TclLookupVar,
+ (Tcl_GetVar2, Tcl_SetVar2, Tcl_TraceVar2, Tcl_UnsetVar2,
+ (Tcl_UntraceVar2, Tcl_UpVar2, Tcl_VarTraceInfo2, Tcl_GetVar2Ex,
+ (TclSetVar2Ex): Updated interfaces of generic/tclVar.c according to
+ TIP 27. In particular, the "part2" arguments were CONSTified. [Patch
+ 532642]
+ * generic/tclDecls.h:
+ * generic/tclIntDecls.h: make genstubs
+
+2002-03-15 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * tests/compile.test (compile-12.3): Test to detect bug 530320.
+ * generic/tclCompile.c (TclCompileTokens): Fixed buffer overrun
+ reported in bug 530320.
+
+2002-03-14 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/configure: Regen.
+ * win/configure.in: Add configure time test for SEH support in the
+ compiler.
+ * win/tclWin32Dll.c (ESP, EBP, TclpCheckStackSpace,
+ (_except_checkstackspace_handler):
+ * win/tclWinChan.c (ESP, EBP, Tcl_MakeFileChannel,
+ (_except_makefilechannel_handler):
+ * win/tclWinFCmd.c (ESP, EBP, DoRenameFile, DoCopyFile,
+ (_except_dorenamefile_handler, _except_docopyfile_handler):
+ Implement SEH support under gcc using inline asm. Tcl and Tk should
+ now compile with Mingw 1.1. [Patch 525746]
+
+2002-03-14 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/tclWinFCmd.c (DoRenameFile, DoCopyFile): Handle an SEH exception
+ with EXCEPTION_EXECUTE_HANDLER instead of restarting the faulting
+ instruction with EXCEPTION_CONTINUE_EXECUTION. [Bug 466102] provides
+ an example of how restarting could send Tcl into an infinite loop.
+ [Patch 525746]
+
+2002-03-11 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/tclWinFCmd.c (DoRenameFile, DoCopyFile, DoDeleteFile,
+ (DoRemoveJustDirectory): Make sure we don't pass NULL or "" as a path
+ name to Win32 API functions since this was crashing under Windows 98.
+
+2002-03-11 Don Porter <dgp@users.sourceforge.net>
+
+ * library/tcltest/tcltest.tcl:
+ * library/tcltest/pkgIndex.tcl: Bumped tcltest package to 2.0.2.
+
+2002-03-11 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * library/tcltest/tcltest.tcl (getMatchingFiles): Pass a proper list
+ to foreach to avoid munging a Windows patch like D:\Foo\Bar into
+ D:FooBar before the glob.
+
+2002-03-11 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * generic/tclEncoding.c: Fix typo in comment.
+ * generic/tclIO.c (DoReadChars, ReadBytes, ReadChars): Use NULL value
+ instead of pointer set to NULL to make things more clear. Reorder
+ arguments so that they match the function signatures. Cleanup little
+ typos and add more descriptive comment.
+
+2002-03-08 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/README: Update to indicate that Mingw 1.1 is required to build
+ Tcl. Add section describing new msys based build process. Update
+ Cygwin build instructions so users know where to find Mingw 1.1.
+
+2002-03-08 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/tclWinFCmd.c (DoCopyFile): correctly set retval to TCL_OK.
+
+2002-03-07 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/tclWin32Dll.c (TclpCheckStackSpace):
+ * win/tclWinFCmd.c (DoRenameFile, DoCopyFile): Replace hard coded
+ constants with Win32 symbolic names. Move control flow statements out
+ of __try blocks since the documentation indicates it is frowned upon.
+
+2002-03-07 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/interp.n:
+ * generic/tclInterp.c (Tcl_InterpObjCmd, SlaveObjCmd,
+ (SlaveRecursionLimit):
+ * generic/tclTest.c:
+ * tests/interp.test: Added the [interp recursionlimit] command to
+ set/query the recursion limit of an interpreter. Proposal and
+ implementation from Stephen Trier. [TIP 87, Patch 522849]
+
+2002-03-06 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tcl.h, tools/tcl.wse.in, unix/configure.in,
+ * unix/tcl.spec, win/README.binary, win/configure.in, README:
+ Bumped patchlevel; this might need to change in the future, but it
+ will help us distinguish between the CVS version and the most recent
+ released version.
+
+2002-03-06 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclInt.h: for unshared objects, TclDecrRefCount now frees
+ the internal rep before the string rep - just like the non-macro
+ Tcl_DecrRefCount/TclFreeObj. [Bug 524802]
+
+2002-03-06 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/lsearch.n: Documentation of new features, plus examples.
+ * tests/lsearch.test: Tests of new features.
+ * generic/tclCmdIL.c (Tcl_LsearchObjCmd): TIP#80 support. See
+ http://purl.org/tcl/tip/80 for details.
+
+2002-03-05 Jeff Hobbs <jeffh@ActiveState.com>
+
+ *** 8.4a4 TAGGED FOR RELEASE ***
+
+ * unix/tclUnixChan.c: initial remedy for [Bug 525783] flush problem
+ introduced by TIP #35. This may not satisfy true serial channels, but
+ it restores the correct flushing of std* channels on exit.
+
+ * unix/README: added --enable-langinfo doc.
+
+ * unix/tcl.spec:
+ * tools/tcl.wse.in: fixed URL refs to use www.tcl.tk or SF.
+
+2002-03-04 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * README:
+ * mac/README:
+ * unix/Makefile.in:
+ * unix/README:
+ * win/README:
+ * win/README.binary: updated to use www.tcl.tk URL.
+
+ * unix/Makefile.in: added older ChangeLogs to dist target.
+
+ * tests/io.test:
+ * tests/encoding.test: corrected iso2022 encoding results.
+ added encoding-24.*
+ * generic/tclEncoding.c (EscapeFromUtfProc): corrected output of
+ escape codes as per RFC 1468. [Patch 474358] (taguchi)
+ (TclFinalizeEncodingSubsystem): corrected potential double-free
+ when encodings were finalized on exit. [Bugs 219314, 524674]
+
+2002-03-01 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * library/encoding/iso2022-jp.enc:
+ * library/encoding/iso2022.enc:
+ * tools/encoding/iso2022-jp.esc:
+ * tools/encoding/iso2022.esc: gave <ESC>$B precedence over <ESC>$@,
+ based on comments (point 1) in [Bug 219283] (rfc 1468)
+
+ * tests/encoding.test: added encoding-23.* tests
+ * generic/tclIO.c (FilterInputBytes): reset the TCL_ENCODING_START
+ flags in the ChannelState when using 'gets'. [Bug 523988]
+ Also reduced the value of ENCODING_LINESIZE from 30 to 20 as this
+ seems to improve the performance of 'gets' according to tclbench.
+
+2002-02-28 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclCmdMZ.c (TraceCommandProc): ensure that TraceCommandInfo
+ structure was also deleted when a command was deleted to prevent a
+ mem leak.
+
+ * generic/tclBasic.c (Tcl_CreateObjTrace): set tracePtr->flags
+ correctly.
+
+ * generic/tclTimer.c (TimerExitProc): remove remaining events in
+ tls on thread exit.
+
+2002-02-28 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclNamesp.c: allow cached fully-qualified namespace names to
+ be usable from different namespaces within the same interpreter
+ without forcing a new lookup [Patch 458872].
+
+2002-02-28 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclExecute.c: Replaced a few direct stack accesses with the
+ POP_OBJECT() macro [Bug 507181] (Don Porter).
+
+2002-02-27 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/GetIndex.3:
+ * generic/tcl.decls (Tcl_GetIndexFromObjStruct):
+ * generic/tclIndexObj.c (Tcl_GetIndexFromObjStruct): Revised the
+ prototype of the Tcl_GetIndexFromObjStruct to take its struct table as
+ a (CONST VOID *) argument, better describing what it is, maintaining
+ source compatibility, and adding CONST correctness according to TIP
+ 27. Thanks to Joe English for an elegant solution. [Bug 520304]
+
+ * generic/tclDecls.h: make genstubs
+
+ * generic/tclMain.c (Tcl_Main,StdinProc): Corrected some reference
+ count management errors on the interactive command Tcl_Obj found by
+ Purify. Thanks to Jeff Hobbs for the report and assistance.
+
+2002-02-27 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclBasic.c (Tcl_EvalTokensStandard): corrected mem leak in
+ error case.
+
+ * generic/tclTest.c (TestStatProc[123]): correct harmless UMRs.
+
+ * generic/tclLink.c (Tcl_LinkVar): correct mem leak in error case.
+
+2002-02-27 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * tests/socket.test (2.7): Accepted and applied patch for [Bug 523470]
+ provided by Don Porter <dgp@users.sourceforge.net> to avoid timing
+ problems in that test.
+
+ * unix/tclUnixChan.c (TclpOpenFileChannel): Added code to regonize
+ "/dev/tty" (by name) and to not handle it as tty / serial line. This
+ is the controlling terminal and is special. Setting it into raw mode
+ as is done for other tty's is a bad idea. This is a hackish fix for
+ expect [Bug 520624]. The fix has limitation: Tcl_MakeFileChannel
+ handles tty's specially too, but is unable to recognize /dev/tty as it
+ only gets a file descriptor, and no name for it.
+
+2002-02-26 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclCmdAH.c (StoreStatData): corrected mem leak.
+
+ * generic/tclCmdMZ.c (Tcl_RegsubObjCmd): prevent obj leak in
+ remedial regsub case.
+
+ * generic/tclFileName.c (Tcl_TranslateFileName): decr refcount for
+ error case to prevent mem leak.
+
+ * generic/tclVar.c (Tcl_ArrayObjCmd): removed extra obj allocation.
+
+ * unix/tclUnixSock.c (Tcl_GetHostName): added an extra
+ gethostbyname check to guard against failure with truncated
+ names returned by uname.
+
+ * unix/configure:
+ * unix/tcl.m4 (SC_SERIAL_PORT): added sys/modem.h check and defined
+ _XOPEN_SOURCE_EXTENDED for HP-11 to get updated header decls.
+
+ * unix/tclUnixChan.c: added Unix implementation of TIP #35, serial
+ port support. [Patch 438509] (schroedter)
+
+2002-02-26 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclCmpCmds.c: (bugfix to the bugfix, hopefully the last)
+ Bugfix to the new [for] compiling code: was setting a exceptArray
+ parameter using another param which wasn't yet initialised, thus
+ filling it with noise.
+
+2002-02-25 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * mac/tclMacSock.c (TcpGetOptionProc): Changed to recognize the option
+ "-error". Essentially ignores the option, always returning an empty
+ string.
+
+2002-02-25 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * doc/Alloc.3:
+ * doc/LinkVar.3:
+ * doc/ObjectType.3:
+ * doc/PkgRequire.3:
+ * doc/Preserve.3:
+ * doc/TCL_MEM_DEBUG.3: Updated documentation to describe the ckalloc,
+ ckfree, ckrealloc, attemptckalloc, and attemptckrealloc macros, and
+ to accurately describe when and how they are used. [Bug 497459] (dgp)
+
+ * generic/tclHash.c (AllocArrayEntry, AllocStringEntry):
+ Before invoking ckalloc when creating a Tcl_HashEntry,
+ check that the amount of memory being allocated is
+ at least as large as sizeof(Tcl_HashEntry). The previous
+ code was allocating memory regions that were one
+ or two bytes short. [Bug 521950] (dejong)
+
+2002-02-25 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclBasic.c (Tcl_EvalEx): avoiding a buffer overrun
+ reported by Joe English, and restoring tcl7.6 behaviour for
+ [subst]: badly terminated nested scripts will raise an error
+ and not be evaluated. [Bug 495207]
+
+2002-02-25 Don Porter <dgp@users.sourceforge.net>
+
+ * unix/tclUnixPort.h: corrected strtoll prototype mismatch on Tru64.
+ * compat/strtod.c (strtod): simplified #includes
+ * compat/strtol.c (strtol): gather result in a long before returning
+ as a long: necessary on platforms where sizeof(int) != sizeof(long).
+
+2002-02-25 Daniel Steffen <das@users.sourceforge.net>
+
+ * unix/tclLoadDyld.c: updated to use Mac OS X 10.1 dyld APIs that
+ have more libdl-like semantics. [Bug 514392]
+
+2002-02-25 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclCompCmds: fixing a bug in patch dated 2002-02-22, in the
+ code for [for] and [while]. Under certain conditions, for long bodies,
+ the exception range parameters were badly computed. Tests forthcoming:
+ I still can't reproduce the conditions in the testsuite (!), although
+ the bug (with assorted segfault or panic!) can be triggered from the
+ console or with the new parse.bench in tclbench.
+
+2002-02-25 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * compat/strtoul.c, compat/strtol.c, compat/strtod.c: Added UCHAR,
+ CONST and #includes to clean up GCC output.
+
+2002-02-23 Don Porter <dgp@users.sourceforge.net>
+
+ * compat/strtoull.c (strtoull):
+ * compat/strtoll.c (strtoll):
+ * compat/strtoul.c (strtoul): Fixed failure to handle leading
+ sign symbols '+' and '-' and '0X' and raise overflow errors.
+ [Bug 440916] Also corrects prototype and errno problems.
+
+2002-02-23 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * configure: Regen.
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): Link with -n32 instead of -32 when
+ building on IRIX64-6.* system. [Bug 521707]
+
+2002-02-22 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclInt.h:
+ * generic/tclObj.c: renamed global variable emptyString ->
+ tclEmptyString because it is no longer static.
+ * generic/tclPkg.c: Fix for panic when library is loaded on a
+ platform without backlinking without proper use of stubs. [Bug 476537]
+
+2002-02-22 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * tests/regexpComp.test: updated regexp-11.[1-4] to match changes in
+ regexp.test for new regsub syntax
+
+ * unix/configure:
+ * unix/tcl.m4: added --enable-64bit support for AIX-4 (using -q64
+ flag) when using IBM's xlc compiler.
+
+ * tests/safe.test: updated safe-8.5 and safe-8.7
+ * library/safe.tcl (CheckFileName): removed the limit on
+ sourceable file names (was only *.tcl or tclIndex files with no more
+ than one dot and 14 chars). There is enough internal protection in a
+ safe interpreter already. [Tk Bug 521560]
+
+2002-02-22 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclCompCmds: [FR 465811]. Optimising [if], [for] and [while]
+ for constant conditions; in addition, [for] and [while] are now
+ compiled with the "loop rotation" optimisation (thanks to Kevin
+ Kenny).
+
+2002-02-22 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ --- TIP#76 CHANGES ---
+ * generic/tclCmdMZ.c (Tcl_RegsubObjCmd): Final-argument-less
+ [regsub] returns the modified string.
+ * doc/regsub.n: Updated docs.
+ * tests/regexp.test: Updated and added tests.
+
+ * compat/strtoll.c (strtoll):
+ * compat/strtoull.c (strtoull):
+ * unix/tclUnixPort.h:
+ * win/tclWinPort.h: Const-ing 64-bit compatability declarations. Note
+ that the return pointer is non-const because it is entirely legal for
+ the functions to be called from somewhere that owns the string being
+ passed. Fixes problem reported by Larry Virden.
+
+2002-02-21 David Gravereaux <davygrvy@pobox.com>
+
+ * win/mkd.bat (removed):
+ * win/coffbase.txt (new):
+ * win/makefile.bc:
+ * win/makefile.vc: Changed the 'setup' target to stop using the
+ mkd.bat file and just make the directory right in the rule. Same
+ change to makefile.bc. Neither configure.in nor Makefile.in use it.
+
+ coffbase.txt will be the master list for our "prefered base addresses"
+ set by the linker. This should improve load-time (NT only) by avoiding
+ relocations. Submissions to the list by extension authors are
+ encouraged.
+
+ Added a 'tidy' target to compliment 'clean' and 'hose' to remove just
+ the outputs. Also removed the $(winlibs) macro as it wasn't being
+ used.
+
+ Stuff left to do:
+ 1) get the winhelp target to stop building in the tools/ directory.
+ 2) stop using rmd.bat
+ 3) add more dependacy rules.
+
+ * win/tclAppInit.c: Reverted back to -r1.6, as the header file change
+ to tclPort.h won't allow for easy embedded support outside of the
+ source dist. Thanks to Don Porter for pointing this out to me.
+
+2002-02-21 David Gravereaux <davygrvy@pobox.com>
+
+ * win/makefile.vc:
+ * win/rules.vc: Added a new "loimpact" option that sets the
+ -ws:aggressive linker option. Off by default. It's said to keep the
+ heap use low at the expense of alloc speed.
+
+ * win/tclAppInit.c: Changed #include "tcl.h" to be tclPort.h to remove
+ the raw windows.h include. tclPort.h brings in windows.h already and
+ lessens the pre-compiled-header mush and the randomly useless #pragma
+ comment (lib,...) references throughout the big windows.h tree (as
+ observed at high linker warning levels).
+
+2002-02-21 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tcl.h: Better guessing of LP64/ILP32 architecture, but now
+ sensitive to presence of (suitable) <limits.h>
+
+2002-02-20 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tcl.decls (Tcl_RegExpRange,Tcl_GetIndexFromObjStruct):
+ Overlooked a few source incompatibilities. Now using CONST84.
+ * generic/tclDecls.h: make genstubs
+ * generic/tcl.h (Tcl_CmdObjTraceProc): silence warning from Sun
+ Workshop compiler.
+
+2002-02-20 David Gravereaux <davygrvy@pobox.com>
+
+ * win/buildall.vc.bat:
+ * win/makefile.vc:
+ * win/rules.vc: General clean-ups. Added compiler and linker tests for
+ a) the pentium 0x0F errata, b) optimizing (not all have this), and c)
+ linker v6 section alignment confusion. All these are tested first to
+ make sure any D4002 or LNK1117 warnings aren't displayed. The pentium
+ 0x0F errata is a recommended switch. The v5 linker's section alignment
+ default is 512, but the v6 linker was changed to 4096 in an attempt to
+ speed loading on Win98. I changed the default to always be 512 across
+ both linkers, unless linking statically, then 4096 is used for the
+ claimed speed effect. Using a 512 alignment saves 12k bytes of dead
+ space in the DLL.
+
+ Added IA64 B-stepping errata switch when the compiler supports it.
+
+ Added profiling to $(lflags) when requested and also removed the
+ explict -entry option as the default works fine as is.
+
+ Removed win/tclWinInit.c from the special case section to let it use
+ the common implicit rule as the $(EXTFLAGS) macro it had was never
+ referenced anywhere.
+
+2002-02-20 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tcl.h: Added code to guess the correct settings for
+ TCL_WIDE_INT_IS_LONG and TCL_WIDE_INT_TYPE when configure doesn't tell
+ us them, as can happen with extensions.
+
+2002-02-19 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/format.n: Updated docs to list the specification.
+ * generic/tclCmdAH.c (Tcl_FormatObjCmd): Made behaviour on 64-bit
+ platforms correctly meet the specification, that %d works with the
+ native word-sized integer, instead of trying to guess (wrongly)
+ from the value being passed.
+
+2002-02-19 Don Porter <dgp@users.sourceforge.net>
+
+ * changes: First draft of updated changes for 8.4a4 release.
+
+2002-02-15 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/tclUnixPort.h: add strtoll/strtoull declarations for
+ platforms that do not define them.
+
+ * generic/tclIndexObj.c (STRING_AT): removed ptrdiff_t cast and
+ use of VOID* in default case (GNU-ism).
+
+2002-02-15 Kevin Kenny <kennykb@acm.org>
+
+ * compat/strtoll.c:
+ * compat/strtoul.c:
+ * compat/strtoull.c:
+ * generic/tclIOUtil.c:
+ * generic/tclPosixStr.c:
+ * generic/tclTest.c:
+ * generic/tclTestObj.c:
+ * tests/get.test:
+ * win/Makefile.vc: Further tweaks to the TIP 72 patch to make it
+ compile under VC++.
+
+2002-02-15 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * tclExecute.c:
+ * tclIOGT.c:
+ * tclIndexObj.c: Touchups to the TIP 72 patch to make it compileable
+ under Windows again. The changes are not complete, there is one nasty
+ regarding _stati64
+
+2002-02-15 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ +----------------------+
+ | TIP #72 IMPLEMENTED. |
+ +----------------------+
+
+ There are a lot of changes from this TIP, so please see
+ http://purl.org/tcl/tip/72.html for discussion of
+ backward-compatability issues, but the main ones modifications are in:
+
+ * generic/tcl.h: New types.
+ * generic/tcl.decls: New public functions.
+ * generic/tclExecute.c: 64-bit aware bytecode engine.
+ * generic/tclBinary.c: 64-bit handling in [binary] command.
+ * generic/tclScan.c: 64-bit handling in [scan] command.
+ * generic/tclCmdAH.c: 64-bit handling in [file] and [format]
+ commands.
+ * generic/tclBasic.c: New "wordSize" entry in ::tcl_platform.
+ * generic/tclFCmd.c: Large-file support (with many consequences.)
+ * generic/tclIO.c: Large-file support (with many consequences.)
+ * compat/strtoll.c, compat/strtoull.c: New support functions.
+ * unix/tcl.m4, unix/configure: 64-bit support and greatly enhanced
+ cacheing.
+
+ Most other changes, including all those in doc/* and test/* as well as
+ the majority in the platform directories, follow on from these.
+
+ Also coming out of the woodwork:
+ * generic/tclIndex.c: Better support for Cray PVP.
+ * win/tclWinMtherr.c: Better Borland support.
+
+ Note that, in a number of places through the Unix part of the platform
+ support, there are Tcl_Platform* references. These are expanded into
+ the correct way to call that particular underlying function, i.e. with
+ or without a '64' suffix, and should be used by people working on the
+ core in preference to the API functions they overlay so that the code
+ remains portable depending on the presence or absence of 64-bit
+ support on the underlying platform.
+
+ ***POTENTIAL INCOMPATIBILITY***: Extracted from the TIP
+
+ SUMMARY OF INCOMPATIBILITIES AND FIXES
+ ======================================
+
+ The behaviour of expressions containing constants that appear positive
+ but which have a negative internal representation will change, as
+ these will now usually be interpreted as wide integers. This is always
+ fixable by replacing the constant with int(constant).
+
+ Extensions creating new channel types will need to be altered as
+ different types are now in use in those areas. The change to the
+ declaration of Tcl_FSStat and Tcl_FSLstat (which are the new preferred
+ API in any case) are less serious as no non-alpha releases have been
+ made yet with those API functions.
+
+ Scripts that are lax about the use of the l modifier in format and
+ scan will probably need to be rewritten. This should be very uncommon
+ though as previously it had absolutely no effect.
+
+ Extensions that create new math functions that take more than one
+ argument will need to be recompiled (the size of Tcl_Value changes),
+ and functions that accept arguments of any type (TCL_EITHER) will need
+ to be rewritten to handle wide integer values. (I do not expect this
+ to affect many extensions at all.)
+
+2002-02-14 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * generic/tclIOCmd.c (Tcl_GetsObjCmd): Trivial fix for [Bug 517503], a
+ memory leak reported by Miguel Sofer <msofer@users.sf.net>. The leak
+ happens if an error occurs for "set var [gets $chan]" and leak one
+ empty object.
+
+2002-02-12 David Gravereaux <davygrvy@pobox.com>
+
+ * djgpp/ (new directory)
+ * djgpp/Makefile (new):
+ * unix/tclAppInit.c:
+ * unix/tclMtherr.c:
+ * unix/tclUnixFCmd.c:
+ * unix/tclUnixFile.c:
+ * unix/tclUnixInit.c:
+ * unix/tclUnixPort.h: Early stage of DJGPP support for building Tcl
+ on DOS. Dynamic loading isn't working, yet. Requires watt32 for the
+ TCP/IP stack. No autoconf, yet. Barely tested, but makes a working exe
+ that runs Tcl in protected-mode, flat memory. [exec] and pipes will
+ need the most work as multi-tasking on DOS has to be carefully.
+
+2002-02-10 Kevin Kenny <kennykb@acm.org>
+
+ * doc/CrtObjCmd.3:
+ * doc/CrtTrace.3:
+ * generic/tcl.decls:
+ * generic/tcl.h:
+ * generic/tclBasic.c:
+ * generic/tclInt.h:
+ * generic/tclTest.c:
+ * tests/basic.test: Added Tcl_CreateObjTrace,
+ Tcl_GetCommandInfoFromToken and Tcl_SetCommandInfoFromToken.
+ (TIPs #32 and #79.)
+
+ * generic/tclDecls.h:
+ * generic/tclStubInit.c: Regenerated Stubs tables.
+
+2002-02-08 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/configure:
+ * unix/tcl.m4: added -pthread for FreeBSD to EXTRA_CFLAGS and
+ LDFLAGS. Also triggered nodots only for FreeBSD-3. Added
+ AC_DEFINE(_POSIX_PTHREAD_SEMANTICS) for Solaris.
+
+ * unix/tclUnixPort.h:
+ * unix/tclUnixThrd.c: added thread-safe versions of readdir,
+ localtime, gmtime and inet_ntoa for threaded build. (jgdavidson)
+
+ * generic/tclScan.c (Tcl_ScanObjCmd): prevented ckfree being called on
+ a pointer to NULL.
+
+2002-02-07 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/DString.3:
+ * doc/Encoding.3:
+ * doc/GetCwd.3:
+ * doc/SplitPath.3:
+ * doc/Translate.3:
+ * doc/Utf.3:
+ * generic/tcl.decls:
+ * generic/tcl.h:
+ * generic/tclEncoding.c:
+ * generic/tclEnv.c:
+ * generic/tclFileName.c:
+ * generic/tclIOUtil.c:
+ * generic/tclUtf.c:
+ * generic/tclUtil.c:
+ * mac/tclMacInit.c:
+ * unix/tclUnixFile.c:
+ * unix/tclUnixInit.c:
+ * unix/tclUnixPipe.c:
+ * win/tclWin32Dll.c:
+ * win/tclWinFCmd.c:
+ * win/tclWinFile.c:
+ * win/tclWinInit.c: Partial TIP 27 rollback. Following routines
+ restored to return (char *): Tcl_DStringAppend,
+ Tcl_DStringAppendElement, Tcl_JoinPath, Tcl_TranslateFileName,
+ Tcl_ExternalToUtfDString, Tcl_UtfToExternalDString,
+ Tcl_UniCharToUtfDString, Tcl_GetCwd, Tcl_WinTCharToUtf. Also restored
+ Tcl_WinUtfToTChar to return (TCHAR *) and Tcl_UtfToUniCharDString to
+ return (Tcl_UniChar *). Modified some callers. This change recognizes
+ that Tcl_DStrings are de-facto white-box objects.
+
+ * generic/tclDecls.h:
+ * generic/tclPlatDecls.h: make genstubs
+
+ * generic/tclCmdMZ.c: corrected use of C++-style comment.
+
+2002-02-06 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * tests/scan.test:
+ * generic/tclScan.c (Tcl_ScanObjCmd): corrected scan 0x... %x handling
+ that didn't accept the 0x as a prelude to a base 16 number. [Bug
+ 495213]
+
+ * generic/tclCompCmds.c (TclCompileRegexpCmd): made early check for
+ bad RE to stop checking further.
+
+ * generic/tclCmdMZ.c (Tcl_RegsubObjCmd): added special case to search
+ for simple 'string map' style regsub calls. Delayed creation of
+ resultPtr object until an initial match is made, as the input string
+ object can then be reused for no matches.
+ (Tcl_StringObjCmd): optimization improvements to the STR_MAP
+ algorithm for zero-length and nocase cases.
+
+ * tests/regexp.test:
+ * tests/regexpComp.test: extra code coverage tests.
+
+ * tests/string.test: added 10.18 and 10.19 extra tests.
+
+ * generic/regc_locale.c (casecmp): slight performance improvement.
+
+2002-02-05 Don Porter <dgp@users.sourceforge.net>
+
+ * library/http/http.tcl:
+ * library/http/pkgIndex.tcl: Corrected use of http::error when
+ ::error was intended. Bump to http 2.4.2.
+
+2002-02-04 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * unix/tclUnixChan.c (FileOutputProc): Fixed [bug 465765] reported by
+ Dale Talcott <daletalcott@users.sourceforge.net>. Avoid writing
+ nothing into a file as STREAM based implementations will consider this
+ a EOF (if the file is a pipe). Not done in the generic layer as this
+ type of writing is actually useful to check the state of a socket.
+
+ * doc/open.n: Fixed [Bug 511540], added cross-reference to 'pid' as
+ the command to use to retrieve the pid of a command pipeline created
+ via 'open'.
+
+2002-02-01 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclCmdMZ.c (Tcl_RegexpObjCmd): handle quirky about case
+ earlier to avoid shimmering problem.
+
+2002-02-01 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * tests/io.test: io-39.22 split into two tests, one platform
+ dependent, the other not. -eofchar is not empty on the windows
+ platform.
+
+2002-02-01 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclTest.c: fix to picky windows compiler problem with the
+ 'MainLoop' function declaration.
+
+2002-01-31 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * win/tclWinFCmd.c: TIP 27: Applied patch fixing CONST warnings on
+ behalf of Don Porter <dgp@users.sourceforge.net>.
+
+2002-01-30 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tcl.decls:
+ * generic/tcl.h:
+ * generic/tclInt.h: For each interface identified in the TIP 27
+ changes below as a POTENTIAL INCOMPATIBILITY, the source of the
+ incompatibility has been parameterized so that it can be removed. When
+ compiling extension code against the Tcl header files, use the
+ compiler flag -DUSE_NON_CONST to remove the irresolvable source
+ incompatibilities introduced by the TIP 27 changes. Resolvable changes
+ are left for extension authors to resolve.
+ * generic/tclDecls.h: make genstubs
+
+2002-01-30 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * doc/FileSystem.3: added documentation for 3 public functions which
+ had been overlooked. [Bug 507701]
+ * unix/mkLinks: make mklinks
+
+2002-01-29 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * tests/regexpComp.test:
+ * generic/tclCompCmds.c (TclCompileRegexpCmd): enhanced to support
+ -nocase and -- options.
+
+2002-01-28 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/tcl.m4 (SC_LOAD_TCLCONFIG):
+ * win/tcl.m4 (SC_LOAD_TCLCONFIG): Set TCL_LIB_SPEC, TCL_STUB_LIB_SPEC,
+ and TCL_STUB_LIB_PATH to the values of TCL_BUILD_LIB_SPEC,
+ TCL_BUILD_STUB_LIB_SPEC, and TCL_BUILD_STUB_LIB_PATH when tclConfig.sh
+ is loaded from the build directory. A Tcl extension should make use of
+ the non-build versions of these variables since they will work in both
+ cases. This modification was described in TIP 34.
+
+2002-01-28 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/tclWinReg.c (regConnectRegistryProc,RecursiveDeleteKey)
+ (DeleteKey,GetKeyNames,GetType,GetValue,OpenSubKey,SetValue):
+ redid the CONSTification as previous changes caused failing tests.
+
+ * tests/regexpComp.test (new):
+ * generic/tclInt.h:
+ * generic/tclBasic.c: added TclCompileRegexpCmd entry
+ * generic/tclCompCmds.c (TclCompileStringCmd): corrected to return
+ TCL_OUT_LINE_COMPILE instead of TCL_ERROR for parsing errors, so
+ it only throws the error for runtime compile, in case the user
+ modifies 'string'.
+ (TclCompileRegexpCmd): first try at a byte-compiled regexp command. It
+ handles static strings and ^$ bounded static strings.
+ (TclCompileAppendCmd): made TclPushVarName call always use
+ TCL_CREATE_VAR as numWords is always > 2 at that point.
+
+ * generic/tclExecute.c (TclExecuteByteCode:INST_LIST): correct
+ possibly dangerous decr in macro call.
+
+ * win/tclWinInit.c (TclpFindVariable): CONSTification touch-up
+
+ * win/tclWinReg.c (OpenSubKey): corrected bug introduced in
+ CONSTification that dropped pointer reference.
+
+ * ChangeLog.2000 (new file):
+ * ChangeLog: broke changes from 2000 into ChangeLog.2000 to reduce
+ size of the main ChangeLog.
+
+2002-01-28 David Gravereaux <davygrvy@pobox.com>
+
+ * generic/tclPlatDecls.h: Added preprocessor logic to force a
+ typedef of TCHAR when __STDC__ is defined when using the uncommon
+ -Za compiler switch with the microsoft compiler.
+
+2002-01-27 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/package.n: Documented global namespace context for script
+ evaluation by [package require].
+
+2002-01-27 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tclInt.decls:
+ * generic/tclIntPlatDecls.h:
+ * mac/tclMacChan.c:
+ * mac/tclMacFCmd.c:
+ * mac/tclMacFile.c:
+ * mac/tclMacInit.c:
+ * mac/tclMacLoad.c:
+ * mac/tclMacResource.c:
+ * mac/tclMacSock.c: TIP 27 CONSTification induced changes
+
+ * tests/event.test:
+ * tests/main.test: added catches/constraints to test that
+ use features that don't exist on the mac.
+
+2002-01-25 Mo DeJong <mdejong@users.sourceforge.net>
+
+ Make -eofchar and -translation options read only for server sockets.
+ [Bug 496733]
+
+ * generic/tclIO.c (Tcl_GetChannelOption, Tcl_SetChannelOption):
+ Instead of returning nothing for the -translation option on a server
+ socket, always return "auto". Return the empty string enclosed in
+ quotes for the -eofchar option on a server socket. Fixup -eofchar
+ usage message so that it matches the implementation.
+ * tests/io.test: Add -eofchar tests and -translation tests to ensure
+ options are read only on server sockets.
+ * tests/socket.test: Update tests to account for -eofchar and
+ -translation option changes.
+
+2002-01-25 Don Porter <dgp@users.sourceforge.net>
+
+ * compat/strstr.c (strstr):
+ * generic/tclCmdAH.c (Tcl_FormatObjCmd):
+ * generic/tclCmdIL.c (InfoNameOfExecutableCmd):
+ * generic/tclEnv.c (ReplaceString):
+ * generic/tclFileName.c (ExtractWinRoot):
+ * generic/tclIO.c (FlushChannel,Tcl_BadChannelOption):
+ * generic/tclStringObj.c (AppendUnicodeToUtfRep):
+ * generic/tclThreadTest.c (TclCreateThread):
+ * generic/tclUtf.c (Tcl_UtfPrev):
+ * mac/tclMacFCmd.c (TclpObjListVolumes):
+ * mac/tclMacResource.c (TclMacRegisterResourceFork,
+ (BuildResourceForkList):
+ * win/tclWinInit.c (AppendEnvironment): Sought out and eliminated
+ instances of CONST-casting that are no longer needed after the
+ TIP 27 effort.
+
+ * Following is [Patch 501006]
+ * generic/tclInt.decls (Tcl_AddInterpResolvers, Tcl_Export,
+ (Tcl_FindNamespace, Tcl_GetInterpResolvers, Tcl_ForgetImport,
+ (Tcl_Import, Tcl_RemoveInterpResolvers):
+ * generic/tclNamesp.c (Tcl_Export, Tcl_Import, Tcl_ForgetImport,
+ (Tcl_FindNamespace):
+ * generic/tclResolve.c (Tcl_AddInterpResolvers,Tcl_GetInterpResolvers,
+ (Tcl_RemoveInterpResolvers): Updated APIs in generic/tclResolve.c and
+ generic/tclNamesp.c according to the guidelines of TIP 27.
+ * generic/tclIntDecls.h: make genstubs
+
+ * Following is [Patch 505630]
+ * doc/AddErrorInfo.3:
+ * generic/tcl.decls (Tcl_LogCommandInfo):
+ * generic/tclBasic.c (Tcl_LogCommandInfo): Updated interfaces
+ of generic/tclBasic.cc according to TIP 27.
+ * generic/tclDecls.h: make genstubs
+
+ * Following is [Patch 506818]
+ * doc/Hash.3:
+ * generic/tcl.decls (Tcl_HashStats):
+ * generic/tclHash.c (Tcl_HashStats): Updated APIs of generic/tclHash.c
+ according to guidelines of TIP 27.
+ * generic/tclDecls.h: make genstubs
+ * generic/tclVar.c (Tcl_ArrayObjCmd): Updated callers.
+
+ * Following is [Patch 506807]
+ * doc/ObjectType.3:
+ * generic/tcl.decls (Tcl_GetObjType):
+ * generic/tclObj.c (Tcl_GetObjType): Updated APIs of generic/tclObj.c
+ according to guidelines of TIP 27.
+ * generic/tclDecls.h: make genstubs
+
+ * Following is [Patch 507304]
+ * doc/Encoding.3:
+ * generic/tcl.decls (Tcl_WinUtfToTChar,Tcl_WinTCharToUtf):
+ * win/tclWin32Dll.c (Tcl_WinUtfToTChar,Tcl_WinTCharToUtf):
+ Updated interfaces in win/tclWin32Dll.c according to TIP 27.
+ * generic/tclPlatDecls.h: make genstubs
+ * generic/tclIOUtil.c (TclpNativeToNormalized):
+ * win/tclWinFCmd.c (TclpObjNormalizePath):
+ * win/tclWinFile.c (TclpFindExecutable,TclpMatchInDirectory,
+ (NativeIsExec,NativeStat):
+ * win/tclWinLoad.c (TclpLoadFile):
+ * win/tclWinPipe.c (TclpOpenFile,ApplicationType):
+ * win/tclWinReg.c (regConnectRegistryProc,RecursiveDeleteKey,DeleteKey,
+ (GetKeyNames,GetType,GetValue,OpenSubKey,SetValue):
+ * win/tclWinSerial.c (SerialSetOptionProc): Update callers.
+
+ * Following is [Patch 505072]
+ * doc/Concat.3:
+ * doc/Encoding.3:
+ * doc/Filesystem.3:
+ * doc/Macintosh.3:
+ * doc/OpenFileChnl.3
+ * doc/SetResult.3:
+ * doc/SetVar.3:
+ * doc/SplitList.3:
+ * doc/SplitPath.3:
+ * doc/Translate.3:
+ * generic/tcl.h (Tcl_FSMatchInDirectoryProc):
+ * generic/tclInt.h (TclpMatchInDirectory):
+ * generic/tcl.decls (Tcl_Concat,Tcl_GetStringResult,Tcl_GetVar,
+ (Tcl_GetVar2,Tcl_JoinPath,Tcl_Merge,Tcl_OpenCommandChannel,Tcl_SetVar,
+ (Tcl_SetVar2,Tcl_SplitList,Tcl_SplitPath,Tcl_TranslateFileName,
+ (Tcl_ExternalToUtfDString,Tcl_GetEncodingName,Tcl_UtfToExternalDString,
+ (Tcl_GetDefaultEncodingDir,Tcl_SetDefaultEncodingDir,
+ (Tcl_FSMatchInDirectory,Tcl_MacEvalResource,Tcl_MacFindResource):
+ * generic/tclInt.decls (TclCreatePipeline,TclGetEnv,TclpGetCwd,
+ (TclpCreateProcess):
+ * mac/tclMacFile.c (TclpGetCwd):
+ * generic/tclEncoding.c (Tcl_GetDefaultEncodingDir,
+ (Tcl_SetDefaultEncodingDir,Tcl_GetEncodingName,
+ (Tcl_ExternalToUtfDString,Tcl_UtfToExternalDString, OpenEncodingFile,
+ (LoadEscapeEncoding):
+ * generic/tclFileName.c (DoTildeSubst,Tcl_JoinPath,Tcl_SplitPath,
+ (Tcl_TranslateFileName):
+ * generic/tclIOUtil.c (Tcl_FSMatchInDirectory):
+ * generic/tclPipe.c (FileForRedirect,TclCreatePipeline,
+ (Tcl_OpenCommandChannel):
+ * generic/tclResult.c (Tcl_GetStringResult):
+ * generic/tclUtil.c (Tcl_Concat,Tcl_SplitList,Tcl_Merge):
+ * generic/tclVar.c (Tcl_GetVar,Tcl_GetVar2,Tcl_SetVar,Tcl_SetVar2):
+ * mac/tclMacResource.c (Tcl_MacEvalResource,Tcl_MacFindResource):
+ Updated interfaces of generic/tclEncoding, generic/tclFilename.c,
+ generic/tclIOUtil.c, generic/tclPipe.c, generic/tclResult.c,
+ generic/tclUtil.c, generic/tclVar.c and mac/tclMacResource.c according
+ to TIP 27. Tcl_TranslateFileName rewritten as wrapper around VFS-aware
+ version.
+ ***POTENTIAL INCOMPATIBILITY***
+ Includes source incompatibilities: argv arguments of Tcl_Concat,
+ Tcl_JoinPath, Tcl_OpenCommandChannel, Tcl_Merge; argvPtr arguments of
+ Tcl_SplitList and Tcl_SplitPath.
+ * generic/tclDecls.h:
+ * generic/tclIntDecls.h: make genstubs
+
+ * generic/tclCkalloc.c (MemoryCmd):
+ * generic/tclClock.c (FormatClock):
+ * generic/tclCmdAH.c (Tcl_CaseObjCmd,Tcl_EncodingObjCmd,Tcl_FileObjCmd):
+ * generic/tclCmdIL.c (InfoLibraryCmd,InfoPatchLevelCmd,
+ (InfoTclVersionCmd):
+ * generic/tclCompCmds.c (TclCompileForeachCmd):
+ * generic/tclCompCmds.h (TclCompileForeachCmd):
+ * generic/tclCompile.c (TclFindCompiledLocal):
+ * generic/tclEnv.c (TclSetupEnv,TclSetEnv,Tcl_PutEnv,TclGetEnv,
+ (EnvTraceProc):
+ * generic/tclEvent.c (Tcl_BackgroundError):
+ * generic/tclIO.c (Tcl_BadChannelOption,Tcl_SetChannelOption):
+ * generic/tclIOCmd.c (Tcl_ExecObjCmd,Tcl_OpenObjCmd):
+ * generic/tclIOSock.c (TclSockGetPort):
+ * generic/tclIOUtil.c (SetFsPathFromAny):
+ * generic/tclLink.c (LinkTraceProc):
+ * generic/tclMain.c (Tcl_Main):
+ * generic/tclNamesp.c (TclTeardownNamespace):
+ * generic/tclProc.c (TclCreateProc):
+ * generic/tclTest.c (TestregexpObjCmd,TesttranslatefilenameCmd,
+ (TestchmodCmd,GetTimesCmd,TestsetCmd,TestOpenFileChannelProc1,
+ (TestOpenFileChannelProc2,TestOpenFileChannelProc3,AsyncHandlerProc,
+ (TestpanicCmd):
+ * generic/tclThreadTest.c (ThreadErrorProc,ThreadEventProc):
+ * generic/tclUtil.c (TclPrecTraceProc):
+ * mac/tclMacFCmd.c (GetFileSpecs):
+ * mac/tclMacFile.c (TclpMatchInDirectory):
+ * mac/tclMacInit.c (TclpInitLibraryPath,Tcl_SourceRCFile):
+ * mac/tclMacOSA.c (tclOSAStore,tclOSALoad):
+ * mac/tclMacResource.c (Tcl_MacEvalResource):
+ * unix/tclUnixFCmd.c (TclpObjNormalizePath):
+ * unix/tclUnixFile.c (TclpMatchInDirectory,TclpGetUserHome,TclpGetCwd,
+ (TclpReadLink):
+ * unix/tclUnixInit.c (TclpInitLibraryPath,TclpSetVariables,
+ (Tcl_SourceRCFile):
+ * unix/tclUnixPipe.c (TclpOpenFile,TclpCreateTempFile,
+ (TclpCreateProcess):
+ * win/tclWinFile.c (TclpGetCwd,TclpMatchInDirectory):
+ * win/tclWinInit.c (TclpInitLibraryPath,Tcl_SourceRCFile,
+ (TclpSetVariables):
+ * win/tclWinPipe.c (TclpCreateProcess): Updated callers.
+
+2002-01-24 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclIOUtil.c (SetFsPathFromAny): Corrected tilde-substitution
+ of pathnames where > 1 separator follows the ~. [Bug 504950]
+
+2002-01-24 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * library/http/pkgIndex.tcl:
+ * library/http/http.tcl: don't add port in default case to handle
+ broken servers. http bumped to 2.4.1 [Bug 504508]
+
+2002-01-23 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * unix/mkLinks: Regenerated.
+ * doc/CrtChannel.3:
+ * doc/ChnlStack.3: Moved documentation for 'Tcl_GetTopChannel' from
+ 'CrtChannel' to 'ChnlStack'. Added documentation of
+ 'Tcl_GetStackedChannel'. [Bug 506147] reported by Mark Patton
+ <msp@users.sourceforge.net>.
+
+2002-01-23 Don Porter <dgp@users.sourceforge.net>
+
+ * win/tclWinFile.c (NativeAccess,NativeStat,NativeIsExec,
+ (TclpGetUserHome):
+ * win/tclWinPort.h (TclWinSerialReopen):
+ * win/tclWinSerial.c (TclWinSerialReopen):
+ * win/tclWinSock.c (Tcl_OpenTcpServer): Corrections to earlier TIP 27
+ changes. Thanks to Andreas Kupries for the feedback.
+ * generic/tclPlatDecls.h: make genstubs
+
+ * doc/GetHostName.3:
+ * doc/GetOpnFl.3:
+ * doc/OpenTcp.3:
+ * tcl.decls (Tcl_GetHostName,Tcl_GetOpenFile,Tcl_OpenTcpClient,
+ (Tcl_OpenTclServer):
+ * mac/tclMacSock.c (CreateSocket,Tcl_OpenTcpClient,Tcl_OpenTcpServer,
+ (Tcl_GetHostName,GetHostFromString):
+ * unix/tclUnixChan.c (CreateSocket,CreateSocketAddress,
+ (Tcl_OpenTcpClient,Tcl_OpenTcpServer,Tcl_GetOpenFile):
+ * unix/tclUnixSock.c (Tcl_GetHostName):
+ * win/tclWinSock.c (CreateSocket,CreateSocketAddress,
+ (Tcl_OpenTcpClient,Tcl_OpenTcpServer,Tcl_GetHostName):
+ Updated socket interfaces according to TIP 27.
+ * generic/tclCmdIL.c (InfoHostnameCmd): Updated callers.
+ * generic/tclDecls.h: make genstubs
+
+2002-01-21 David Gravereaux <davygrvy@pobox.com>
+
+ * generic/tclLoadNone.c: TclpLoadFile() didn't match proto of typedef
+ Tcl_FSLoadFileProc. OK'd by vincentdarley. [Patch 502488]
+
+2002-01-21 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * generic/tclIO.c (WriteChars): Fix for [Bug 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.
+
+2002-01-21 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclTest.c: Converted declarations of TestReport file system
+ to more portable form. [Bug 501417]
+
+ * generic/tcl.decls (Tcl_TraceCommand,Tcl_UntraceCommand,
+ (Tcl_CommandTraceInfo):
+ * generic/tclCmdMZ.c (Tcl_TraceCommand,Tcl_UntraceCommand,
+ (Tcl_CommandTraceInfo): Updated APIs in generic/tclCmdMZ.c according
+ to the guidelines of TIP 27.
+ * generic/tclDecls.h: make genstubs
+
+2002-01-18 Don Porter <dgp@users.sourceforge.net>
+
+ * win/tclWinChan.c:
+ * win/tclWinFCmd.c:
+ * win/tclWinFile.c: Overlooked callers of Tcl_FSGetNativePath
+
+ * win/tclWinDde.c:
+ * win/tclWinReg.c: Overlooked callers of Tcl_GetIndexFromObj
+
+2002-01-18 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tclThreadTest.c:
+ * mac/tclMacChan.c:
+ * mac/tclMacFCmd.c:
+ * mac/tclMacFile.c:
+ * mac/tclMacLoad.c:
+ * mac/tclMacResource.c: TIP 27 CONSTification broke the mac build in a
+ number of places.
+
+2002-01-17 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * generic/tclIOCmd.c (Tcl_GetsObjCmd): Fixed [Bug 504642] as reported
+ by Brian Griffin <bgriffin@users.sourceforge.net>, using his
+ patch. Before the patch the generic I/O layer held an unannounced
+ reference to the interp result to store the read line into. This
+ unfortunately has disastrous results if the channel driver executes a
+ tcl script to perform its operation, this freeing the interp
+ result. In that case we are dereferencing essentially a dangling
+ reference. It is not truly dangling because the object is in the free
+ list, but this only causes us to smash the free list and have the
+ error occur later somewhere else. The patch simply creates a new
+ object for the line and later sets it into the interp result when we
+ are done with reading.
+
+2002-01-16 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/tcl.m4 (SC_LOAD_TCLCONFIG):
+ * win/tcl.m4 (SC_LOAD_TCLCONFIG): Subst TCL_DBGX into
+ TCL_STUB_LIB_FILE and TCL_STUB_LIB_FLAG variables so that an extension
+ does not need to subst TCL_DBGX into its makefile. [Tk Bug 504356]
+
+2002-01-16 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/FileSystem.3:
+ * doc/GetCwd.3:
+ * doc/GetIndex.3:
+ * generic/tcl.decls (Tcl_GetIndexFromObj, Tcl_GetIndexFromObjStruct,
+ (Tcl_GetCwd, Tcl_FSFileAttrStrings, Tcl_FSGetNativePath,
+ (Tcl_FSGetTranslatedStringPath):
+ * generic/tcl.h (Tcl_FSFileAttrStringsProc):
+ * generic/tclFCmd.c (TclFileAttrsCmd):
+ * generic/tclIOUtil.c (Tcl_GetCwd,NativeFileAttrStrings,
+ (Tcl_FSFileAttrStrings,Tcl_FSGetTranslatedStringPath,
+ (Tcl_FSGetNativePath):
+ * generic/tclIndexObj.c (Tcl_GetIndexFromObj,
+ (Tcl_GetIndexFromObjStruct):
+ More TIP 27 updates in tclIOUtil.c and tclIndexObj.c that were
+ overlooked before. [Patch 504671]
+ ***POTENTIAL INCOMPATIBILITY***
+ Includes a source incompatibility in the tablePtr arguments of the
+ Tcl_GetIndexFromObj* routines.
+ * generic/tclDecls.h: make genstubs
+
+ * generic/tclBinary.c (Tcl_BinaryObjCmd):
+ * generic/tclClock.c (Tcl_ClockObjCmd):
+ * generic/tclCmdAH.c (Tcl_EncodingObjCmd, Tcl_FileObjCmd):
+ * generic/tclCmdIL.c (Tcl_InfoObjCmd,Tcl_LsearchObjCmd,Tcl_LsortObjCmd):
+ * generic/tclCmdMZ.c (Tcl_TraceObjCmd,Tcl_RegexpObjCmd,Tcl_RegsubObjCmd,
+ (Tcl_StringObjCmd,Tcl_SubstObjCmd,Tcl_SwitchObjCmd,
+ (TclTraceCommandObjCmd,TclTraceVariableObjCmd):
+ * generic/tclCompCmds.c (TclCompileStringCmd):
+ * generic/tclEvent.c (Tcl_UpdateObjCmd):
+ * generic/tclFileName.c (Tcl_GlobObjCmd):
+ * generic/tclIO.c (Tcl_FileEventObjCmd):
+ * generic/tclIOCmd.c (Tcl_SeekObjCmd,Tcl_ExecObjCmd,Tcl_SocketObjCmd,
+ (Tcl_FcopyObjCmd):
+ * generic/tclInterp.c (Tcl_InterpObjCmd,SlaveObjCmd):
+ * generic/tclNamesp.c (Tcl_NamespaceObjCmd):
+ * generic/tclPkg.c (Tcl_PackageObjCmd):
+ * generic/tclTest.c (Tcltest_Init,TestencodingObjCmd,TestgetplatformCmd,
+ (TestlocaleCmd,TestregexpObjCmd,TestsaveresultCmd,
+ (TestGetIndexFromObjStructObjCmd,TestReportFileAttrStrings):
+ * generic/tclTestObj.c (TestindexObjCmd,TeststringObjCmd):
+ * generic/tclTimer.c (Tcl_AfterObjCmd):
+ * generic/tclVar.c (Tcl_ArrayObjCmd):
+ * mac/tclMacFCmd.c (SetFileFinderAttributes):
+ * unix/tclUnixChan.c (TclpOpenFileChannel):
+ * unix/tclUnixFCmd.c (tclpFileAttrStrings):
+ * unix/tclUnixFile.c (TclpObjAccess,TclpObjChdir,TclpObjStat,
+ (TclpObjLstat):
+ * win/tclWinFCmd.c (tclpFileAttrStrings): Updated callers.
+
+ * doc/RegExp.3:
+ * doc/Utf.3:
+ * generic/tcl.decls:
+ * generic/tclInt.decls:
+ * generic/tclRegexp.c:
+ * generic/tclUtf.c: Updated APIs in generic/tclUtf.c and
+ generic/tclRegexp.c according to the guidelines of TIP 27.
+ [Patch 471509]
+
+ * generic/regc_locale.c (element,cclass):
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd):
+ * generic/tclFileName.c (TclpGetNativePathType,SplitMacPath):
+ * generic/tclIO.c (ReadChars):
+ * mac/tclMacLoad.c (TclpLoadFile):
+ * win/tclWinFile.c (TclpGetUserHome): Updated callers.
+
+ * generic/tclDecls.h:
+ * generic/tclIntDecls.h: make genstubs
+
+ * doc/ParseCmd.3 (Tcl_ParseVar):
+ * generic/tcl.decls (Tcl_ParseVar):
+ * generic/tclParse.c (Tcl_ParseVar):
+ * generic/tclTest.c (TestparsevarObjCmd): Updated APIs in
+ generic/tclParse.c according to the guidelines of TIP 27. Updated
+ callers. [Patch 501046]
+ * generic/tclDecls.h: make genstubs
+
+ * generic/tcl.decls (Tcl_RecordAndEval):
+ * generic/tclDecls.h: make genstubs
+ * generic/tclHistory.c (Tcl_RecordAndEval): Updated APIs in
+ generic/tclHistory.c according to the guidelines of TIP 27.
+ [Patch 504091]
+
+ * doc/CrtSlave.3:
+ * generic/tcl.decls (Tcl_CreateAlias, Tcl_CreateAliasObj,
+ (Tcl_CreateSlave, Tcl_GetAlias, Tcl_GetAliasObj, Tcl_GetSlave):
+ * generic/tclInterp.c (Tcl_CreateAlias, Tcl_CreateAliasObj,
+ (Tcl_CreateSlave, Tcl_GetAlias, Tcl_GetAliasObj, Tcl_GetSlave):
+ Updated APIs in the file generic/tclInterp.c according to the
+ guidelines of TIP 27. [Patch 501371]
+ ***POTENTIAL INCOMPATIBILITY***
+ Includes a source incompatibility in the targetCmdPtr arguments of the
+ Tcl_GetAlias* routines.
+
+ * generic/tclDecls.h: make genstubs
+
+2002-01-15 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/SetErrno.3 (Tcl_ErrnoMsg): Corrected documentation for
+ Tcl_ErrnoMsg; it takes an integer argument. Thanks to Georgios
+ Petasis. [Bug 468183]
+
+ * doc/AddErrInfo.3 (Tcl_PosixError):
+ * doc/Eval.3 (Tcl_EvalFile):
+ * doc/FileSystem.c (Tcl_FSOpenFileChannel,Tcl_FSOpenFileChannelProc):
+ * doc/OpenFileChnl.3 (Tcl_OpenFileChannel):
+ * doc/SetErrno.3 (Tcl_ErrnoId,Tcl_ErrnoMsg):
+ * doc/Signal.3 (Tcl_SignalId,Tcl_SignalMsg):
+ * generic/tcl.decls (Tcl_ErrnoId,TclErrnoMsg,Tcl_EvalFile,
+ (Tcl_OpenFileChannel,Tcl_PosixError,Tcl_SignalId,Tcl_SignalMsg,
+ (Tcl_FSOpenFileChannel):
+ * generic/tcl.h (Tcl_FSOpenFileChannelProc):
+ * generic/tclIO.c (FlushChannel):
+ * generic/tclIOUtil.c (Tcl_OpenFileChannel,Tcl_EvalFile,TclGetOpenMode,
+ (Tcl_PosixError,Tcl_FSOpenFileChannel):
+ * generic/tclInt.decls (TclGetOpenMode):
+ * generic/tclInt.h (TclOpenFileChannelProc_,TclGetOpenMode,
+ (TclpOpenFileChannel):
+ * generic/tclPipe.c (TclCleanupChildren):
+ * generic/tclPosixStr.c (Tcl_ErrnoId,Tcl_ErrnoMsg,Tcl_SignalId,
+ (Tcl_SignalMsg):
+ * generic.tclTest.c (PretendTclpOpenFileChannel,
+ (TestOpenFileChannelProc1,TestOpenFileChannelProc2,
+ (TestOpenFileChannelProc3,TestReportOpenFileChannel):
+ * mac/tclMacChan.c (TclpOpenFileChannel):
+ * unix/tclUnixChan.c (TclpOpenFileChannel):
+ * win/tclWinChan.c (TclpOpenFileChannel): Updated APIs in
+ generic/tclIOUtil.c and generic/tclPosixStr.c according to the
+ guidelines of TIP 27. Updated callers. [Patch 499196]
+
+ * generic/tclDecls.h:
+ * generic/tclIntDecls.h: make genstubs
+
+ * doc/CrtChannel.3:
+ * doc/OpenFileChnl.3:
+ * generic/tcl.decls:
+ * generic/tclIO.h:
+ * generic/tclIO.c (DoWrite, Tcl_RegisterChannel, Tcl_GetChannel,
+ (Tcl_CreateChannel, Tcl_GetChannelName, CloseChannel, Tcl_Write,
+ (Tcl_WriteRaw, Tcl_Ungets, Tcl_BadChannelOption, Tcl_GetChannelOption,
+ (Tcl_SetChannelOption, Tcl_GetChannelNamesEx, Tcl_ChannelName):
+ Updated APIs in the file generic/tclIO.c according to the guidelines
+ of TIP 27. Several minor documentation corrections as well.
+ [Patch 503565]
+ * generic/tclDecls.h: make genstubs
+
+ * generic/tcl.h (Tcl_DriverOutputProc, Tcl_DriverGetOptionProc,
+ (Tcl_DriverSetOptionProc):
+ * generic/tclIOGT.c (TransformOutputProc, TransformGetOptionProc,
+ (TransformSetOptionProc):
+ * mac/tclMacChan.c (FileOutput, StdIOOutput):
+ * man/tclMacSock.c (TcpGetOptionProc, TcpOutput):
+ * unix/tclUnixChan.c (FileOutputProc, TcpGetOptionProc, TcpOutputProc,
+ (TtyGetOptionProc, TtySetOptionProc):
+ * unix/tclUnixPipe.c (PipeOuputProc):
+ * win/tclWinChan.c (FileOutputProc):
+ * win/tclWinConsole.c (ConsleOutputProc):
+ * win/tclWinPipe.c (PipeOuputProc):
+ * win/tclWinSerial.c (SerialOutputProc, SerialGetOptionProc,
+ (SerialSetOptionProc):
+ * win/tclWinSock.c (TcpGetOptionProc, TcpOutput): Updated channel
+ driver interface according to the guidelines of TIP 27. See also
+ [Bug 500348].
+
+ * doc/CrtChannel.3:
+ * generic/tcl.h:
+ * generic/tclIO.c:
+ * generic/tclIO.h:
+ * generic/tclInt.h:
+ * tools/checkLibraryDoc.tcl:
+ Moved Tcl_EolTranslation enum declaration from generic/tcl.h to
+ generic/tclInt.h (renamed to TclEolTranslation). It is not used
+ anywhere in Tcl's public interface.
+
+2002-01-14 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/GetIndex.3:
+ * doc/WrongNumArgs.3:
+ * generic/tcl.decls (Tcl_GetIndexFromObj, Tcl_GetIndexFromObjStruct,
+ (Tcl_WrongNumArgs):
+ * generic/tclIndexObj.c (Tcl_GetIndexFromObj,Tcl_GetIndexFromObjStruct,
+ (Tcl_WrongNumArgs): Updated APIs in the file generic/tclIndexObj.c
+ according to the guidelines of TIP 27. [Patch 501491]
+ * generic/tclDecls.h: make genstubs
+
+2002-01-11 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/configure: Regen.
+ * unix/configure.in:
+ * win/configure: Regen.
+ * win/configure.in: Use ${libdir} instead of ${exec_prefix}/lib
+ to properly support the --libdir option to configure. [Bug 489370]
+
+2002-01-11 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+ * win/tclWinSerial.c (SerialSetOptionProc): Applied patch for [Bug
+ 500348] supplied by Rolf Schroedter <schroedter@users.sf.net>. The
+ function modified the contents of the the 'value' string and now does
+ not do this anymore. This is a followup to the change made on
+ 2001-12-17.
+
+2002-01-11 David Gravereaux <davygrvy@pobox.com>
+
+ * win/makefile.vc: Removed -GD compiler option. It was intended for
+ future use, but MS is again changing the future at their whim. The
+ D4002 warning was harmless though, but someone using VC .NET logged it
+ as a concern. [Bug 501565]
+
+2002-01-11 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/Makefile.in: Burn Tcl build directory into tcltest executable
+ to avoid crashes caused by ld loading a previously installed version
+ of the tcl shared library. [Bug 218110]
+
+2002-01-10 Don Porter <dgp@users.sourceforge.net>,
+ Kevin Kenny <kennykb@users.sourceforge.net>
+
+ * unix/tclLoadDld.c (TclpLoadFile): syntax error: unbalanced parens.
+ Kevin notes that it's far from clear that this file is ever included
+ in an actual build; Linux without dlopen appears to be a nonexistent
+ configuration.
+
+2002-01-08 Don Porter <dgp@users.sourceforge.net>,
+ Kevin Kenny <kennykb@users.sourceforge.net>
+
+ * doc/StaticPkg.3 (Tcl_StaticPackage):
+ * generic/tcl.decls (Tcl_StaticPackage):
+ * generic/tclDecls.h (Tcl_StaticPackage):
+ * generic/tclInt.decls (TclGuessPackageName):
+ * generic/tclInt.h (TclGuessPackageName):
+ * generic/tclLoad.c (Tcl_StaticPackage):
+ * generic/tclLoadNone.c (TclGuessPackageName):
+ * mac/tclMacLoad.c (TclGuessPackageName):
+ * unix/tclLoadAout.c (TclGuessPackageName):
+ * unix/tclLoadDl.c (TclGuessPackageName):
+ * unix/tclLoadDld.c (TclGuessPackageName):
+ * unix/tclLoadDyld.c (TclGuessPackageName):
+ * unix/tclLoadNext.c (TclGuessPackageName):
+ * unix/tclLoadOSF.c (TclGuessPackageName):
+ * unix/tclLoadShl.c (TclGuessPackageName):
+ * win/tclWinLoad.c (TclGuessPackageName): Updated APIs in the files
+ */tcl*Load*.c according to the guidelines of TIP 27. [Patch 501096]
+
+2002-01-09 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclTest.c (MainLoop):
+ * tests/main.test (Tcl_Main-1.{3,4,5,6}): Corrected some non-portable
+ tests from the new Tcl_Main changes. Thanks to Kevin Kenny.
+
+2002-01-07 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclEvent.c (TclInExit):
+ * generic/tclIOUtil.c (SetFsPathFromAbsoluteNormalized,
+ (SetFsPathFromAny,Tcl_FSNewNativePath,DupFsPathInternalRep):
+ * generic/tclListObj.c (TclLsetList,TclLsetFlat): Added some type
+ casts to satisfy picky compilers.
+
+ * generic/tclMain.c: Bug fix: neglected the NULL case in
+ TclGetStartupScriptFileName(). Broke Tk/wish.
+
+2002-01-05 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/Tcl_Main.3:
+ * generic/tclMain.c: Substantial rewrite and expanded documentation
+ of Tcl_Main to correct a number of bugs and flaws:
+
+ - Interactive Tcl_Main can now enter a main loop, exit that loop and
+ continue interactive operations. The loop may even exit in the
+ midst of interactive command typing without loss of the partial
+ command. [Bugs 486453, 474131]
+ - Tcl_Main now gracefully handles deletion of its master
+ interpreter.
+ - Interactive Tcl_Main can now operate with non-blocking stdin
+ - Interactive Tcl_Main can now detect EOF on stdin even in
+ mid-command. [Bug 491341]
+ - Added VFS-aware internal routines for managing the startup script
+ selection.
+ - Tcl variable 'tcl_interactive' is now linked to C variable 'tty'
+ so that one can disable/enable interactive prompts at the script
+ level when there is no startup script. This is meant for use by
+ the test suite.
+ - Consistent use of the Tcl libraries standard channels as returned
+ by Tcl_GetStdChannel(); as opposed to the channels named 'stdin',
+ 'stdout', and 'stderr' in the master interp, which can be
+ different or unavailable.
+ - Tcl_Main now calls Tcl_Exit() if evaluation of [exit] in the
+ master interpreter returns, assuring Tcl_Main does not return.
+ - Documented Tcl_Main's absence from public stub table
+ - Documented that Tcl_Main does not return.
+ - Documented Tcl variables set by Tcl_Main.
+ - All prompts are done from a single procedure, Prompt.
+ - Use of Tcl_Obj-enabled interfaces everywhere.
+
+ * generic/tclInt.decls (TclGetStartupScriptPath,
+ (TclSetStartupScriptPath): New internal VFS-aware routines for
+ managing the startup script of Tcl_Main.
+ * generic/tclIntDecls.h:
+ * generic/tclStubInit.c: make genstubs
+
+ * generic/tclTest.c (TestsetmainloopCmd,TestexitmainloopCmd,
+ (Tcltest_Init,TestinterpdeleteCmd):
+ * tests/main.test (new): Added new file to test suite that thoroughly
+ tests generic/tclMain.c; added some new test commands for testing
+ Tcl_SetMainLoop().
+
+2002-01-04 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/Alloc.3:
+ * doc/Concat.3:
+ * doc/CrtMathFnc.3:
+ * doc/Hash.3:
+ * doc/Interp.3:
+ * doc/LinkVar.3:
+ * doc/ObjectType.3:
+ * doc/PkgRequire.3:
+ * doc/Preserve.3:
+ * doc/SetResult.3:
+ * doc/SplitList.3:
+ * doc/SplitPath.3:
+ * doc/TCL_MEM_DEBUG.3: Updated documentation to describe the ckalloc,
+ ckfree, ckrealloc, attemptckalloc, and attemptckrealloc macros, and
+ to accurately describe when and how they are used. [Bug 497459]
+
+ * generic/tclThreadJoin.c (TclRememberJoinableThread,TclJoinThread):
+ Replaced Tcl_Alloc and Tcl_Free calls with ckalloc and ckfree so that
+ memory debugging is supported.
+
+2002-01-04 Daniel Steffen <das@users.sourceforge.net>
+
+ * mac/tclMacTime.c (TclpGetTZName): fix for daylight savings TZName bug
+
+2002-01-03 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/FileSystem.3:
+ * generic/tclIOUtil.c: Updated some old uses of "fileName" to
+ new VFS terminology, "pathPtr".
+
+2002-01-03 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * tests/basic.test (basic-39.4): Greatly simplified test while
+ still leaving it so that it crashes when run without the fix to
+ the [foreach] implementation.
+ * generic/tclCmdAH.c (Tcl_ForeachObjCmd): Stopped [Bug 494348] from
+ happening by not trying to be so clever with cacheing; if nothing
+ untoward is happening anyway, the less efficient technique will
+ only add a few instruction cycles (one function call and a few
+ derefs/assigns per list per iteration, with no change in the
+ number of tests) and if something odd *is* going on, the code is
+ now far more robust.
+
+ * tests/basic.test (basic-39.4): Reproducable script from [Bug 494348]
+
+2002-01-02 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * tests/util.test (Wrapper_Tcl_StringMatch,util-5.*): Rewrote so the
+ test is performed with the right internal function since [string
+ match] no longer uses Tcl_StringCaseMatch internally.
+
+ * tests/string.test (string-11.51):
+ * generic/tclUtf.c (Tcl_UniCharCaseMatch):
+ * generic/tclUtil.c (Tcl_StringCaseMatch): Fault with matching
+ case-insensitive non-ASCII patterns containing upper case characters.
+ [Bug 233257]
+
+ ******************************************************************
+ *** 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.2003 b/ChangeLog.2003
new file mode 100644
index 0000000..b12cd2c
--- /dev/null
+++ b/ChangeLog.2003
@@ -0,0 +1,3349 @@
+2003-12-25 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/tclWin32Dll.c (DllMain): Add HAVE_NO_SEH blocks in place of
+ __try and __except statements to support gcc builds. This is needed
+ after David's changes on 2003-12-21. [Patch 858493]
+
+2003-12-23 David Gravereaux <davygrvy@pobox.com>
+
+ * generic/tclAlloc.c: All uses of 'panic' (the macro) changed to
+ * generic/tclBasic.c: 'Tcl_Panic' (the function). The #define of
+ * generic/tclBinary.c: panic in tcl.h clearly states it is deprecated
+ * generic/tclCkalloc.c: in the comments. [Patch 865264]
+ * generic/tclCmdAH.c:
+ * generic/tclCmdIL.c:
+ * generic/tclCmdMZ.c:
+ * generic/tclCompCmds.c:
+ * generic/tclCompExpr.c:
+ * generic/tclCompile.c:
+ * generic/tclConfig.c:
+ * generic/tclDictObj.c:
+ * generic/tclEncoding.c:
+ * generic/tclEvent.c:
+ * generic/tclExecute.c:
+ * generic/tclHash.c:
+ * generic/tclInterp.c:
+ * generic/tclIO.c:
+ * generic/tclIOCmd.c:
+ * generic/tclIOUtil.c:
+ * generic/tclListObj.c:
+ * generic/tclLiteral.c:
+ * generic/tclNamesp.c:
+ * generic/tclObj.c:
+ * generic/tclParse.c:
+ * generic/tclPathObj.c:
+ * generic/tclPkg.c:
+ * generic/tclPreserve.c:
+ * generic/tclProc.c:
+ * generic/tclStringObj.c:
+ * generic/tclTest.c:
+ * generic/tclThreadAlloc.c:
+ * generic/tclTimer.c:
+ * generic/tclTrace.c:
+ * generic/tclVar.c:
+ * mac/tclMacChan.c:
+ * mac/tclMacOSA.c:
+ * mac/tclMacResource.c:
+ * mac/tclMacSock.c
+ * mac/tclMacThrd.c:
+ * unix/tclUnixChan.c:
+ * unix/tclUnixNotfy.c:
+ * unix/tclUnixThrd.c:
+ * unix/tclXtNotify.c:
+ * win/tclWin32Dll.c:
+ * win/tclWinChan.c:
+ * win/tclWinFCmd.c:
+ * win/tclWinNotify.c:
+ * win/tclWinPipe.c:
+ * win/tclWinSock.c:
+ * win/tclWinThrd.c:
+
+ * generic/tclInt.h: Deprecated use of Tcl_Ckalloc changed to
+ Tcl_Alloc in the TclAllocObjStorage macro.
+
+2003-12-22 David Gravereaux <davygrvy@pobox.com>
+
+ * win/nmakehlp.c:
+ * win/rules.vc: New feature for extensions that use rules.vc. Now
+ reads header files for version strings. No more hard coding
+ TCL_VERSION = 8.5 and having to edit it when you swap cores.
+
+ * win/makefile.vc: VERSION macro now set by reading tcl.h for it.
+
+ * generic/tcl.h: Removed note that makefile.vc needs to have a version
+ number changed.
+
+2003-12-21 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWin32Dll.c: Structured Exception Handling added around
+ Tcl_Finalize called from DllMain's DLL_PROCESS_DETACH. We can't be
+ 100% assured that Tcl is being unloaded by the OS in a stable
+ condition and we need to protect the exit handlers should the stack be
+ in a hosed state. AT&T style assembly for SEH under MinGW has not been
+ added yet. This is a first part change for [Patch 858493]
+
+2003-12-17 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tclBinary.c (DeleteScanNumberCache): fixed crashing bug when
+ numeric scan-value cache contains NULL value.
+
+2003-12-17 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclCmdAH.c:
+ * unix/tclUnixFile.c:
+ * win/tclWinFCmd.c:
+ * tests/fCmd.test:
+ * tests/fileSystem.test:
+ * doc/file.n: final fix to support for relative links and its
+ implications on normalization and other parts of the filesystem code.
+ Fixes [Bug 859251] and some Windows problems with recursive file
+ delete/copy and symbolic links.
+
+2003-12-17 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclPathObj.c:
+ * tests/fileSystem.test: fix and tests for [Bug 860402] in new file
+ normalization code.
+
+2003-12-17 Zoran Vasiljevic <zv@archiware.com>
+
+ * generic/tclIOUtil.c: fixed 2 memory (object) leaks. [Bug 839519]
+
+ * generic/tclPathObj.c: fixed Tcl_FSGetTranslatedPath to always return
+ properly refcounted path object. [Bug 861515]
+
+2003-12-16 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * tests/fCmd.test: marking fCmd-9.14.2, as nonPortable, since on
+ Solaris one can change the name of the current directory with 'file
+ rename'.
+ * doc/FileSystem.3: clarified documentation on ownership of return
+ objects/strings of some Tcl_FS* calls.
+
+2003-12-16 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclThreadAlloc.c (binfo): Made variable file-local.
+
+2003-12-15 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tcl.rc:
+ * win/tclsh.rc: Slight modification to the STRINGIFY macro to support
+ Borland's rc tool.
+
+ * win/tclWinFile.c (TclpUtime) : utimbuf struct not a problem with
+ Borland.
+
+ * win/tclWinTime.c (TclpGetDate) : Borland's localtime() has a slight
+ behavioral difference.
+
+ From Helmut Giese <hgiese@ratiosoft.com> [Patch 758097].
+
+2003-12-14 David Gravereaux <davygrvy@pobox.com>
+
+ * generic/tclInt.decls: commented-out entry for TclpCheckStackSpace,
+ removing it from the Stubs table. It's already declared in tclInt.h
+ and labeled as a function that is not to be exported. Regened tables.
+
+2003-12-14 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclCmdMZ.c (Tcl_SwitchObjCmd): TIP#75 Implementation
+ * tests/switch.test: Can now get submatch information when using
+ * doc/switch.n: -regexp matching in [switch].
+
+2003-12-14 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclPathObj.c: complete rewrite of generic file normalization
+ code to cope with links followed by '..'. [Bug 849514], and parts of
+ [Bug 859251]
+
+2003-12-12 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinChan.c: Win32's SetFilePointer() takes LONGs not DWORDs (a
+ signed/unsigned mismatch). Redid local vars to avoid all casting
+ except where truly required.
+
+2003-12-12 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclCmdAH.c: fix to normalization of non-existent user name
+ ('file normalize ~nobody') [Bug 858937]
+ * doc/file.n: clarify behaviour of 'file link' when the target is not
+ an absolute path.
+ * doc/filename.n: correct documentation to say that Windows Tcl does
+ handle '~user', for recent Windows releases, and clarified distinction
+ between MacOS 'classic' and MacOS X.
+ * doc/glob.n: clarification of glob's behaviour when returning
+ filenames starting with a '~'.
+
+ * tests/fileSystem.test:
+ * tests/fileName.test: new tests added for the normalization problem
+ above and other recentlt reported issues.
+
+ * win/tclWinFile.c: corrected unclear comments
+
+ * unix/tclUnixFile.c: allow creation of relative links. [Bug 833713]
+
+2003-12-11 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinSock.c (SocketThreadExitHandler) : added a TerminateThread
+ fallback just in case the socket handler thread is really in a paused
+ state. This can happen when Tcl is being unloaded by the OS from an
+ exception handler. See MSDN docs on DllMain, it states this behavior.
+
+2003-12-09 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/configure:
+ * unix/tcl.m4: updated OpenBSD build configuration based on
+ [Patch #775246] (cassoff)
+
+2003-12-09 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * unix/tclUnixPort.h: #ifdef'd out declarations of errno which are
+ * tools/man2tcl.c: known to cause problems with recent glibc.
+ [Bug 852369]
+
+2003-12-09 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * win/tclWinFile.c: fix to NT file permissions code [Bug 855923]
+ * tests/winFile.test: added tests for NT file permissions - patch and
+ test scripts supplied by Benny.
+
+ * tests/winFCmd.test: fixed one test for when not running in C:/
+
+2003-12-02 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclBinary.c (DeleteScanNumberCache, ScanNumber): Made the
+ numeric scan-value cache have proper references to the objects within
+ it so strange patterns of writes won't cause references to freed
+ objects. Thanks to Paul Obermeir for the report. [Bug 851747]
+
+2003-12-01 Miguel Sofer <msofer@users.sf.net>
+
+ * doc/lset.n: fix typo [Bug 852224]
+
+2003-11-24 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclParse.c: Corrected faulty check for trailing white
+ space in {expand} parsing. Thanks Andreas Leitgeb. [Bug 848262]
+ * tests/parse.test: New tests for the bug.
+
+2003-11-24 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclPathObj.c: fix to [Bug 845778] - Infinite recursion on
+ [cd] (Windows only bug), for which new tests have just been added.
+
+2003-11-21 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/winFCmd.test (winFCmd-16.10,11): Merged new tests from
+ core-8-4-branch.
+
+2003-11-20 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclVar.c: fix flag bit collision between LOOKUP_FOR_UPVAR
+ and TCL_PARSE_PART1 (deprecated) [Bug 835020]
+
+2003-11-19 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/compile.test (compile-16.22.0): Improved test for the recent
+ fix for Bug 845412.
+
+2003-11-19 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclCompile.c (TclCompileScript): Added a guard for the
+ expansion code so that long non-expanding commands don't get expansion
+ infrastructure inserted in them, especially when that infrastructure
+ isn't initialised. [Bug 845412]
+
+2003-11-18 David Gravereaux <davygrvy@pobox.com>
+
+ * contrib/djgpp/Makefile: Changes from Victor Wagner
+ * contrib/djgpp/langinfo.c (new): <vitus@45.free.net> for better
+ * contrib/djgpp/langinfo.h (new): DJGPP support.
+ * unix/tclUnixInit.c: .
+ * unix/tclUnixChan.c: .
+ * unix/tclUnixFCmd.c: .
+
+2003-11-17 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/reg.test: Added tests for [Bugs 230589, 504785, 505048, 840258]
+ recently fixed by 2003-11-15 commit to regcomp.c by Pavel Goran. His
+ notes on the fix: This bug results from an error in code that splits
+ states into "progress" and "no-progress" ones. This error causes an
+ interesting situation with the pre-collected single-linked list of
+ states to be splitted: many items were added to the list, but only
+ several of them are accessible from the list beginning, since the
+ "tmp" member of struct state (which is used here to hold a pointer to
+ the next list item) gets overwritten, which results in a "looped"
+ chain. As a result, not all of states are splitted, and one state is
+ splitted two times, causing incorrect "no-progress" flag values.
+
+2003-11-16 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclExecute.c (TclExecuteByteCode): Make sure that
+ Tcl_AsyncInvoke is called regularly when processing bytecodes.
+ * generic/tclTest.c (AsyncThreadProc, TestasyncCmd): Extended testing
+ harness to send an asynchronous marking without relying on UNIX
+ signals.
+ * tests/async.test (async-4.*): Tests to check that async events are
+ handled by the bytecode core. [Bug 746722]
+
+2003-11-15 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclTest.c (TestHashSystemHashCmd): Removed 'const' modifier
+ from hash type structure; it should be const and the hash code assumes
+ it behaves like const, but that's not how the API is defined. Like
+ this, we are following in the same footsteps as Tcl_RegisterObjType()
+ which has the same conditions on its argument. Stops VC++5.2 warning.
+ [Bug 842511]
+
+2003-11-14 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclHash.c (Tcl_DeleteHashTable,Tcl_HashStats,RebuildTable):
+ * generic/tclTest.c (TestHashSystemHashCmd): TIP#138 implementation,
+ * tests/misc.test: plus a new chunk of stuff to test the hash
+ functions more thoroughly in the test suite.
+ [Patch 731356, modified]
+
+ * doc/Tcl.n: Updated Tcl version number and changebars.
+
+2003-11-14 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/ParseCmd.3: Implementation of TIP 157. Adds recognition
+ * doc/Tcl.n: of the new leading {expand} syntax on words.
+ * generic/tcl.h: Parses such words as the new Tcl_Token type
+ * generic/tclBasic.c: TCL_TOKEN_EXPAND_WORD. Updated Tcl_EvalEx and
+ * generic/tclCompile.c: the bytecode compiler/execution engine to
+ * generic/tclCompile.h: recognize the new token type. New opcodes
+ * generic/tclExecute.c: INST_LIST_VERIFY and INST_INVOKE_EXP and a new
+ * generic/tclParse.c: operand type OPERAND_ULIST1 are defined. Docs
+ * generic/tclTest.c: and tests are included.
+ * tests/basic.test:
+ * tests/compile.test:
+ * tests/parse.test:
+
+ * library/auto.tcl: Replaced several [eval]s used to perform
+ * library/package.tcl: argument expansion with the new syntax. In the
+ * library/safe.tcl: test files lindex.test and lset.test, replaced
+ * tests/cmdInfo.test: use of [eval] to force direct string
+ * tests/encoding.test: evaluation with use of [testevalex] which more
+ * tests/execute.test: directly and robustly serves the same purpose.
+ * tests/fCmd.test:
+ * tests/http.test:
+ * tests/init.test:
+ * tests/interp.test:
+ * tests/io.test:
+ * tests/ioUtil.test:
+ * tests/iogt.test:
+ * tests/lindex.test:
+ * tests/lset.test:
+ * tests/namespace-old.test:
+ * tests/namespace.test:
+ * tests/pkg.test:
+ * tests/pkgMkIndex.test:
+ * tests/proc.test:
+ * tests/reg.test:
+ * tests/trace.test:
+ * tests/upvar.test:
+ * tests/winConsole.test:
+ * tests/winFCmd.test:
+
+2003-11-12 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * tests/cmdMZ.test (cmdMZ-1.4): change to nonPortable as more systems
+ are using permissions caching, and this isn't really a Tcl controlled
+ issue.
+
+2003-11-11 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/configure:
+ * unix/tcl.m4: improve AIX --enable-64bit handling
+ remove -D__NO_STRING_INLINES -D__NO_MATH_INLINES from CFLAGS_OPTIMIZE
+ on Linux. Make default opt -O2 (was -O).
+
+2003-11-11 David Gravereaux <davygrvy@pobox.com>
+
+ * contrib/djgpp/Makefile: Suggested changes from vitus@45.free.net
+ (Victor Wagner)
+
+ * unix/tclUnixPort.h: added socklen_t typedef for DJGPP
+
+2003-11-10 Don Porter <dgp@users.sourceforge.net>
+
+ * unix/tclUnixInit.c (TclpInitLibraryPath):
+ * win/tclWinInit.c (TclpInitLibraryPath): Fix for [Bug 832657]
+ that should not run afoul of startup constraints.
+
+ * library/dde/pkgIndex.tcl: Added safeguards so that registry and
+ * library/reg/pkgIndex.tcl: dde packages are not offered on
+ * win/tclWinDde.c: non-Windows platforms. Bumped to
+ * win/tclWinReg.c: registry 1.1.3 and dde 1.3.
+ * win/Makefile.in:
+ * win/configure.in:
+ * win/makefile.bc:
+ * win/makefile.vc:
+
+ * win/configure: autoconf (2.57)
+
+2003-11-10 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * tests/cmdIL.test: Stopped cmdIL-5.5 from stomping over the test
+ command, and updated the tests to use some tcltest2 features in
+ relation to cleanup. [Bug 838384]
+
+2003-11-10 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclCmdAH.c:
+ * tests/fCmd.test: fix to misleading error message in 'file link'.
+ [Bug 836208]
+
+2003-11-07 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclIOUtil.c: fix to compiler warning/error with some
+ compilers. [Bug 835918]
+
+2003-11-07 Daniel Steffen <das@users.sourceforge.net>
+
+ * macosx/Makefile: optimized builds define NDEBUG to turn off
+ ThreadAlloc range checking.
+
+2003-11-05 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/unixInit.test (unixInit-2.10): New test to expose [Bug 832657]
+ failure of TclpInitLibraryPath() to properly handle .. in the path
+ of the executable.
+
+2003-11-04 Daniel Steffen <das@users.sourceforge.net>
+
+ * macosx/Makefile: added 'test' target.
+
+2003-11-03 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclIOUtil.c
+ * generic/tclInt.h: added comments and re-arranged code to clarify
+ distinction between Tcl_LoadHandle, ClientData for 'load'ed code, and
+ point out limitations of the design introduced with Tcl 8.4.
+
+ * unix/tclUnixFile.c: fix to memory leak
+
+ * generic/tclCmdIL.c: removed warning on Windows.
+
+2003-11-01 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclCmdIL.c (Tcl_LrepeatObjCmd): Check for sensible list
+ lengths and allow for soft failure of the memory subsystem in the
+ [lconcat] command [Bug 829027]. Uses direct list creation to avoid
+ extra copies when working near the limit of available memory. Also
+ reorganized to encourage optimizing compilers to optimize heavily.
+ * generic/tclListObj.c (TclNewListObjDirect): New list constructor
+ that does not copy the array of objects. Useful for creating
+ potentially very large lists or where you are about to throw away the
+ array argument which is being used in its entirety.
+
+2003-10-28 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c (NEXT_INST macros): replaced macro variable
+ "result" by "resultHandling" to avoid confusion.
+
+2003-10-23 Andreas Kupries <andreask@activestate.com>
+
+ * unix/tclUnixChan.c (Tcl_MakeFileChannel): Applied [Patch 813606]
+ fixing [Bug 813087]. Detection of sockets was off for Mac OS X which
+ implements pipes as local sockets. The new code ensures that only IP
+ sockets are detected as such.
+
+ * win/tclWinSock.c (TcpWatchProc): Watch for FD_CLOSE too when asked
+ for writable events by the generic layer.
+ (SocketEventProc): Generate a writable event too when a close is
+ detected.
+
+ Together the changes fix [Bug 599468].
+
+2003-10-23 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * tests/resource.test:
+ * mac/tclMacResource.c: fix to resource freeing problem in 'resource'
+ command reported by Bernard Desgraupes.
+
+ * doc/FileSystem.3: updated documentation for 'glob' fix on 2003-10-13
+ below
+
+2003-10-22 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclCmdAH.c (Tcl_FileObjCmd): Changed FILE_ prefix to FCMD_
+ to stop symbol/#def clashes on Cygwin/Mingw32 on NT. [Bug 822528]
+
+2003-10-21 Daniel Steffen <das@users.sourceforge.net>
+
+ * tools/tcltk-man2html.tcl: fixed incorrect html generated for
+ .IP/.TP lists, now use <DL><DT>...<DD>...<P><DT>...<DD>...</DL>
+ instead of illegal <DL><P><DT>...<DD>...<P><DT>...<DD>...</DL>.
+ Added skipping of directives directly after .TP to avoid them being
+ used as item descriptions, e.g. .TP\n.VS in clock.n.
+
+2003-10-21 Andreas Kupries <andreask@pliers.activestate.com>
+
+ * win/tclWinPipe.c (BuildCommandLine): Applied the patch coming with
+ [Bug 805605] to the code, fixing the incorrect use of ispace noted by
+ Ronald Dauster <ronaldd@users.sourceforge.net>.
+
+2003-10-20 Kevin B. Kenny <kennykb@users.sourceforge.net>
+
+ * doc/msgcat.n:
+ * library/msgcat/msgcat.tcl (mclocale,mcload):
+ * tools/tcl.wse.in:
+ * unix/Makefile.in: Implementation of TIP#156, add a "root locale"
+ * win/makefile.bc: to the 'msgcat' package. Advanced msgcat
+ * win/Makefile.in: version number to 1.4
+ * win/Makefile.vc:
+
+2003-10-15 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclCmdIL.c (SortInfo,etc): Reorganized so that SortInfo
+ carries an array of integer indices instead of a Tcl list. This nips
+ shimmering problems in the bud and simplifies SelectObjFromSublist at
+ the cost of making setup slightly more complex. [Bug 823768]
+
+2003-10-14 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclAppInit.c (sigHandler): Punt gracefully if exitToken has
+ already been destroyed.
+
+2003-10-14 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclCmdMZ.c:
+ * tests/regexp.test: fix to [Bug 823524] in regsub; added three new
+ tests.
+
+2003-10-14 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c (TclAppendObjToErrorInfo): New internal routine
+ that appends a Tcl_Obj to the errorInfo, saving the caller the trouble
+ of extracting the string rep.
+
+ * generic/tclStringObj.c (TclAppendLimitedToObj): New internal
+ routine that supports truncated appends with optional ellipsis marking.
+ This single routine supports UTF-8-safe truncated appends needed in
+ several places throughout the Tcl source code, mostly for error and
+ stack messages. Clean fix for [Bug 760872].
+
+ * generic/tclInt.h: Declarations for new internal routines.
+
+ * generic/tclCmdMZ.c: Updated callers to use the new routines.
+ * generic/tclCompExpr.c:
+ * generic/tclCompile.c:
+ * generic/tclExecute.c:
+ * generic/tclIOUtil.c:
+ * generic/tclNamesp.c:
+ * generic/tclObj.c:
+ * generic/tclParseExpr.c:
+ * generic/tclProc.c:
+ * generic/tclStringObj.c:
+ * mac/tclMacResource.c:
+
+ * library/init.tcl: Updated ::errorInfo cleanup in [unknown] to
+ reflect slight modifications to Tcl_LogCommandInfo(). Corrects failing
+ init-4.* tests.
+
+2003-10-14 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ TIP#127 IMPLEMENTATION FROM JOE MICHAEL SCHLENKER
+
+ * generic/tclCmdIL.c (SelectObjFromSublist): Element selection engine.
+ * generic/tclCmdIL.c (Tcl_LsearchObjCmd, Tcl_LsortObjCmd):
+ * tests/lsearch.test: Set up and use of element selection engine,
+ * tests/cmdIL.test: plus tests and documentation.
+ * doc/lsearch.n: Based on [Patch 693836]
+ * doc/lsort.n:
+
+2003-10-13 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tcl.h:
+ * generic/tclFileName.c:
+ * generic/tclIOUtil.c:
+ * generic/tclPathObj.c:
+ * generic/tclTest.c:
+ * mac/tclMacFile.c:
+ * tests/fileName.test: better tests for [Bug 813273]
+ * unix/tclUnixFCmd.c:
+ * unix/tclUnixFile.c:
+ * win/tclWin32Dll.c:
+ * win/tclWinFCmd.c:
+ * win/tclWinFile.c:
+ * win/tclFileInt.h:
+
+ Fixed [Bug 800106] in which 'glob' was incapable of merging the
+ results of a directory listing (real or virtual) and any virtual
+ filesystem mountpoints in that directory (the latter were ignored).
+ This meant boundaries between different filesystems were not seamless
+ (e.g. 'glob */*' across a filesystem boundary was wrong). Added new
+ entry to Tcl_GlobTypeData in a totally backwards compatible way. To
+ allow listing of mounts, registered filesystems must support the
+ 'TCL_GLOB_TYPE_MOUNT' flag. If this is not supported (e.g. in tclvfs
+ 1.2) then mounts will simply not be listed for that filesystem.
+
+ Fixed [Bug 749876] 'file writable/readable/etc' (NativeAccess) using
+ correct permission checking code for Windows NT/2000/XP where more
+ complex user-based security/access priveleges are available,
+ particularly on shared volumes. The performance impact of this extra
+ checking will need further investigation. Note: Win 95,98,ME have no
+ support for this.
+
+ Also made better use of normalized rather than translated paths in the
+ platform specific code.
+
+2003-10-12 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/tclUnixTest.c (TestalarmCmd): don't bother checking return
+ value of alarm. [Bug #664755] (english)
+
+2003-10-09 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ * win/makefile.vc: Applied patches for bug #801467 by Joe Mistachkin
+ * win/tclAppInit.c: to fix incompatible TCL_MEM_DEBUG handling in
+ * generic/tclObj.c: Win32 VC builds.
+
+2003-10-08 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c: Save and restore the iPtr->flag bits that
+ control the state of errorCode and errorInfo management when calling
+ "leave" execution traces, so that all error information of the traced
+ command is still available whether traced or not. [Bug 760947]
+ Thanks to Yahalom Emet.
+
+2003-10-08 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclTest.c (TestNumUtfCharsCmd): Command to allow finer
+ access to Tcl_NumUtfChars for testing.
+ * generic/tclUtf.c (Tcl_NumUtfChars): Corrected string length
+ determining when the length parameter is negative; the terminator is a
+ zero byte, not (necessarily) a \u0000 character. [Bug 769812]
+
+2003-10-07 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/cmdAH.test:
+ * tests/exec.test: Corrected temporary file management
+ * tests/fileSystem.test: issues uncovered by -debug 1 test
+ * tests/io.test: operations. Also backported some
+ * tests/ioCmd.test: other fixes from the HEAD.
+ * tests/main.test:
+ * tests/pid.test: [Bugs 675605, 675655, 675659]
+ * tests/socket.test:
+ * tests/source.test:
+
+ * tests/fCmd.test: Run tests with the [temporaryDirectory] as the
+ current directory, so that tests can depend on ability to write files.
+ [Bug 575837]
+
+ * doc/OpenFileChnl.3: Updated Tcl_Tell and Tcl_Seek documentation to
+ reflect that they now return Tcl_WideInt (TIP 72). [Bug 787537]
+
+ * tests/io.test: Corrected several tests that failed when paths
+ * tests/ioCmd.test: included regexp-special chars. [Bug 775394]
+
+2003-10-06 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/configure:
+ * win/tcl.m4: removed incorrect checks for existence of optimization.
+ TCL_CFG_OPTIMIZED is now defined whenever the user does not build with
+ --enable-symbols.
+
+2003-10-06 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/regexp.test: Matched [makeFile] with [removeFile].
+ * tests/regexpComp.test: [Bug 675652]
+
+ * tests/fCmd.test (fCmd-8.2): Test only that tilde-substitution
+ happens, not for any particular result. [Bug 685991]
+
+ * unix/tcl.m4 (SC_PATH_TCLCONFIG): Corrected search path so that
+ alpha and beta releases of Tcl are not favored. [Bug 608698]
+
+ * tests/reg.test: Corrected duplicate test names.
+ * tests/resource.test: [Bugs 710370, 710358]
+ * tests/dict.test:
+
+ * tests/dict.test: Updated [package require tcltest] lines to
+ * tests/fileSystem.test: indiciate that these test files
+ * tests/lrepeat.test: use features of tcltest 2. [Bug 706114]
+ * tests/notify.test:
+ * tests/parseExpr.test:
+ * tests/unixNotfy.test:
+ * tests/winDde.test:
+
+2003-10-04 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c (TEBC):
+ * tests/execute.test (execute-8.2): fix for [Bug 816641] - faulty
+ execution and catch stack management.
+
+2003-10-03 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c: Fixed error in ref count management of command
+ * generic/tclCmdMZ.c: and execution traces that caused access to
+ freed memory in trace-32.1. [Bug 811483]
+
+2003-10-02 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclTrace.c: Corrected comingling of introspection results of
+ [trace info command] and [trace info execution]. [Bug 807243]
+ Thanks to Mark Saye.
+
+2003-10-01 Daniel Steffen <das@users.sourceforge.net>
+
+ * macosx/Makefile: fixed redo prebinding bug when DESTDIR="".
+ * mac/tclMacResource.c: fixed possible NULL dereference (bdesgraupes).
+
+2003-09-29 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclPathObj.c:
+ * tests/fileName.test: fix to inconsistent handling of backslash
+ path separators on Windows in 'file join' [Bug 813273]
+
+2003-09-29 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclPathObj.c (TclNativePathInFilesystem,TclFSGetPathType):
+ * generic/tclIOUtil.c (TclNativeDupInternalRep,TclGetPathType): Rename
+ to make sure function names won't interfere with other non-Tcl code
+ (reported by George Staplin)
+
+ TIP#121 IMPLEMENTATION FROM JOE MISTACHKIN
+
+ * generic/tclEvent.c (Tcl_SetExitProc,Tcl_Exit): Implementation of
+ application exit handler scheme.
+ * generic/tcl.decls (Tcl_SetExitProc): Public declaration.
+ * doc/Exit.3: Documentation of new API function.
+
+ TIP#112 IMPLEMENTATION
+
+ * generic/tclNamesp.c: Core of implementation.
+ * generic/tclInt.h (Namespace,TclInvalidateNsCmdLookup): Add command
+ list epoch counter and list of ensembles to namespace structure, and
+ define a macro to ease update of the epoch counter.
+ * generic/tclBasic.c (Tcl_CreateObjCommand,etc.): Update epoch counter
+ when list of commands in a namespace changes.
+ * generic/tclObj.c (TclInitObjSubsystem): Register ensemble subcommand
+ type.
+ * tests/namespace.test (42.1-47.6): Tests.
+ * doc/namespace.n: Documentation.
+
+ * library/http/http.tcl (geturl): Correctly check the type of
+ boolean-valued options. [Bug 811170]
+
+ * unix/tcl.m4 (SC_ENABLE_FRAMEWORK): Added note to make it clearer
+ that this is an OSX feature, not a general Unix feature. [Bug 619440]
+
+2003-09-28 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinPipe.c: The windows port of expect can call
+ TclWinAddProcess before any of the other pipe functions. Added a
+ missing PipeInit() call to make sure the initialization happens.
+
+2003-09-25 Daniel Steffen <das@users.sourceforge.net>
+
+ * macosx/Makefile: ensure SYMROOT exists if OBJROOT is overridden on
+ command line. Replaced explict use of /usr/bin by ${BINDIR}.
+
+2003-09-24 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * library/package.tcl (tcl::MacPkgUnknown, tcl::MacOSXPkgUnknown):
+ Minor performance tweaks to reduce the number of [file] invocations.
+ Meant to improve startup times, at least a little bit. (The generic
+ equivalent patch was applied on 2003-02-21).
+
+2003-09-24 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * trace.test: removed 'knownBug' from a test which doesn't illustrate
+ a bug, just a bad test.
+
+2003-09-23 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c:
+ * generic/tclInt.h: changed the evaluation-stack addressing mode, from
+ array-style to pointer-style; the catch stack and evaluation stack are
+ now contiguous in memory. [Patch 457449]
+
+2003-09-23 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/trace.test (trace-31,32-*): Added tests for [Bug 807243] and
+ [Bug 811483].
+
+ * library/init.tcl (auto_load, auto_import): Expanded Eric Melski's
+ 2000-01-28 fix for [Bug 218871] to all potentially troubled uses of
+ [info commands] on input data, where glob-special characters could
+ cause problems.
+
+2003-09-20 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * tests/expr.test (expr-23.4): Prevented accidental wrapping round of
+ exponential operation; it isn't portable, and not what I intended to
+ test either. [Bug 808244]
+
+2003-09-19 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c: adding (DE)CACHE_STACK_INFO() pairs to protect
+ all calls that may cause traces on ::errorInfo or ::errorCode to
+ corrupt the stack. [Bug 804681]
+
+2003-09-17 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * tclPathObj.c: fix to test-suite problem introduced by the bug fix
+ below. No problem in ordinary code, just test suite code which
+ manually adjusts tclPlatform. [Bug 808247]
+
+2003-09-16 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * doc/filename.n: documentation of Windows-specific feature as
+ discussed in [Bug 541989]
+ * generic/tclPathObj.c: fix for normalization of volume-relative paths
+ [Bug 767834]
+ * tests/winFCmd.test: new tests for both of the above.
+ * tests/cmdAH.test: fix for AFS problem in test suite [Bug 748960]
+
+2003-09-13 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ TIP#123 IMPLEMENTATION BASED ON WORK BY ARJEN MARKUS
+
+ * generic/tclCompile.h (INST_EXPON): Implementation of
+ * generic/tclCompile.c (tclInstructionTable): exponential operator.
+ * generic/tclCompExpr.c (operatorTable):
+ * generic/tclParseExpr.c (ParseExponentialExpr, GetLexeme):
+ * generic/tclExecute.c (TclExecuteByteCode, ExponWide, ExponLong):
+ (IllegalExprOperandType):
+ * tests/expr.test:
+ * tests/compExpr-old.test:
+ * doc/expr.n:
+
+2003-09-10 Don Porter <dgp@users.sourceforge.net>
+
+ * library/opt/optparse.tcl: Latest revisions caused [OptGuessType]
+ to guess "int" instead of "string" for empty strings. Missed the
+ required "-strict" option to [string is]. Thanks to Revar Desmera.
+ [Bug 803968]
+
+2003-09-08 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinLoad.c (TclpDlopen): Changed the error message for
+ ERROR_PROC_NOT_FOUND to be a bit more helpful in giving us clues.
+ "can't find specified procedure" means a function in the import table,
+ for implicit loading, couldn't be resolved and that's why the load
+ failed.
+
+2003-09-04 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/Tcl_Main.3:
+ * doc/FileSystem.3: Implementation of
+ * doc/source.n: TIPs 137/151. Adds a
+ * doc/tclsh.1: -encoding option to
+ * generic/tcl.decls: the [source] command
+ * generic/tclCmdMZ.c (Tcl_SourceObjCmd): and a new C routine,
+ * generic/tclIOUtil.c (Tcl_FSEvalFileEx): Tcl_FSEvalFileEx(),
+ * generic/tclMain.c (Tcl_Main): that provides C access
+ * mac/tclMacResource.c (Tcl_MacSourceObjCmd): to the same function.
+ * tests/cmdMZ.test: Also adds command line
+ * tests/main.test: option handling in Tcl_Main() so that tclsh
+ * tests/source.test: and other apps built on Tcl_Main() respect a
+ -encoding command line option before a script filename. Docs and tests
+ updated as well. [Patch 742683]
+ This is a ***POTENTIAL INCOMPATIBILITY*** only for those C programs
+ that embed Tcl, build on Tcl_Main(), and make use of Tcl_Main's former
+ ability to pass a leading "-encoding" option to interactive shell
+ operations.
+
+ * generic/tclInt.decls: Added internal stub
+ * generic/tclMain.c (Tcl*StartupScript*): table entries for two
+ new functions Tcl_SetStartupScript() and Tcl_GetStartupScript() that
+ set/get the path and encoding for the startup script to be evaluated
+ by either Tcl_Main() or Tk_Main(). Given public names in anticipation
+ of their exposure by a followup TIP.
+
+ * generic/tclDecls.h: make genstubs
+ * generic/tclIntDecls.h:
+ * generic/tclStubInit.c:
+
+2003-09-04 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/SplitList.3: Implementation of TIP 148. Fixes [Bug 489537].
+ * generic/tcl.h: Updated Tcl_ConvertCountedElement() to quote
+ * generic/tclUtil.c: the leading "#" character of all list elements
+ unless the TCL_DONT_QUOTE_HASH flag is passed in.
+
+ * generic/tclDictObj.c: Updated Tcl_ConvertCountedElement() callers
+ * generic/tclListObj.c: to pass in the TCL_DONT_QUOTE_HASH flags
+ * generic/tclResult.c: when appropriate.
+
+2003-08-31 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/return.n: Updated [return] docs to cover new TIP 90 features.
+
+ * doc/break.n: Added SEE ALSO references to return.n
+ * doc/continue.n:
+
+2003-09-01 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/Namespace.3: Basic documentation for the TIP#139 functions. This
+ will need improving, but the basic bits are there at least.
+
+2003-08-31 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/catch.n: Updated [catch] docs to cover new TIP 90 features.
+
+2003-08-29 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCmdAH.c: Corrected bug in TIP 90 implementation where
+ * tests/cmdMZ.test: the default -errorcode NONE value was not
+ copied into the return options dictionary. This correction modified
+ one test result.
+
+2003-08-27 David Gravereaux <davygrvy@pobox.com>
+
+ * compat/strftime.c (_fmt): Removed syst array intializer that
+ couldn't take variables within it under the watcom compiler:
+ 'Initializers must be constant'. I believe Borland has this strictness
+ as well. VC++ must be non-standard about this.
+
+ Changed Win32 platform #ifdef from 'WIN32' to '__WIN32__' as this is
+ the correct one to use across the Tcl sources. Even though we do force
+ it in tcl.h, the true parent one is __WIN32__.
+
+ Added missing CONST'ification usage to match prototype listed in
+ tclInt.decls.
+
+ * win/tclWinPort.h: Added a block for OpenWatcom adjustments that
+ fixes 1) the same issue Mo did for MinGW lack of missing LPFN_*
+ typedefs in their WINE derived <winsock2.h> and 2) The need to be
+ strict about how the char type needs to be signed by default.
+
+ * win/tclWinSock.c: Added OpenWatcom to the commentary about the
+ #ifdef HAVE_NO_LPFN_DECLS block.
+
+ * win/tclWinTime.c: Changed use of '_timezone' to 'timezone' as this
+ difference is already adjusted for in tclWinPort.h. Removed
+ unreferenced posixEpoch file-scope global.
+
+ * win/tclWinFile.c (WinReadLinkDirectory): Fix for 'Initializers must
+ be constant' with the driveSpec array using OpenWatcom.
+
+2003-08-27 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclUtil.c: Corrected [Bug 411825] and other bugs in
+ TclNeedSpace() where non-breaking space (\u00A0) and backslash-escaped
+ spaces were handled incorrectly.
+ * tests/util.test: Added new tests util-8.[2-6].
+
+2003-08-26 David Gravereaux <davygrvy@pobox.com>
+
+ * generic/tcl.h: Added some support for the LCC-Win32 compiler.
+ Unfortunetly, this compiler has a bug in its preprocessor and can't
+ build Tcl even with this minor patch. Also added some support for the
+ OpenWatcom compiler. A new win/makefile.wc to follow soon.
+
+2003-08-25 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * tools/genStubs.tcl (genStubs::makeDecl): A more subtle way of
+ generating stubbed declarations allows us to have declarations of a
+ function in multiple interfaces simultaneously.
+
+ * generic/tcl.decls: Duplicated some namespace declarations from
+ tclInt.decls here, as mandated by TIP #139. This is OK since the
+ declarations match and will end up using the declarations in the
+ public code from now on because of #include ordering. Keeping the old
+ declarations in tclInt.decls; there's no need to gratuitously break
+ compatability for those extensions which are already clients of the
+ namespace code.
+
+2003-08-23 Zoran Vasiljevic <zoran@archiwrae.com>
+
+ * generic/tclIOUtil.c: merged fixes for thread-unsafe handling of
+ filesystem records [Bug 753315]. This also fixed the [Bug 788780]
+ * generic/tclPathObj.c: merged fixes for thread-unsafe handling of
+ filesystem records. [Bug 753315]
+
+ * generic/tclFileSystem.h: merged fixes for thread-unsafe handling of
+ filesystem records. [Bug 753315]
+
+2003-08-19 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ * win/tclWinSerial.c (SerialErrorStr): Fixed a syntax error created in
+ the previous code cleanup.
+
+2003-08-19 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * win/tclWinSerial.c: Adjusted commenting and spacing usage to follow
+ the principles of the Style Guide better.
+
+2003-08-18 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/configure: Regen.
+ * win/tcl.m4 (SC_ENABLE_SYMBOLS): Use test instead of -eq, which does
+ not work. [Bug 781109]
+
+2003-08-13 Chengye Mao <chengye.geo@yahoo.com>
+
+ * win/tclWinPipe.c: fixed a bug in BuildCommandLine. This bug built a
+ command line with a missing space between tclpipe.dll and the
+ following arguments. It caused error in Windows 98 when exec
+ command.com (e.g. dir). [Bug 789040]
+
+2003-08-11 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ TIP #136 IMPLEMENTATION from Simon Geard <simon.geard@ntlworld.com>
+ * generic/tclCmdIL.c (Tcl_LrepeatObjCmd): Adapted version of Simon's
+ * doc/lrepeat.n: patch, updated to the HEAD
+ * tests/lrepeat.test: and matching the core style.
+ * generic/tclBasic.c (buildIntCmds): Splice into core.
+ * generic/tclInt.h:
+ * doc/list.n: Cross-reference.
+
+2003-08-06 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/tclWinInit.c: recognize amd64 and ia32_on_win64 cpus.
+
+2003-08-06 Don Porter <dgp@users.sourceforge.net>
+
+ * library/msgcat/msgcat.tcl: Added escape so that non-Windows
+ * library/msgcat/pkgIndex.tcl: platforms do not try to use the
+ registry package. This can save a costly and pointless package search.
+ Bumped to 1.3.1. Thanks to Dave Bodenstab. [Bug 781609]
+
+2003-08-05 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c (INST_INVOKE, INST_EVAL, INST_PUSH_RESULT):
+ added a Tcl_ResetResult(interp) at each point where the interp's
+ result is pushed onto the stack, to avoid keeping an extra reference
+ that may cause costly Tcl_Obj duplication. Detected by Franco Violi,
+ analyzed by Peter Spjuth and Donal Fellows. [Bug 781585]
+
+2003-07-28 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * doc/FileSystem.3:
+ * doc/Translate.3: better documentation of Tcl_TranslateFileName and
+ related functions. [Bug 775220]
+
+2003-07-24 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * generic/tcl.h: Revert change made on 2003-07-21 since it made the
+ sizeof(Tcl_Obj) different for regular vs mem debug builds.
+ * generic/tclInt.h: Define TclDecrRefCount in terms of
+ Tcl_DbDecrRefCount which removes one layer of inderection.
+ * generic/tclObj.c (TclDbInitNewObj, Tcl_DbIncrRefCount,
+ (Tcl_DbDecrRefCount, Tcl_DbIsShared): Define ThreadSpecificData that
+ contains a hashtable. The table is used to ensure that a Tcl_Obj is
+ only acted upon in the thread that allocated it. This checking code is
+ enabled only when mem debug and threads are enabled.
+
+2003-07-24 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/async.test: Added several tests that demonstrate [Bug
+ * tests/basic.test: 489537], Tcl's longstanding failure to
+ * tests/dict.test: properly quote any leading '#' character when
+ * tests/dstring.test: generating the string rep of a list so that
+ * tests/list.test: the comment-power of that character is hidden
+ * tests/parse.test: from any [eval], in order to satisfy the
+ * tests/util.test: documentation that [list] does [eval]-safe
+ quoting.
+
+2003-07-24 Reinhard Max <max@suse.de>
+
+ * library/package.tcl: Fixed a typo that broke pkg_mkIndex -verbose.
+ * tests/pkgMkIndex.test: Added a test for [pkg_mkIndex -verbose].
+
+ * ChangeLog.2002 (new file):
+ * ChangeLog: broke changes from 2002 into ChangeLog.2002 to reduce
+ size of the main ChangeLog.
+
+2003-07-23 Daniel Steffen <das@users.sourceforge.net>
+
+ * unix/Makefile.in: changes to html-tcl & html-tk targets for
+ compatibility with non-gnu makes.
+
+ * unix/Makefile.in: added macosx/README to dist target.
+
+2003-07-23 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ * win/tclWinReg.c (OpenSubKey): Fixed bug 775976 which causes the
+ registry set command to fail when built with VC7.
+ * library/reg/pkgIndex.tcl: Incremented the version to 1.1.2.
+
+2003-07-21 Mo DeJong <mdejong@users.sourceforge.net>
+
+ Check that the thread incrementing or decrementing the ref count of a
+ Tcl_Obj is the thread that originally allocated the thread. This fail
+ fast behavior will catch programming errors that allow a single
+ Tcl_Obj to be accessed from multiple threads.
+
+ * generic/tcl.h (Tcl_Obj): Add allocThread member to Tcl_Obj. This
+ member records the thread id the Tcl_Obj was allocated. It is used to
+ check that any future ref count incr or decr is done from the same
+ thread that allocated the Tcl_Obj. This member is defined only when
+ threads and mem debug are enabled.
+ * generic/tclInt.h (TclNewObj, TclDbNewObj, TclDecrRefCount):
+ Define TclNewObj and TclDbNewObj using TclDbInitNewObj when mem debug
+ is enabled. This fixes a problem where TclNewObj calls did not work
+ the same as TclDbNewObj when mem debug was enabled.
+ * generic/tclObj.c (TclDbInitNewObj, Tcl_DbIncrRefCount,
+ (Tcl_DbDecrRefCount): Add new helper to init Tcl_Obj members when mem
+ debug is enabled. Init the allocThread member in TclDbInitNewObj and
+ check it in Tcl_DbIncrRefCount and Tcl_DbDecrRefCount to make sure a
+ Tcl_Obj allocated in one thread is not being acted upon in another
+ thread.
+
+2003-07-21 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * test/cmdAH.test: ensure certain tests run in local filesystem. [Bug
+ 748960]
+
+2003-07-18 Daniel Steffen <das@users.sourceforge.net>
+
+ * macosx/Makefile: added option to allow installing manpages in
+ addition to default html help.
+
+2003-07-18 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/Utf.3: Tightened up documentation of Tcl_UtfNext and Tcl_UtfPrev
+ to better match the behaviour. [Bug 769895]
+
+2003-07-18 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * library/http/pkgIndex.tcl: upped to http v2.4.4
+ * library/http/http.tcl: add support for user:pass info in URL.
+ * tests/http.test: [Bug 759888] (shiobara)
+
+2003-07-18 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/tcltest.n: Restored the [Eval] proc to replace
+ * library/tcltest/tcltest.tcl: the [::puts] command when either the
+ -output or -error option for [test] is in use, in order to capture
+ data written to the output or error channels for comparison against
+ what is expected. This is easier to document and agrees better with
+ most user expectations than the previous attempt to replace [puts]
+ only in the caller's namespace. Documentation made more precise on
+ the subject. [Bug 706359]
+
+ * doc/AddErrInfo.3: Improved consistency of documentation by
+ * doc/CrtTrace.3: using "null" everywhere to refer to the
+ * doc/Encoding.3: character '\0', and using "NULL" everywhere
+ * doc/Eval.3: to refer to the value of a pointer that points
+ * doc/GetIndex.3: to nowhere. Also dropped references to ASCII
+ * doc/Hash.3: that are no longer true, and standardized on
+ * doc/LinkVar.3: the hyphenated spelling of "null-terminated".
+ * doc/Macintosh.3:
+ * doc/OpenFileChnl.3:
+ * doc/SetVar.3:
+ * doc/StringObj.3:
+ * doc/Utf.3:
+
+ * doc/CrtSlave.3 (Tcl_MakeSafe): Removed warning about possible
+ deprecation (no TIP on that).
+
+2003-07-17 Daniel Steffen <das@users.sourceforge.net>
+
+ * unix/tclUnixFCmd.c: fix for compilation errors on platforms where
+ configure detects non-functional chflags(). [Bug 748946]
+
+ * macosx/Makefile: Rewrote buildsystem for Mac OS X framework build
+ to be purely make driven; in order to become independent of Apple's
+ closed-source IDE and build tool. The changes are intended to be
+ transparent to the Makefile user, all existing make targets and cmd
+ line variable overrides should continue to work. Changed build to only
+ include tcl specific html help in Tcl.framework, the tk specific html
+ help is now included in Tk.framework. Added var to allow overriding of
+ tclsh used during html help building (Landon Fuller).
+
+ * macosx/Tcl.pbproj/project.pbxproj:
+ * macosx/Tcl.pbproj/jingham.pbxuser: Changed to purely call through to
+ the make driven buildsystem; Tcl.framework is no longer assembled by
+ ProjectBuilder.
+ Set default SYMROOT in target options to simplify setting up PB
+ (manually setting common build folder for tcl & tk no longer needed).
+
+ * tools/tcltk-man2html.tcl: Added options to allow building only the
+ tcl or tk html help files; the default behaviour with none of the new
+ options is to build both, as before.
+
+ * unix/Makefile.in: Added targets for building only the tcl or tk help
+
+ * macosx/README (new): Tcl specific excerpts of tk/macosx/README.
+
+ * generic/tcl.h: Updated reminder comment about editing
+ macosx/Tcl.pbproj/project.pbxproj when version number changes.
+
+2003-07-16 Mumit Khan <khan@nanotech.wisc.edu>
+
+ * generic/tclPathObj.c (SetFsPathFromAny): Add Cygwin specific code to
+ convert POSIX filename to native format.
+ * generic/tclFileName.c (Tcl_TranslateFileName): And remove from here.
+ (TclDoGlob): Adjust for cygwin and append / for dirs instead of \
+ * win/tclWinFile.c (TclpObjChdir): Use chdir on Cygwin.
+ [Patch 679315]
+
+2003-07-16 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * library/safe.tcl (FileInAccessPath): normalize paths before
+ comparison. [Bug 759607] (myers)
+
+ * unix/tclUnixNotfy.c (NotifierThreadProc): correct size of found and
+ word vars from int to long. [Bug 767578] (hgo)
+
+ * generic/tcl.h: Add recognition of -DTCL_UTF_MAX=6 on the make
+ * generic/regcustom.h: line to support UCS-4 mode. No config arg at
+ this time, as it is not the recommended build mode.
+
+ * generic/tclPreserve.c: In Result and Preserve'd routines, do not
+ * generic/tclUtil.c: assume that ckfree == free, as that is not
+ * generic/tclResult.c: always true. [Bug 756791] (fuller)
+
+2003-07-16 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/CrtSlave.3 (Tcl_MakeSafe): Updated documentation to strongly
+ discourage use. IMHO code outside the core that uses this function is
+ a bug... [Bug 655300]
+
+2003-07-16 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclFileName.c (Tcl_GlobObjCmd): [Bug 771840]
+ * generic/tclPathObj.c (Tcl_FSConvertToPathType):[Bug 771947]
+ * unix/tclUnixFCmd.c (GetModeFromPermString): [Bug 771949]
+ Silence compiler warnings about unreached lines.
+
+ * library/tcltest/tcltest.tcl (ProcessFlags): Corrected broken call
+ * library/tcltest/pkgIndex.tcl: to [lrange]. Bumped to
+ version 2.2.4. [Bug 772333]
+
+2003-07-15 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/dltest/pkga.c (Pkga_EqObjCmd): Fix typo that was causing a
+ crash in load.test.
+
+2003-07-15 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/array.n: Make sure docs are synched with the 8.4 release.
+
+2003-07-15 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/http.n: Updated SYNOPSIS to match actual syntax of commands.
+ [Bug 756112]
+
+ * unix/dltest/pkga.c: Updated to not use Tcl_UtfNcmp and counted
+ strings instead of strcmp (not defined in any #include'd header) and
+ presumed NULL-terminated strings.
+
+ * generic/tclCompCmds.c (TclCompileIfCmd): Prior fix of Bug 711371 on
+ 2003-04-07 introduced a buffer overflow. Corrected. [Bug 771613]
+
+2003-07-15 Kevin B. Kenny <kennykb@acm.org>
+
+ * win/rules.vc: Added a missing $(OPTDEFINES) which broke the build if
+ STATS=memdbg was specified.
+
+2003-07-15 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclCmdIL.c (SortCompare): Cleared up confusing error
+ message. [Bug 771539]
+
+2003-07-11 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * tests/binary.test (binary-46.*): Tests to help enforce the current
+ behaviour.
+ * doc/binary.n: Documented that [binary format a] and [binary scan a]
+ do encoding conversion by dropping high bytes, unlike the rest of the
+ core. [Bug 735364]
+
+2003-07-11 Don Porter <dgp@users.sourceforge.net>
+
+ * library/package.tcl: Corrected [pkg_mkIndex] bug reported on
+ comp.lang.tcl. The indexer was searching for newly indexed packages
+ instead of newly provided packages.
+
+2003-07-08 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * tests/winFCmd.test: fix for five tests under win98 [Bug 767679]
+
+2003-07-07 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * doc/array.n: add examples from Welton
+
+2003-06-23 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * doc/file.n: clarification of 'file tail' behaviour [Bug 737977]
+
+2003-07-04 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/expr.n: Tighten up the wording of some operations. [Bug 758488]
+
+ * tests/cmdAH.test: Made tests of [file mtime] work better on FAT
+ filesystems. [Patch 760768] Also a little general cleanup.
+
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd): Made [string map] accept
+ dictionaries for maps. This is much trickier than it looks, since map
+ entry ordering is significant. [Bug 759936]
+
+ * generic/tclVar.c (Tcl_ArrayObjCmd, TclArraySet): Made [array get]
+ and [array set] work with dictionaries, producing them and consuming
+ them. Note that for compatability reasons, you will never get a dict
+ from feeding a string literal to [array set] since that alters the
+ trace behaviour of "multi-key" sets. [Bug 759935]
+
+2003-06-23 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclTrace.c: fix to Window debug build compilation error.
+
+2003-06-27 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/init.test: Added [cleanupTests] to report results of tests
+ * tests/pkg.test: that run in slave interps. [Bugs 761334,761344]
+
+ * tests/http.test: Used more reliable path to find httpd script.
+
+2003-06-25 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/init.test: Added tests init-4.6.* to illustrate [Bug 760872]
+
+2003-06-25 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclTrace.c: New file, factoring out of virtually all the
+ various trace-related things from tclBasic.c and tclCmdMZ.c with the
+ goal of making this a separate maintenance area.
+
+2003-06-25 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/configure: Regen.
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): Add -ieee when compiling with cc and
+ add -mieee when compiling with gcc under OSF1-V5 "Tru64" systems. [Bug
+ 748957]
+
+2003-06-24 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/encoding.n: Corrected the docs to say that [source] uses the
+ system encoding, which it always did anyway (since 8.1) [Bug 742100]
+
+2003-06-24 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclHash.c (Tcl_HashStats): Prevented occurrence of
+ division-by-zero problems. [Bug 759749]
+
+2003-06-24 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/tclUnixPort.h: #undef inet_ntoa before #define to avoid
+ compiler warning under freebsd. [Bug 745844]
+
+2003-06-23 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ * doc/dde.n: Committed TIP #135 which changes the
+ * win/tclWinDde.c: -exact option to -force. Also cleaned a
+ * tests/winDde.test: bug in the tests.
+ * library/dde/pkgIndex.tcl: Incremented version to 1.2.5
+
+ * doc/dde.n: Committed TIP #120 which provides the
+ * win/tclWinDde.c: dde package for safe interpreters.
+ * tests/winDde.test: Incremented package version to 1.2.4
+ * library/dde/pkgIndex.tcl:
+
+2003-06-23 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclFCmd.c: fix to bad error message when trying to do 'file
+ copy foo ""'. [Bug 756951]
+ * tests/fCmd.test: added two new tests for the bug.
+
+ * win/tclWinFile.c:
+ * win/tclWin32Dll.c: recommitted some filesystem globbing speed-ups,
+ but disabled some on the older Win 95/98/ME where they don't seem to
+ work.
+
+ * doc/FileSystem.3: documentation fix [Bug 720634]
+
+2003-06-18 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclNamesp.c (Tcl_Export): removed erroneous comments. [Bug
+ 756744]
+
+2003-06-17 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * win/makefile.vc: fixes to check-in below so compilation now works
+ again on Windows.
+
+ * generic/tclCmdMZ.c:
+ * tests/regexp.test: fixing of bugs related to regexp and regsub
+ matching of empty strings. Addition of a number of new tests. [Bug
+ 755335]
+
+2003-06-16 Andreas Kupries <andreask@activestate.com>
+
+ * win/Makefile.in: Haven't heard back from David for a week. Now
+ * win/configure: committing the remaining changes.
+ * win/configure.in: Note: In active contact with Helmut Giese about
+ * win/makefile.vc: the borland relatedchanges. This part will see
+ * win/rules.vc: future updates.
+ * win/tcl.m4:
+ * win/makefile.bc:
+
+2003-06-10 Andreas Kupries <andreask@activestate.com>
+
+ * generic/tclConfig.c (ASSOC_KEY): Changed the key to
+ "tclPackageAboutDict" (tcl prefix) to make collisions with the keys of
+ other packages more unlikely.
+
+2003-06-10 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclBasic.c:
+ * generic/tclExecute.c: let TclExecuteObjvInternal call
+ TclInterpReady instead of relying on its callers to do so; fix for the
+ part of [Bug 495830] that is new in 8.4.
+ * tests/interp.test: Added tests 18.9 (knownbug) and 18.10
+
+2003-06-09 Andreas Kupries <andreask@activestate.com>
+
+ * generic/tcl.decls: Ported the changes from the
+ * generic/tcl.h: 'tip-59-implementation' branch into the CVS
+ * generic/tclBasic.c: head. Regenerated stub table. Regenerated the
+ * generic/tclInt.h: configure's scripts, with help from Joe English.
+ * generic/tclDecls.h:
+ * generic/tclStubInit.c:
+ * generic/tclConfig.c:
+ * generic/tclPkgConfig.c:
+ * unix/Makefile.in:
+ * unix/configure.in: The changes in the windows section are not yet
+ * unix/tcl.m4: committed, they await feedback from David
+ * unix/mkLinks: Gravereaux.
+ * doc/RegConfig.3:
+ * mac/tclMacPkgConfig.c:
+ * tests/config.test:
+
+2003-06-09 Don Porter <dgp@users.sourceforge.net>
+
+ * string.test (string-4.15): Added test for [string first] bug
+ reported in Tcl 8.3, where test for all-single-byte-encoded strings
+ was not reliable.
+
+2003-06-04 Joe Mistachkin <joe@mistachkin.com>
+
+ * tools/man2help.tcl: Added duplicate help section checking and
+ * tools/index.tcl: corrected a comment typo for the getTopics proc
+ in index.tcl. [Bug 748700]
+
+2003-06-02 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * win/tclWinFCmd.c:
+ * tests/fCmd.test: fix to [Bug #747575] in which a bad error message
+ is given when trying to rename a busy directory to one with the same
+ prefix, but not the same name. Added three new tests.
+
+2003-05-23 D. Richard Hipp <drh@hwaci.com>
+
+ * win/tclWinTime.c: Add tests to detect and avoid a division by zero
+ in the windows precision timer calibration logic.
+
+2003-05-23 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclObj.c (tclCmdNameType): Converted internal rep
+ management of the cmdName Tcl_ObjType the opposite way, to always use
+ the twoPtrValue instead of always using the otherValuePtr. Previous
+ fix on 2003-05-12 broke several extensions that wanted to poke around
+ with the twoPtrValue.ptr2 value of a cmdName Tcl_Obj, like TclBlend
+ and e4graph. [Bug 726018]
+ Thanks to George Petasis for the bug report and Jacob Levy for testing
+ assistance.
+
+2003-05-23 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/mkLinks: Set the var S to "" at the top of the file to avoid
+ error when user has set S to something. [Tk Bug 739833]
+
+2003-05-22 Daniel Steffen <das@users.sourceforge.net>
+
+ * macosx/Tcl.pbproj/project.pbxproj: added missing references to new
+ source files tclPathObj.c and tclMacOSXFCmd.c.
+
+ * macosx/tclMacOSXBundle.c: fixed a problem that caused only the first
+ call to Tcl_MacOSXOpenVersionedBundleResources() for a given bundle
+ identifier to succeed. This caused the tcl runtime library not to be
+ found in all interps created after the inital one.
+
+2003-05-19 Kevin B. Kenny <kennykb@hippolyta>
+
+ * unix/tclUnixTime.c: Corrected a bug in conversion of non-ASCII
+ chars in the format string.
+
+2003-05-19 Daniel Steffen <das@users.sourceforge.net>
+
+ * macosx/Tcl.pbproj/project.pbxproj: changed tclConfig.sh location in
+ versioned framework subdirectories to be identical to location in
+ framework toplevel; fixed stub library symbolic links to be tcl
+ version specific.
+
+ * unix/tclUnixTime.c: fixed typo.
+
+2003-05-18 Kevin Kenny <kennykb@acm.org>
+
+ * compat/strftime.c: Modified TclpStrftime to return its result in
+ * generic/tclClock.c: UTF-8 encoding, and removed the conversion from
+ * mac/tclMacTime.c: system encoding to UTF-8 from [clock format].
+ * unix/tclUnixTime.c: Needed to avoid double conversion of the
+ * win/tclWinTime.c: timezone name on Windows systems. [Bug 624408]
+
+2003-05-16 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ * library/dde/pkgIndex.tcl: Applied TIP #130 which provides for
+ * tests/winDde.test: unique dde server names. Added some more
+ * win/tclWinDde.c: tests. Fixes [Bug 219293]
+
+ * doc/dde.n: Updated documentation re TIP #130.
+ * tests/winDde.test: Applied patch for [Bug 738929] by KKB and changed
+ to new-style tests.
+
+2003-05-16 Kevin B. Kenny <kennykb@acm.org>
+
+ * unix/Makefile.in: Removed one excess source file tclDToA.c
+
+2003-05-16 Daniel Steffen <das@users.sourceforge.net>
+
+ * macosx/Tcl.pbproj/project.pbxproj: updated copyright year.
+
+2003-05-15 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclGetDate.y: added further hackery to the yacc
+ * generic/tclDate.c: post-processing to arrange for the code to set
+ * unix/Makefile.in: up exit handlers to free the stacks. [Bug
+ 736425]
+
+2003-05-15 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/tclWinFile.c (TclpMatchInDirectory): revert glob code to r1.44
+ as 2003-04-11 optimizations broke Windows98 glob'ing.
+
+ * doc/socket.n: nroff font handling correction
+
+ * library/encoding/gb2312-raw.enc (new): This is the original
+ gb2312.enc renamed to allow for it to still be used. This is needed by
+ Tk (unix) because X fonts with gb2312* charsets really do want the
+ original gb2312 encoding. [Bug 557030]
+
+2003-05-14 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclCmdAH.c (Tcl_FormatObjCmd): Stop unwarranted demotion of
+ wide values to longs by formatting of int values. [Bug 699060]
+
+2003-05-14 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * library/encoding/gb2312.enc: copy euc-cn.enc over original
+ gb2312.enc. gb2312.enc appeared to not work as expected, and most uses
+ of gb2312 really mean euc-cn (which may be the cause of the problem).
+ [Bug 557030]
+
+2003-05-14 Daniel Steffen <das@users.sourceforge.net>
+
+ Implementation of TIP 118:
+
+ * generic/tclFCmd.c (TclFileAttrsCmd): return the list of attributes
+ that can be retrieved without error for a given file, instead of
+ aborting the whole command when any error occurs.
+
+ * unix/tclUnixFCmd.c: added support for new file attributes and for
+ copying Mac OS X file attributes & resource fork during [file copy].
+
+ * generic/tclInt.decls: added declarations of new external commands
+ needed by new file attributes support in tclUnixFCmd.c.
+
+ * macosx/tclMacOSXFCmd.c (new): Mac OS X specific implementation of
+ new file attributes and of attribute & resource fork copying.
+
+ * mac/tclMacFCmd.c: added implementation of -rsrclength attribute &
+ fixes to other attributes for consistency with OSX implementation.
+
+ * mac/tclMacResource.c: fixes to OSType handling.
+
+ * doc/file.n: documentation of [file attributes] changes.
+
+ * unix/configure.in: check for APIs needed by new file attributes.
+
+ * unix/Makefile.in:
+ * unix/tcl.m4: added new platform specifc tclMacOSXFCmd.c source.
+
+ * unix/configure:
+ * generic/tclStubInit.c:
+ * generic/tclIntPlatDecls.h: regen.
+
+ * tools/genStubs.tcl: fixes to completely broken code trying to
+ prevent overlap of "aqua", "macosx", "x11" and "unix" stub entries.
+
+ * tests/unixFCmd.test: added tests of -readonly attribute.
+
+ * tests/macOSXFCmd.test (new): tests of macosx file attributes and of
+ preservation of attributes & resource fork during [file copy].
+
+ * tests/macFCmd.test: restore -readonly attribute of test dir, as
+ otherwise its removal can fail on unices supporting -readonly.
+
+2003-05-13 David Gravereaux <davygrvy@pobox.com>
+
+ * generic/tclEnv.c: Another putenv() copy behavior problem repaired
+ when compiling on windows and using microsoft's runtime. [Bug 736421]
+
+2003-05-13 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclIOUtil.c: ensure cd is thread-safe.
+ [Bug 710642] (vasiljevic)
+
+2003-05-13 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclEvent.c (Tcl_Finalize): Removed unused variable to reduce
+ compiler warnings. [Bug 664745]
+
+2003-05-13 Joe Mistachkin <joe@mistachkin.com>
+
+ * generic/tcl.decls: Changed Tcl_JoinThread parameter name from
+ * generic/tclDecls.h: "id" to "threadId". [Bug 732477]
+ * unix/tclUnixThrd.c:
+ * win/tclWinThrd.c:
+ * mac/tclMacThrd.c:
+
+2003-05-13 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tcl.decls:
+ * macosx/tclMacOSXBundle.c: added extended version of the
+ Tcl_MacOSXOpenBundleResources() API taking an extra version number
+ argument: Tcl_MacOSXOpenVersionedBundleResources(). This is needed to
+ be able to access bundle resources in versioned frameworks such as Tcl
+ and Tk, otherwise if multiple versions were installed, only the latest
+ version's resources could be accessed. [Bug 736774]
+
+ * unix/tclUnixInit.c (Tcl_MacOSXGetLibraryPath): use new versioned
+ bundle resource API to get tcl runtime library for TCL_VERSION. [Bug
+ 736774]
+
+ * generic/tclPlatDecls.h:
+ * generic/tclStubInit.c: regen.
+
+ * unix/tclUnixPort.h: worked around the issue of realpath() not
+ being thread-safe on Mac OS X by defining NO_REALPATH for threaded
+ builds on Mac OS X. [Bug 711232]
+
+2003-05-12 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * tests/cmdAH.test: General clean-up of tests so that all
+ tcltest-specific commands are protected by constraints and all
+ platforms see the same number of tests. [Bug 736431]
+
+2003-05-12 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclInterp.c: (AliasObjCmd): Added refCounting of the words
+ * tests/interp.test (interp-33.1): of the target of an interp
+ alias during its execution. Also added test. [Bug 730244]
+
+ * generic/tclBasic.c (TclInvokeObjectCommand): objv[argc] is no
+ longer set to NULL (Tcl_CreateObjCommand docs already say that it
+ should not be accessed).
+
+ * tests/cmdMZ.test: Forgot to import [temporaryDirectory].
+
+ * generic/tclObj.c (tclCmdNameType): Corrected variable use of the
+ otherValuePtr or the twoPtrValue.ptr1 fields to store a
+ (ResolvedCmdName *) as the internal rep. [Bug 726018]
+
+ * doc/Eval.3: Corrected prototype for Tcl_GlobalEvalObj [Bug 727622].
+
+2003-05-12 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclVar.c (TclObjLookupVar): [Bug 735335] temporary fix,
+ disabling usage of tclNsVarNameType.
+ * tests/var.test (var-15.1): test for [Bug 735335]
+
+2003-05-10 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/tclWinSerial.c (SerialCloseProc): correct mem leak on closing a
+ Windows serial port [Bug 718002] (schroedter)
+
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd): prevent string repeat crash
+ when overflow sizes were given (throws error). [Bug 714106]
+
+2003-05-09 Joe Mistachkin <joe@mistachkin.com>
+
+ * generic/tclThreadAlloc.c (TclFreeAllocCache): Fixed memory leak
+ caused by treating cachePtr as a TLS index. [Bug 731754]
+
+ * win/tclAppInit.c (Tcl_AppInit): Fixed memory leaks caused by not
+ freeing the memory allocated by setargv and the async handler created
+ by Tcl_AppInit. An exit handler has been created that takes care of
+ both leaks. In addition, Tcl_AppInit now uses ckalloc instead of
+ Tcl_Alloc to allow for easier leak tracking and to be more consistent
+ with the rest of the Tcl core. [Bugs 733156, 733221]
+
+ * tools/encoding/txt2enc.c (main): Fixed memory leak caused by failing
+ to free the memory used by the toUnicode array of strings [Bug 733221]
+
+2003-05-09 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompile.c (TclCompileScript):
+ * tests/compile.test (compile-3.5): corrected wrong test and
+ behaviour in the earlier fix for [Bug 705406]; Don Porter reported
+ this as [Bug 735055], and provided the solution.
+
+2003-05-09 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclCmdMZ.c (Tcl_ReturnObjCmd): The array of strings passed
+ to Tcl_GetIndexFromObj must be NULL terminated. [Bug 735186]
+ Thanks to Joe Mistachkin for spotting this.
+
+2003-05-07 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/trace.n: Fixed very strange language in the documentation for
+ 'trace add execution'. [Bug 729821]
+
+ * generic/tclCmdMZ.c (Tcl_TraceObjCmd): Made error message for 'trace
+ info' more consistent with documentation. [Bug 706961]
+
+ * generic/tclDictObj.c (DictInfoCmd): Fixed memory leak caused by
+ confusion about string ownership. [Bug 731706]
+
+2003-05-05 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c: Implementation of TIP 90, which
+ * generic/tclCmdAH.c: extends the [catch] and [return]
+ * generic/tclCompCmds.c: commands to enable creation of a
+ * generic/tclExecute.c: proc that is a replacement for
+ * generic/tclInt.h: [return]. [Patch 531640]
+ * generic/tclProc.c:
+ * generic/tclResult.c:
+ * tests/cmdAH.test:
+ * tests/cmdMZ.test:
+ * tests/error.test:
+ * tests/proc-old.test:
+
+ * library/tcltest/tcltest.tcl: The -returnCodes option to [test]
+ failed to recognize the symbolic name "ok" for return code 0.
+
+2003-05-05 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclBasic.c (Tcl_HideCommand): Fixed error message for
+ grammar and spelling.
+
+2003-04-28 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclDictObj.c (DictIncrCmd): Updated to reflect the behaviour
+ with wide increments of the normal [incr] command.
+ * generic/tclInt.decls: Added TclIncrWideVar2 to internal stub table
+ and cleaned up.
+ * tests/incr.test (incr-3.*):
+ * generic/tclVar.c (TclIncrWideVar2, TclPtrIncrWideVar):
+ * generic/tclExecute.c (TclExecuteByteCode):
+ * generic/tclCmdIL.c (Tcl_IncrObjCmd): Make [incr] work when trying to
+ increment by wide values. [Bug 728838]
+
+ * generic/tclCompCmds.c (TclCompileSwitchCmd): Default mode of
+ operation of [switch] is exact matching. [Bug 727563]
+
+2003-04-25 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c: Tcl_EvalObjv() failed to honor the
+ TCL_EVAL_GLOBAL flag when resolving command names. Tcl_EvalEx passed a
+ string rep including leading whitespace and comments to
+ TclEvalObjvInternal().
+
+2003-04-25 Andreas Kupries <andreask@activestate.com>
+
+ * win/tclWinThrd.c: Applied SF patch #727271. This patch changes the
+ code to catch any errors returned by the windows functions handling
+ TLS ASAP instead of waiting to get some mysterious crash later on due
+ to bogus pointers. Patch provided by Joe Mistachkin.
+
+ This is a stop-gap measure to deal with the low number of ?TLS slots
+ provided by some of the variants of Windows (60-80).
+
+2003-04-24 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclFileName.c: fix to bug reported privately by Jeff where,
+ for example, 'glob -path {[tcl]} *' gets confused by the leading
+ special character (which is escaped internally), and instead lists
+ files in '/'. Bug only occurs on Windows where '\' is also a directory
+ separator.
+ * tests/fileName.test: added test for the above bug.
+
+2003-04-22 Andreas Kupries <andreask@activestate.com>
+
+ * The changes below fix SF bugs [593810], and [718045].
+
+ * generic/tclIO.c (Tcl_CutChannel, Tcl_SpliceChannel): Invoke
+ TclpCutSockChannel and TclpSpliceSockChannel.
+
+ * generic/tclInt.h: Declare TclpCutSockChannel and
+ TclpSpliceSockChannel.
+
+ * unix/tclUnixSock.c (TclpCutSockChannel, TclpSpliceSockChannel):
+ Dummy functions, on unix the sockets are _not_ handled specially.
+
+ * mac/tclMacSock.c (TclpCutSockChannel, TclpSpliceSockChannel):
+ * win/tclWinSock.c (TclpCutSockChannel, TclpSpliceSockChannel): New
+ functions to handle socket specific cut/splice operations: auto-init
+ of socket system for thread on splice, management of the module
+ internal per-thread list of sockets, management of association of
+ sockets with HWNDs for event notification.
+
+ * win/tclWinSock.c (NewSocketInfo): Extended initialization
+ assignments to cover all items of the structure. During debugging of
+ the new code mentioned above I found that two fileds could contain
+ bogus data.
+
+ * win/tclWinFile.c: Added #undef HAVE_NO_FINDEX_ENUMS before
+ definition because when compiling in debug mode the compiler complains
+ about a redefinition, and this warning is also treated as an error.
+
+2003-04-21 Don Porter <dgp@users.sourceforge.net>
+
+ * library/tcltest/tcltest.tcl: When the return code of a test does
+ not meet expectations, report that as the reason for test failure, and
+ do not attempt to check the test result for correctness. [Bug 725253]
+
+2003-04-18 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/tclWinInt.h (VER_PLATFORM_WIN32_CE): conditionally define.
+ * win/tclWinInit.c: recognize Windows CE as a Win platform. This just
+ recognizes CE - full support will come later.
+
+ * win/configure: regen
+ * win/configure.in (SHELL): force it to /bin/sh as autoconf 2.5x
+ uses /bin/bash, which can fail to find exes in the path (ie: lib).
+
+ * generic/tclExecute.c (ExprCallMathFunc): remove incorrect
+ extraneous cast from Tcl_WideAsDouble.
+
+2003-04-18 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/open.n: Moved serial port options from [fconfigure] to
+ * doc/fconfigure.n: [open] as it is up to the creator of a channel
+ to describe the channel's special config
+ options. [Bug 679010]
+
+2003-04-16 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tcl.h: Made changes so that the "wideInt" Tcl_ObjType
+ * generic/tclObj.c: is defined on all platforms, even those where
+ * generic/tclPort.h: TCL_WIDE_INT_IS_LONG is defined. Also made the
+ Tcl_Value struct have a wideValue field on all platforms. This is a
+ ***POTENTIAL INCOMPATIBILITY*** for TCL_WIDE_INT_IS_LONG platforms
+ because that struct changes size. This is the same TIP 72
+ incompatibility that was seen on other platforms at the 8.4.0 release,
+ when this change should have happened as well. [Bug 713562]
+
+ * generic/tclInt.h: New internal macros TclGetWide() and
+ TclGetLongFromWide() to deal with both forms of the "wideInt"
+ Tcl_ObjType, so that conditional TCL_WIDE_INT_IS_LONG code is confined
+ to the header file.
+
+ * generic/tclCmdAH.c: Replaced most coding that was conditional
+ * generic/tclCmdIL.c: on TCL_WIDE_INT_IS_LONG with code that
+ * generic/tclExecute.c: works across platforms, sometimes using
+ * generic/tclTest.c: the new macros above to do it.
+ * generic/tclUtil.c:
+ * generic/tclVar.c:
+
+2003-04-17 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/socket.n: Added a paragraph to remind people to specify their
+ encodings when using sockets. [Bug 630621]
+
+2003-04-16 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/CrtMathFnc.3: Functions also have to deal with wide ints, but
+ this was not documented. [Bug 709720]
+
+2003-04-16 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclPathObj.c: removed undesired 'static' for function which
+ is now shared (previously it was duplicated).
+
+2003-04-15 Joe English <jenglish@users.sourceforge.net>
+
+ * doc/namespace.n: added example section "SCOPED SCRIPTS", supplied by
+ Kevin Kenny. [Bug 219183]
+
+2003-04-15 Kevin Kenny <kennykb@acm.org>
+
+ * makefile.vc: Updated makefile.vc to conform with Mo DeJong's changes
+ to Makefile.in and tclWinPipe.c on 2003-04-14. Now passes TCL_PIPE_DLL
+ in place of TCL_DBGX.
+ * win/tclWinTime.c: Corrected use of types to make compilation
+ compatible with VC++5.
+
+2003-04-15 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclIOUtil.c: finished check-in from yesterday, removing
+ duplicate function definition.
+
+2003-04-14 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclClock.c: Corrected compiler warnings.
+ * generic/tclTest.c:
+
+2003-04-14 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/Makefile.in: Don't define TCL_DBGX symbol for every compile.
+ Instead, define TCL_PIPE_DLL only when compiling tclWinPipe.c. This
+ will break other build systems, so they will need to remove the
+ TCL_DBGX define and replace it with a define for TCL_PIPE_DLL.
+ * win/tclWinPipe.c (TclpCreateProcess): Remove PREFIX_IDENT and
+ DEBUG_IDENT from top of file. Use TCL_PIPE_DLL passed in from build
+ env instead of trying to construct the dll name from already defined
+ symbols. This approach is more flexible and better in the long run.
+
+2003-04-14 Kevin Kenny <kennykb@acm.org>
+
+ * win/tclWinFile.c: added conditionals to restore compilation on
+ VC++6, which was broken by recent changes.
+
+2003-04-14 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclIOUtil.c:
+ * generic/tclPathObj.c:
+ * generic/tclFileSystem.h: overlooked one function which was
+ duplicated, so this is now shared between modules.
+ * win/tclWinFile.c: allow this file to compile with VC++ 5.2 again
+ since Mingw build fixes broke that.
+
+2003-04-13 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/configure: Regen.
+ * win/configure.in: Add check for FINDEX_INFO_LEVELS from winbase.h,
+ known to be a problem in VC++ 5.2. Define HAVE_NO_FINDEX_ENUMS if the
+ define does not exist.
+ * win/tclWinFile.c: Put declarations for FINDEX_INFO_LEVELS and
+ FINDEX_SEARCH_OPS inside a check for HAVE_NO_FINDEX_ENUMS so that
+ these are not declared twice. This fixes the Mingw build.
+ * win/tclWinTime.c: Rework the init of timeInfo so that the number or
+ initializers matches the declaration. This was broken under Mingw. Add
+ cast to avoid compile warning when calling the AccumulateSample
+ function.
+
+2003-04-12 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/Makefile.in (GENERIC_OBJS): add missing tclPathObj.c
+
+2003-04-12 Kevin Kenny <kennykb@acm.org>
+
+ * doc/clock.n:
+ * generic/tclClock.c (Tcl_ClockObjCmd):
+ * tests/clock.test: Implementation of TIP #124. Also renumbered test
+ cases to avoid duplicates. [Bug 710310]
+ * tests/winTime.test:
+ * win/tclWinTest.c (TestwinclockCmd, TestwinsleepCmd):
+ * win/tclWinTime.c (Tcl_WinTime, UpdateTimeEachSecond,
+ (ResetCounterSamples, AccumulateSample, SAMPLES, TimeInfo): Made
+ substantial changes to the phase-locked loop (replaced an IIR filter
+ with an FIR one) in a quest for improved loop stability (Bug not
+ logged at SF, but cited in private communication from Jeff Hobbs).
+
+2003-04-11 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd,STR_IS_INT): Corrected
+ inconsistent results of [string is integer] observed on systems where
+ sizeof(long) != sizeof(int). [Bug 718878]
+ * tests/string.test: Added tests for Bug 718878.
+ * doc/string.n: Clarified that [string is integer] accepts 32-bit
+ integers.
+
+2003-04-11 Andreas Kupries <andreask@activestate.com>
+
+ * generic/tclIO.c (UpdateInterest): When dropping interest in
+ TCL_READABLE now dropping interest in TCL_EXCEPTION too. This fixes a
+ bug where Expect detects eof on a file prematurely on solaris 2.6 and
+ higher. A much more complete explanation is in the code itself (40
+ lines of comments for a one-line change :)
+
+2003-04-11 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * tests/cmdAH.test: fix test suite problem if /home is a symlink. [Bug
+ 703264]
+ * generic/tclIOUtil.c: fix bad error message with 'cd ""'. [Bug
+ 704917]
+ * win/tclWinFile.c, win/tclWin32Dll.c:
+ * win/tclWinInt.h: allow Tcl to differentiate between reparse points
+ which are symlinks and mounted volumes, and correctly handle the
+ latter. This involves some elaborate code to find the actual drive
+ letter (if possible) corresponding to a mounted volume. [Bug 697862]
+ * tests/fileSystem.test: add constraints to stop tests running in
+ ordinary tcl interpreter. [Bug 705675]
+
+ * generic/tclIOUtil.c:
+ * generic/tclPathObj.c: (new file)
+ * generic/tclFileSystem.h: (new file)
+ * win/makefile.vc:
+ Split path object handling out of the virtual filesystem layer, into
+ tclPathObj.c. This refactoring cleans up the internal filesystem code,
+ and will make any future optimisations and forthcoming better
+ thread-safety much easier.
+
+ * generic/tclTest.c:
+ * tests/reg.test: added some 'knownBug' tests for problems in Tcl's
+ regexp code with the TCL_REG_CAN_MATCH flag (see Bug 703709). Code too
+ impenetrable to fix right now, but a fix is needed for tip113 to work
+ correctly.
+
+ * tests/fCmd.test
+ * win/tclWinFile.c: added some filesystem optimisation to the 'glob'
+ implementation, and some new tests.
+
+ * generic/tclCmdMZ.c: fix typo in comment
+
+ * tests/winFile.test:
+ * tests/ioUtil.test:
+ * tests/unixFCmd.test: renumbered tests with duplicate numbers. [Bug
+ 710361]
+
+2003-04-10 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/binary.n: Fixed typo in [binary format w] desc. [Bug 718543]
+
+2003-04-08 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclCmdAH.c (Tcl_ErrorObjCmd): Strings are only empty if
+ they have zero length, not if their first byte is zero, so fix test
+ guarding Tcl_AddObjErrorInfo to take this into account. [Bug
+ reported by Don Porter; no bug-id.]
+
+2003-04-07 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCompCmds.c (TclCompileIfCmd): Corrected string limits of
+ arguments interpolated in error messages. [Bug 711371]
+
+ * generic/tclCmdMZ.c (TraceExecutionProc): Added missing
+ Tcl_DiscardResult() call to avoid memory leak.
+
+2003-04-07 Donal K. Fellows <zzcgudf@ernie.mvc.mcc.ac.uk>
+
+ * generic/tclDictObj.c (Tcl_DictObjCmd): Stopped compilers from
+ moaning about switch fall-through. [Bug 716327]
+ (DictFilterCmd): Yet more warning killing, this time reported by
+ Miguel Sofer by private chat.
+
+2003-04-07 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * tests/dict.test (dict-2.6):
+ * generic/tclDictObj.c (Tcl_NewDictObj, Tcl_DbNewDictObj): Oops!
+ Failed to fully initialise the Dict structure.
+ (DictIncrCmd): Moved valueAlreadyInDictionary label to stop compiler
+ complaints. [Bug 715751]
+
+ * generic/tclDictObj.c (DictIncrCmd): Followed style in the rest of
+ the core by commenting out wide-specific operations on platforms where
+ wides are longs, and used longs more thoroughly than ints through
+ [dict incr] anyway to forestall further bugs.
+ * generic/tclObj.c: Made sure there's always a tclWideIntType
+ implementation available, not that it is always useful. [Bug 713562]
+
+2003-04-05 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclDictObj.c: Removed commented out notes on declarations to
+ be moved to elsewhere in the Tcl core.
+
+ * generic/tclInt.h: Final stages of plumbing in.
+ * generic/tclBasic.c:
+ * generic/tclObj.c (TclInitObjSubsystem):
+
+ * unix/Makefile.in, win/Makefile.in, win/makefile.[bv]c: Build support.
+ * generic/tcl.decls: Added dict public API to stubs table.
+ * generic/tcl.h (Tcl_DictSearch): Added declaration of structure to
+ allow user code to iterate over dictionaries.
+
+ * doc/DictObj.3: New files containing dictionary implementation
+ * doc/dict.n: documentation and tests as as mandated by TIP
+ * generic/tclDictObj.c: #111.
+ * tests/dict.test:
+
+2003-04-03 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/configure:
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): Don't set TCL_LIBS if it is already
+ set to support use of TCL_LIBS var from tclConfig.sh in the Tk
+ configure script.
+
+2003-04-03 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/Makefile.in: Don't subst MATH_LIBS, LIBS, and DL_LIBS
+ separately. Instead, just subst TCL_LIBS since it includes the
+ others.
+ * unix/configure: Regen.
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS, SC_TCL_LINK_LIBS): Set and subst
+ TCL_LIBS in SC_CONFIG_CFLAGS instead of SC_TCL_LINK_LIBS. Don't subst
+ MATH_LIBS since it is now covered by TCL_LIBS.
+ * unix/tclConfig.sh.in: Use TCL_LIBS instead of DL_LIBS, LIBS, and
+ MATH_LIBS.
+ * unix/dltest/Makefile.in: Ditto.
+
+2003-04-03 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCompCmds.c (TclCompileReturnCmd): Now that [return]
+ compiles to INST_RETURN, it is safe to compile even outside a proc.
+
+2003-04-02 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/configure: Regen.
+ * win/configure.in: Set stub lib flag based on new LIBFLAGSUFFIX
+ variable.
+ * win/tcl.m4 (SC_CONFIG_CFLAGS): Set new LIBFLAGSUFFIX that works like
+ LIBSUFFIX, it is used when creating library names. The previous
+ implementation would generate -ltclstub85 instead of -ltclstub85s when
+ configured with --disable-shared.
+
+2003-04-02 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclParse.c (TclSubstTokens): Moved declaration of
+ utfCharBytes to beginning of procedure so that it does not go out of
+ scope (get free()d) while append is still pointing to it. [Bugs
+ 703167, 713754]
+
+2003-04-01 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/configure: Regen.
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): Check for inet_ntoa in -lbind inside
+ the BeOS block since doing it later broke the build under SuSE 7.3.
+ [Bug 713128]
+
+2003-04-01 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/README: Direct [source] of *.test files is no longer
+ recommended. The tests/*.test files should only be evaluated under the
+ control of the [runAllTests] command in tests/all.tcl.
+
+ * generic/tclExecute.c (INST_RETURN): Bytecompiled [return] failed to
+ reset iPtr->returnCode, causing tests parse-18.17 and parse-18.21 to
+ fail strangely.
+ * tests/parse.test (parse-18.21): Corrected now functioning test.
+ Added further coverage tests.
+
+2003-03-31 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/parse.test (parse-18.*): Coverage tests for the new
+ implementation of Tcl_SubstObj(). Note that tests parse-18.17 and
+ parse-18.21 demonstrate some bugs left to fix in the current code.
+
+2003-03-27 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/configure: Regen.
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): Use -Wl,--export-dynamic instead of
+ -rdynamic for LDFLAGS. The -rdynamic is not documented so it seems
+ better to pass the --export-dynamic flag to the linker. [Patch 573395]
+
+2003-03-27 Miguel Sofer <msofer@users.sf.net>
+
+ * tests/encoding.test:
+ * tests/proc-old.test:
+ * tests/set-old.test: Altered test numers to eliminate duplicates,
+ [Bugs 710313, 710320, 710352]
+
+2003-03-27 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * tests/parseOld.test: Altered test numers to eliminate duplicates.
+ * tests/parse.test: [Bugs 710365, 710369]
+ * tests/expr-old.test:
+ * tests/expr.test:
+
+ * tests/utf.test: Altered test numers to eliminate duplicates.
+ * tests/trace.test: [Bugs 710322, 710327, 710349, 710363]
+ * tests/lsearch.test:
+ * tests/list.test:
+ * tests/info.test:
+ * tests/incr-old.test:
+ * tests/if-old.test:
+ * tests/format.test:
+ * tests/foreach.test:
+
+2003-03-26 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/configure: Regen.
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS, SC_TCL_LINK_LIBS): Add BeOS system to
+ SC_CONFIG_CFLAGS. Check for inet_ntoa in -lbind, needed for BeOS.
+
+2003-03-26 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/tcltest.n:
+ * library/tcltest/tcltest.tcl: Added reporting during [configure
+ -debug 1] operations to warn about multiple uses of the same test
+ name. [FRQ 576693]
+
+ * tests/msgcat.test (msgcat-2.2.1): changed test name to avoid
+ duplication. [Bug 710356]
+
+ * unix/dltest/pkg?.c: Changed all Tcl_InitStubs calls to pass
+ argument exact = 0, so that rebuilds are not required when Tcl
+ bumps to a new version. [Bug 701926]
+
+2003-03-24 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclVar.c:
+ * tests/var.test: fixing ObjMakeUpvar's lookup algorithm for the
+ created local variable. [Bug 631741] (Chris Darroch) and [Bug 696893]
+ (David Hilker)
+
+2003-03-24 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ * library/dde/pkgIndex.tcl: bumped version to 1.2.2 in tclWinDde.c,
+ now adding here too.
+
+2003-03-22 Kevin Kenny <kennykb@acm.org>
+
+ * library/dde/pkgIndex.tcl:
+ * library/reg/pkgIndex.tcl: Fixed a bug where [package require dde]
+ or [package require registry] attempted to load the release version
+ of the DLL into a debug build. [Bug 708218] Thanks to Joe Mistachkin
+ for the patch.
+ * win/makefile.vc: Added quoting around the script name in the 'test'
+ target; Joe Mistachkin insists that he has a configuration that fails
+ to launch tcltest without it, and it appears harmless otherwise.
+
+2003-03-22 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ * win/tclWinDde.c: Make dde services conform the the documentation
+ such that giving only a topic name really returns all services with
+ that topic. [Bug 219155]
+ Prevent hangup caused by dde server applications failing to process
+ messages. [Bug 707822]
+ * tests/winDde.test: Corrected labels and added a test for search by
+ topic name.
+
+2003-03-20 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclInt.h (tclOriginalNotifier):
+ * generic/tclStubInit.c (tclOriginalNotifier):
+ * mac/tclMacNotify.c (Tcl_SetTimer,Tcl_WaitForEvent):
+ * unix/tclUnixNotfy.c (Tcl_SetTimer,Tcl_WaitForEvent,
+ (Tcl_CreateFileHandler,Tcl_DeleteFileHandler):
+ * win/tclWinNotify.c (Tcl_SetTimer,Tcl_WaitForEvent): Some linkers
+ apparently use a different representation for a pointer to a function
+ within the same compilation unit and a pointer to a function in a
+ different compilation unit. This causes checks like those in the
+ original notifier procedures to fall into infinite loops. The fix is
+ to store pointers to the original notifier procedures in a struct
+ defined in the same compilation unit as the stubs tables, and compare
+ against those values. [Bug 707174]
+
+ * generic/tclInt.h: Removed definition of ParseValue struct that is
+ no longer used.
+
+2003-03-19 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompile.c:
+ * tests/compile.test: bad command count on TCL_OUT_LINE_COMPILE.
+ [Bug 705406] (Don Porter)
+
+2003-03-19 Don Porter <dgp@users.sourceforge.net>
+
+ * library/auto.tcl: Replaced [regexp] and [regsub] with
+ * library/history.tcl: [string map] where possible. Thanks
+ * library/ldAout.tcl: to David Welton. [Bugs 667456,667558]
+ * library/safe.tcl: Bumped to http 2.4.3, opt 0.4.5, and
+ * library/http/http.tcl: tcltest 2.2.3.
+ * library/http/pkgIndex.tcl:
+ * library/opt/optparse.tcl:
+ * library/opt/pkgIndex.tcl:
+ * library/tcltest/tcltest.tcl:
+ * library/tcltest/pkgIndex.tcl:
+ * tools/genStubs.tcl:
+ * tools/tcltk-man2html.tcl:
+ * unix/mkLinks.tcl:
+
+ * doc/Eval.3 (Tcl_EvalObjEx): Corrected CONST and
+ * doc/ParseCmd.3 (Tcl_EvalTokensStandard): return type errors in
+ documentation. [Bug 683994]
+
+ * generic/tclCompCmds.c (TclCompileReturnCmd): Alternative fix for
+ * generic/tclCompile.c (INST_RETURN): [Bug 633204] that uses a new
+ * generic/tclCompile.h (INST_RETURN): bytecode INST_RETURN to
+ * generic/tclExecute.c (INST_RETURN): properly bytecode the [return]
+ command to something that returns TCL_RETURN.
+
+2003-03-18 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/configure: Regen.
+ * win/configure.in: Don't run the AC_CYGWIN macro since it uses
+ AC_CANONICAL_HOST under autoconf 2.5X. Just check to see if __CYGWIN__
+ is defined by the compiler and set the ac_cv_cygwin variable based on
+ that. [Bug 705912]
+
+2003-03-18 Kevin Kenny <kennykb@users.sourceforge.net>
+
+ * tests/registry.test: Changed the conditionals to avoid an abort if
+ [testlocale] is missing, as when running the test in tclsh rather than
+ tcltest. [Bug 705677]
+
+2003-03-18 Daniel Steffen <das@users.sourceforge.net>
+
+ * tools/tcltk-man2html.tcl: added support for building 'make html'
+ from inside distribution directories named with 8.x.x version numbers.
+ tcltk-man2html now uses the latest tcl8.x.x resp. tk8.x.x directories
+ found inside its --srcdir argument.
+
+2003-03-17 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * tests/format.test: Renumber tests, a bunch of tests all had the same
+ id.
+
+2003-03-17 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/lsearch.n: Altered documentation of -ascii options so
+ * doc/lsort.n: they don't specify that they operate on ASCII
+ strings, which they never did anyway. [Bug
+ 703807]
+
+2003-03-14 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclCmdAH.c (Tcl_FormatObjCmd): Only add the modifier that
+ indicates we've got a wide int when we're formatting in an integer
+ style. Stops some libc's from going mad. [Bug 702622] Also tidied
+ whitespace.
+
+2003-03-13 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/tcl.m4 (SC_WITH_TCL): Port version number fix that was made in
+ tk instead of tcl sources.
+
+2003-03-13 Mo DeJong <mdejong@users.sourceforge.net>
+
+ Require autoconf 2.57 or newer, see TIP 34 for a detailed explanation
+ of why this is good. This will no doubt break the build on some
+ platforms, let the flaming begin.
+
+ * tools/configure: Regen with autoconf 2.57.
+ * tools/configure.in: Require autoconf 2.57.
+ * unix/configure: Regen with autoconf 2.57.
+ * unix/configure.in: Require autoconf 2.57.
+ Apply AC_LIBOBJ changes from patch 529884.
+ * unix/tcl.m4: Ditto.
+ * win/configure: Regen with autoconf 2.57.
+ * win/configure.in: Require autoconf 2.57.
+ Don't subst LIBOBJS since this happens by default, this avoids an
+ autoconf error.
+
+2003-03-12 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c (Tcl_EvalTokensStandard):
+ * generic/tclCmdMZ.c (Tcl_SubstObj):
+ * generic/tclCompCmds.c (TclCompileSwitchCmd):
+ * generic/tclCompExpr.c (CompileSubExpr):
+ * generic/tclCompile.c (TclSetByteCodeFromAny,TclCompileScript,
+ (TclCompileTokens,TclCompileCmdWord):
+ * generic/tclCompile.h (TclCompileScript):
+ * generic/tclExecute.c (TclCompEvalObj):
+ * generic/tclInt.h (Interp,TCL_BRACKET_TERM,TclSubstTokens):
+ * generic/tclParse.c (ParseTokens,Tcl_SubstObj,TclSubstTokens):
+ * tests/subst.test (2.4, 8.7, 8.8, 11.4, 11.5):
+ Substantial refactoring of Tcl_SubstObj to make use of the same
+ parsing and substitution procedures as normal script evaluation.
+ Tcl_SubstObj() moved to tclParse.c. New routine TclSubstTokens()
+ created in tclParse.c which implements all substantial functioning of
+ Tcl_EvalTokensStandard(). TclCompileScript() loses its "nested"
+ argument, the Tcl_Interp struct loses its termOffset field and the
+ TCL_BRACKET_TERM flag in the evalFlags field, all of which were only
+ used (indirectly) by Tcl_SubstObj(). Tests subst-8.7,8.8,11.4,11.5
+ modified to accomodate the only behavior change: reporting of parse
+ errors now takes precedence over [return] and [continue] exceptions.
+ All other behavior should remain compatible. [RFE 536831,684982] [Bug
+ 685106]
+
+ * generic/tcl.h: Removed TCL_PREFIX_IDENT and TCL_DEBUG_IDENT
+ * win/tclWinPipe.c: from tcl.h -- they are not part of Tcl's
+ public interface. Put them in win/tclWinPipe.c where they are used.
+
+ * generic/tclInterp.c (Tcl_InterpObjCmd): Corrected and added
+ * tests/interp.test (interp-2.13): test for option
+ parsing beyond objc for [interp create --]. Thanks to Marco Maggi.
+ [Bug 702383]
+
+2003-03-11 Kevin Kenny <kennykb@users.sourceforge.net>
+
+ * win/makefile.vc: Added two missing uses of $(DBGX) so that
+ tclpip8x.dll loads without panicking on Win9x.
+
+2003-03-09 Kevin Kenny <kennykb@users.sourceforge.net>
+
+ * generic/tclTest.c (TestChannelCmd): Removed an unused local variable
+ that caused compilation problems on some platforms.
+
+2003-03-08 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/tcltest.n: Added missing "-body" to example. Thanks to Helmut
+ Giese. [Bug 700011]
+
+2003-03-07 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * tests/io.test:
+ * tests/ioCmd.test: Define a fcopy constraint and add it to the
+ constraint list of any test that depends on the fcopy command. This is
+ only useful to Jacl which does not support fcopy.
+
+2003-03-07 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * tests/encoding.test: Name temp files *.tcltestout instead of *.out
+ so that when they are removed later, we don't accidently toast any
+ files named *.out that the user has created in the build directory.
+
+2003-03-07 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclCmdAH.c (Tcl_FileObjCmd): Fix the setting of a file's
+ mtime and atime on 64-bit platforms. [Bug 698146]
+
+2003-03-06 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * tests/io.test: Doh! Undo accidental commenting out of a couple of
+ tests.
+
+2003-03-06 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * tests/io.test: Define a fileevent constraint and add it to the
+ constraint list of any test that depends on the fileevent command.
+ This is only useful to Jacl which does not support fileevent.
+
+2003-03-06 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * tests/io.test: Define an openpipe constraint and add it to the
+ constraint list of any test that creates a pipe using the open
+ command. This is only useful to Jacl which does not support pipes.
+
+2003-03-06 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/TclUtf.c (Tcl_UniCharNcasecmp): Corrected failure to
+ * tests/utf.test (utf-25.*): properly compare Unicode strings of
+ different case in a case insensitive manner. [Bug 699042]
+
+2003-03-06 Kevin Kenny <kennykb@users.sourceforge.net>
+
+ * generic/tclCompCmds.c (TclCompileSwitchCmd):
+ Replaced a non-portable 'bzero' with a portable 'memset'. [Bug 698442]
+
+2003-03-06 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * generic/tclIO.c (Tcl_Seek, Tcl_OutputBuffered): If there is data
+ buffered in the statePtr->curOutPtr member then set the BUFFER_READY
+ flag in Tcl_Seek. This is needed so that the next call to FlushChannel
+ will write any buffered bytes before doing the seek. The existing code
+ would set the BUFFER_READY flag inside the Tcl_OutputBuffered
+ function. This was a programming error made when Tcl_OutputBuffered
+ was originally created in CVS revision 1.35. The setting of the
+ BUFFER_READY flag should not have been included in the
+ Tcl_OutputBuffered function.
+ * generic/tclTest.c (TestChannelCmd): Use the Tcl_InputBuffered and
+ Tcl_OutputBuffered util methods to query the amount of buffered input
+ and output.
+
+2003-03-06 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * generic/tclIO.c (Tcl_Flush): Compare the nextAdded member of the
+ ChannelBuffer to the nextRemoved member to determine if any output has
+ been buffered. The previous check against the value 0 seems to have
+ just been a coding error. See other methods like Tcl_OutputBuffered
+ for examples where nextAdded is compared to nextRemoved to find the
+ number of bytes buffered.
+
+2003-03-06 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * generic/tclIO.c (Tcl_GetsObj): Check that the eol pointer has not
+ gone past the end of the string when in auto translation mode and the
+ INPUT_SAW_CR flag is set. The previous code worked because the end of
+ string value \0 was being compared to \n, this patch just skips that
+ pointless check.
+
+2003-03-06 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * generic/tclIO.c (WriteBytes, WriteChars, Tcl_GetsObj, ReadBytes):
+ Rework calls to TranslateOutputEOL to make it clear that a boolean
+ value is being returned. Add some comments in an effort to make the
+ code more clear. This patch makes no functional changes.
+
+2003-03-06 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * generic/tclIO.c (Tcl_SetChannelOption): Invoke the
+ Tcl_SetChannelBufferSize method as a result of changing the
+ -buffersize option to fconfigure. The previous implementation used
+ some inlined code that reset the buffer size to the default size
+ instead of ignoring the request as implemented in
+ Tcl_SetChannelBufferSize.
+ * tests/io.test: Update test case so that it actually checks the
+ implementation of Tcl_SetChannelBufferSize.
+
+2003-03-05 David Gravereaux <davygrvy@pobox.com>
+
+ * win/rules.vc: updated default tcl version to 8.5.
+
+2003-03-05 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * generic/tclCompCmds.c (TclCompileSwitchCmd): First attempt at a
+ bytecode-compiled switch command. It only handles the most common case
+ of switching, but that should be enough for this to speed up a lot of
+ people's code. It is expected that the speed gains come from two
+ things: better handling of the switch itself, and integrated
+ compilation of the arms instead of embedding separate bytecode
+ sequences (i.e. better local variable handling.)
+ * tests/switch.test (switch-10.*): Tests of both uncompiled and
+ compiled switch behaviour. [Patch #644819]
+
+ * generic/tclCompile.h (TclFixupForwardJumpToHere): Additional macro
+ to make the most common kind of jump fixup a bit easier.
+
+2003-03-04 Don Porter <dgp@users.sourceforge.net>
+
+ * README: Bumped version number of
+ * generic/tcl.h: Tcl to 8.5a0.
+ * library/init.tcl:
+ * mac/README:
+ * macosx/Tcl.pbproj/project.pbxproj:
+ * tests/basic.test:
+ * tools/configure.in:
+ * tools/tcl.hpj.in:
+ * tools/tcl.wse.in:
+ * unix/configure.in:
+ * unix/tcl.spec:
+ * win/README:
+ * win/README.binary:
+ * win/configure.in:
+ * win/makefile.bc:
+ * win/makefile.vc:
+ * win/tcl.m4:
+
+ * tools/configure: autoconf
+ * unix/configure:
+ * win/configure:
+
+2003-03-03 Jeff Hobbs <jeffh@ActiveState.com>
+
+ *** 8.4.2 TAGGED FOR RELEASE ***
+
+2003-03-03 Daniel Steffen <das@users.sourceforge.net>
+
+ Mac OS Classic specific fixes:
+ * generic/tclIOUtil.c (TclNewFSPathObj): on TCL_PLATFORM_MAC, skip
+ potential directory separator at the beginning of addStrRep.
+ * mac/tclMacChan.c (OpenFileChannel, CommonWatch): followup fixes to
+ cut and splice implementation for file channels.
+ * mac/tclMacFile.c (TclpUtime): pass native path to utime().
+ * mac/tclMacFile.c (TclpObjLink): correctly implemented creation of
+ alias files via new static proc CreateAliasFile().
+ * mac/tclMacPort.h: define S_ISLNK macro to fix stat'ing of links.
+ * mac/tclMacUtil.c (FSpLocationFromPathAlias): fix to enable stat'ing
+ of broken links.
+
+2003-03-03 Kevin Kenny <kennykb@users.sourceforge.net>
+
+ * win/Makefile.vc: corrected bug introduced by 'g' for debug builds.
+
+2003-03-03 Don Porter <dgp@users.sourceforge.net>
+
+ * library/dde/pkgIndex.tcl: dde bumped to version 1.2.1 for
+ * win/tclWinDde.c: bundled release with Tcl 8.4.2
+
+ * library/reg/pkgIndex.tcl: registry bumped to version 1.1.1 for
+ * win/tclWinReg.c: bundled release with Tcl 8.4.2
+
+ * library/opt/pkgIndex.tcl: updated package index to version 0.4.4
+
+2003-02-28 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/configure:
+ * win/configure.in: check for 'g' for debug build type, not 'd'.
+ * win/rules.vc (DBGX): correct to use 'g' for nmake win makefile to
+ match the cygwin makefile for debug builds. [Bug 635107]
+
+2003-02-28 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * doc/file.n: subcommand is 'file volumes' not 'file volume'
+
+2003-02-27 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclIOUtil.c (MakeFsPathFromRelative): removed dead code
+ check of typePtr (darley).
+
+ * tests/winTime.test: added note about PCI hardware dependency issues
+ with high performance clock.
+
+2003-02-27 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * tests/lsearch.test (lsearch-10.7):
+ * generic/tclCmdIL.c (Tcl_LsearchObjCmd): Stopped -start option from
+ causing an option when used with an empty list. [Bug 694232]
+
+2003-02-26 Chengye Mao <chengye.geo@yahoo.com>
+
+ * win/tclWinInit.c: fixed a bug in TclpSetVariables by initializing
+ dwUserNameLen with the sizeof(szUserName) before calling GetUserName.
+ Don't know if this bug has been recorded: it caused crash in starting
+ Tcl or wish in Windows.
+
+2003-02-26 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclCmdMZ.c (TraceCommandProc): Fix mem leak when deleting a
+ command that had trace on it. [Bug 693564] (sofer)
+
+2003-02-25 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/pkgMkIndex.n: Modified [pkg_mkIndex] to use -nocase matching
+ * library/package.tcl: of -load patterns, to better accomodate common
+ user errors due to confusion between [package names] names and [info
+ loaded] names.
+
+2003-02-25 Andreas Kupries <andreask@pliers.activestate.com>
+
+ * tests/pid.test: See below [Bug 678412].
+ * tests/io.test: Made more robust against spaces in paths [Bug 678400]
+
+2003-02-25 Miguel Sofer <msofer@users.sf.net>
+
+ * tests/execute.test: cleaning up testobj's at the end, to avoid
+ leak warning by valgrind.
+
+2003-02-22 Zoran Vasiljevic <zoran@archiwrae.com>
+
+ * generic/tclEvent.c (Tcl_FinalizeThread): Fix [Bug 571002]
+
+2003-02-21 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * tests/binary.test (binary-44.[34]):
+ * generic/tclBinary.c (ScanNumber): Fixed problem with unwanted
+ sign-bit propagation when scanning wide ints. [Bug 690774]
+
+2003-02-21 Daniel Steffen <das@users.sourceforge.net>
+
+ * mac/tclMacChan.c (TclpCutFileChannel, TclpSpliceFileChannel):
+ Implemented missing cut and splice procs for file channels.
+
+2003-02-21 Don Porter <dgp@users.sourceforge.net>
+
+ * library/package.tcl (tclPkgUnknown): Minor performance tweaks to
+ reduce the number of [file] invocations. Meant to improve startup
+ times, at least a little bit. [Patch 687906]
+
+2003-02-20 Daniel Steffen <das@users.sourceforge.net>
+
+ * unix/tcl.m4:
+ * unix/tclUnixPipe.c: (macosx) use vfork() instead of fork() to create
+ new processes, as recommended by Apple (vfork can be up to 100 times
+ faster thank fork on macosx).
+ * unix/configure: regen.
+
+2003-02-20 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclEncoding.c (LoadTableEncoding):
+ * library/encoding/cp932.enc: Correct jis round-trip encoding
+ * library/encoding/euc-jp.enc: by adding 'R' type to .enc files.
+ * library/encoding/iso2022-jp.enc: [Patch 689341] (koboyasi, taguchi)
+ * library/encoding/jis0208.enc:
+ * library/encoding/shiftjis.enc:
+ * tests/encoding.test:
+
+ * unix/tclUnixChan.c (Tcl_MakeTcpClientChannel): add
+ MakeTcpClientChannelMode that takes actual mode flags to avoid hang on
+ OS X (may be OS X bug, but patch works x-plat). [Bug 689835] (steffen)
+
+2003-02-20 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/regsub.n: Typo fix [Bug 688943]
+
+2003-02-19 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/tclUnixThrd.c (TclpReaddir):
+ * unix/tclUnixPort.h: update to Bug 689100 patch to ensure that there
+ is a defined value of MAXNAMLEN (aka NAME_MAX in POSIX) and that we
+ have some buffer allocated.
+
+2003-02-19 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tclStringObj.c: restored Tcl_SetObjLength() side-effect of
+ always invalidating unicode rep (if the obj has a string rep). Added
+ hasUnicode flag to String struct, allows decoupling of validity of
+ unicode rep from buffer size allocated to it (improves memory
+ allocation efficiency). [Bugs 686782, 671138, 635200]
+
+ * macosx/Tcl.pbproj/project.pbxproj:
+ * macosx/Makefile: reworked embedded build to no longer require
+ relinking but to use install_name_tool instead to change the
+ install_names for embedded frameworks. [Bug 644510]
+
+ * macosx/Tcl.pbproj/project.pbxproj: preserve mod dates when running
+ 'make install' to build framework (avoids bogus rebuilds of dependent
+ frameworks because tcl headers appear changed).
+
+ * tests/ioCmd.test (iocmd-1.8): fix failure when system encoding is
+ utf-8: use iso8859-1 encoding explicitly.
+
+2003-02-18 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompile.c (TclCompileExprWords): remove unused variable
+ "range" [Bug 664743]
+ * generic/tclExecute.c (ExprSrandFunc): remove unused variable
+ "result" [Bug 664743]
+ * generic/tclStringObj.c (UpdateStringOfString): remove unused
+ variable "length" [Bug 664751]
+ * tests/execute.test (execute-7.30): fix for [Bug 664775]
+
+2003-02-18 Andreas Kupries <andreask@activestate.com>
+
+ * unix/tcl.m4: [Bug #651811] Added definition of _XOPEN_SOURCE and
+ linkage of 'xnet' library to HP 11 branch. This kills a lot of
+ socket-related failures in the testsuite when Tcl was compiled in 64
+ bit mode (both PA-RISC 2.0W, and IA 64).
+
+ * unix/configure: Regenerated.
+
+2003-02-18 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclIO.c (HaveVersion): correctly decl static
+
+ * unix/tclUnixThrd.c (TclpReaddir): reduce size of name string in tsd
+ to NAME_MAX instead of PATH_MAX. [Bug 689100] (waters)
+
+2003-02-18 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/configure: Regen.
+ * unix/tcl.m4 (SC_ENABLE_THREADS): Make sure -lpthread gets passed on
+ the link line when checking for the pthread_attr_setstacksize symbol.
+
+2003-02-18 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclTest.c: cleanup of new 'simplefs' test code, and better
+ documentation.
+
+2003-02-17 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclBasic.c (TclRenameCommand): fixing error in previous
+ commit.
+
+2003-02-17 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclExecute.c (TclExecuteByteCode INST_STR_MATCH):
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd STR_MATCH):
+ * generic/tclUtf.c (TclUniCharMatch):
+ * generic/tclInt.decls: add private TclUniCharMatch function that
+ * generic/tclIntDecls.h: does string match on counted unicode
+ * generic/tclStubInit.c: strings. Tcl_UniCharCaseMatch has the failing
+ * tests/string.test: that it can't handle strings or patterns with
+ * tests/stringComp.test: embedded NULLs. Added tests that actually try
+ strings/pats with NULLs. TclUniCharMatch should be TIPed and made
+ public in the next minor version rev.
+
+2003-02-17 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclBasic.c (TclRenameCommand): 'oldFullName' object was not
+ being freed on all function exits, causing a memory leak. [Bug 684756]
+
+2003-02-17 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * generic/tclIO.c (Tcl_GetsObj): Minor change so that eol is only
+ assigned at the top of the TCL_TRANSLATE_AUTO case block. The other
+ cases assign eol so this does not change any functionality.
+
+2003-02-17 Kevin Kenny <kennykb@users.sourceforge.net>
+
+ * tests/notify.test: Removed Windows line terminators. [Bug 687913].
+
+2003-02-15 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclBasic.c (Tcl_EvalEx):
+ * generic/tclCompExpr.c (CompileSubExpr):
+ * generic/tclCompile.c (TclCompileScript):
+ * generic/tclParse.c (Tcl_ParseCommand, ParseTokens):
+ * generic/tclParseExpr.c (ParsePrimaryExpr):
+ * tests/basic.test (47.1):
+ * tests/main.test (3.4):
+ * tests/misc.test (1.2):
+ * tests/parse.test (6.18):
+ * tests/parseExpr.test (15.35):
+ * tests/subst.test (8.6): Don Porter's fix for bad parsing of nested
+ scripts. [Bug 681841]
+
+2003-02-15 Kevin Kenny <kennykb@users.sourceforge.net>
+
+ * tests/notify.test (new-file):
+ * generic/tclTest.c (TclTest_Init, EventtestObjCmd, EventtestProc,
+ (EventTestDeleteProc):
+ * generic/tclNotify.c (Tcl_DeleteEvents): Fixed Tcl_DeleteEvents not
+ to get a pointer smash when deleting the last event in the queue.
+ Added test code in 'tcltest' and a new file of test cases
+ 'notify.test' to exercise this functionality; several of the new test
+ cases fail for the original code and pass for the corrected code. [Bug
+ 673714]
+
+ * unix/tclUnixTest.c (TestfilehandlerCmd): Corrected a couple of typos
+ in error messages. [Bug 596027]
+
+2003-02-14 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * README: Bumped to version 8.4.2.
+ * generic/tcl.h:
+ * tools/tcl.wse.in:
+ * unix/configure:
+ * unix/configure.in:
+ * unix/tcl.m4:
+ * unix/tcl.spec:
+ * win/README.binary:
+ * win/configure:
+ * win/configure.in:
+ * macosx/Tcl.pbproj/project.pbxproj:
+
+ * generic/tclStringObj.c (Tcl_GetCharLength): perf tweak
+
+ * unix/tcl.m4: correct HP-UX ia64 --enable-64bit build flags
+
+2003-02-14 Kevin Kenny <kennykb@users.sourceforge.net>
+
+ * win/tclWinTime.c: Added code to test and compensate for forward
+ leaps of the performance counter. See the MSDN Knowledge Base article
+ Q274323 for the hardware problem that makes this necessary on certain
+ machines.
+ * tests/winTime.test: Revised winTime-2.1 - it had a tolerance of
+ thousands of seconds, rather than milliseconds. (What's six orders of
+ magnitude among friends?) Both the above changes are triggered by a
+ problem reported at:
+ http://aspn.activestate.com/ASPN/Mail/Message/ActiveTcl/1536811
+ although the developers find it difficult to believe that it accounts
+ for the observed behavior and suspect a fault in the RTC chip.
+
+2003-02-13 Kevin Kenny <kennykb@users.sourceforge.net>
+
+ * win/tclWinInit.c: Added conversion from the system encoding to
+ tcl_platform(user), so that it works with non-ASCII7 user names. [Bug
+ 685926]
+
+ * doc/tclsh.1: Added language to describe the handling of the
+ end-of-file character \u001a embedded in a script file. [Bug 685485]
+
+2003-02-11 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * tests/fileName.test:
+ * unix/tclUnixFile.c: fix for [Bug 685445] when using 'glob -l' on
+ broken symbolic links. Added two new tests for this bug.
+
+2003-02-11 Kevin Kenny <kennykb@users.sourceforge.net>
+
+ * tests/http.test: Corrected a problem where http-4.14 would fail when
+ run in an environment with a proxy server. Replaced references to
+ scriptics.com by tcl.tk.
+
+2003-02-11 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * tests/lsearch.test:
+ * generic/tclCmdIL.c (Tcl_LsearchObjCmd): protect against the case
+ that lsearch -regepx list and pattern objects are equal.
+
+ * tests/stringObj.test:
+ * generic/tclStringObj.c (Tcl_GetCharLength): correct ascii char opt
+ of 2002-11-11 to not stop early on \x00. [Bug 684699]
+
+ * tests.parse.test: remove excess EOF whitespace
+
+ * generic/tclParse.c (CommandComplete): more paranoid check to break
+ on (p >= end) instead of just (p == end).
+
+2003-02-11 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclParse.c (CommandComplete):
+ * tests/parse.test: fix for [Bug 684744], by Don Porter.
+
+2003-02-11 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclIOUtil.c (Tcl_FSJoinPath, Tcl_FSGetNormalizedPath):
+ (UpdateStringOfFsPath): revert the cwdLen == 0 check and instead
+ follow a different code path in Tcl_FSJoinPath.
+ (Tcl_FSConvertToPathType, Tcl_FSGetNormalizedPath):
+ (Tcl_FSGetFileSystemForPath): Update string rep of path objects before
+ freeing the internal object. (darley)
+
+ * tests/fileSystem.test: added test 8.3
+ * generic/tclIOUtil.c (Tcl_FSGetNormalizedPath):
+ (UpdateStringOfFsPath): handle the cwdLen == 0 case
+
+ * unix/tclUnixFile.c (TclpMatchInDirectory): simplify the hidden file
+ match check.
+
+2003-02-10 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/configure:
+ * win/configure.in: Generate error when attempting to build under
+ Cygwin. The Cygwin port of Tcl/Tk does not build and people are filing
+ bug reports under the mistaken impression that someone is actually
+ maintaining the Cygwin port. A post to comp.lang.tcl asking someone to
+ volunteer as an area maintainer has generated no results. Closing bugs
+ 680840, 630199, and 634772 and marking as "Won't fix".
+
+2003-02-10 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/append.n: Return value was not documented. [Bug 683188]
+
+2003-02-10 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * doc/FileSystem.3:
+ * generic/tclIOUtil.c:
+ * generic/tclInt.h:
+ * tests/fileSystem.test:
+ * unix/tclUnixFCmd.c:
+ * unix/tclUnixFile.c:
+ * win/tclWinFile.c: further filesystem optimization, applying [Patch
+ 682500]. In particular, these code examples are faster now:
+ foreach f $flist { if {[file exists $f]} {file stat $f arr;...}}
+ foreach f [glob -dir $dir *] { # action and/or recursion on $f }
+ cd $dir
+ foreach f [glob *] { # action and/or recursion on $f }
+ cd ..
+
+ * generic/tclTest.c: Fix for [Bug 683181] where test suite left files
+ in 'tmp'.
+
+2003-02-08 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * library/safe.tcl: code cleanup of eval and string comp use.
+
+2003-02-07 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * win/tclWinFCmd.c: cleanup long lines
+ * win/tclWinFile.c: sped up pure 'glob' by a factor of 2.5
+ ('foreach f [glob *] { file exists $f }' is still slow)
+ * tests/fileSystem.text:
+ * tests/fileName.test: added new tests to ensure correct behaviour in
+ optimized filesystem code.
+
+2003-02-07 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclTest.c:
+ * tests/fileSystem.text: fixed test 7.2 to avoid a possible crash, and
+ not change the pwd.
+
+ * tests/http.text: added comment to test 4.15, that it may fail if you
+ use a proxy server.
+
+2003-02-06 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * generic/tclCompCmds.c (TclCompileIncrCmd):
+ * tests/incr.test: Don't include the text "(increment expression)" in
+ the errorInfo generated by the compiled version of the incr command
+ since it does not match the message generated by the non-compiled
+ version of incr. It is also not possible to match this error output
+ under Jacl, which does not support a compiler.
+
+2003-02-06 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * generic/tclExecute.c (TclExecuteByteCode): When an error is
+ encountered reading the increment value during a compiled call to
+ incr, add a "(reading increment)" error string to the errorInfo
+ variable. This makes the errorInfo variable set by the compiled incr
+ command match the value set by the non-compiled version.
+ * tests/incr-old.test: Change errorInfo result for the compiled incr
+ command case to match the modified implementation.
+ * tests/incr.test: Add tests to make sure the compiled and
+ non-compiled errorInfo messages are the same.
+
+2003-02-06 Don Porter <dgp@users.sourceforge.net>
+
+ * library/tcltest/tcltest.tcl: Filename arguments to [outputChannel]
+ and [errorChannel] (also -outfile and -errfile) were [open]ed but
+ never [closed]. Also, [cleanupTests] could remove output or error
+ files. [Bug 676978].
+ * library/tcltest/pkgIndex.tcl: Bumped to version 2.2.2.
+
+2003-02-05 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * tests/interp.test:
+ * tests/set-old.test: Run test cases that depend on hash order through
+ lsort so that the tests also pass under Jacl. Does not change test
+ results under Tcl.
+
+2003-02-04 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclIOUtil.c:
+ * generic/tclEvent.c:
+ * generic/tclInt.h:
+ * mac/tclMacFCmd.c:
+ * unix/tclUnixFCmd.c:
+ * win/tclWin32Dll.c:
+ * win/tclWinFCmd.c:
+ * win/tclWinInit.c:
+ * win/tclWinInt.h:
+ * tests/fileSystem.test: fix to finalization/unloading/encoding issues
+ to make filesystem much less dependent on encodings for its cleanup,
+ and therefore allow it to be finalized later in the exit process. This
+ fixes fileSystem.test-7.1. Also fixed one more bug in setting of
+ modification dates of files which have undergone cross-platform
+ copies. [Patch 676271]
+
+ * tests/basic.test:
+ * tests/exec.test:
+ * tests/fileName.test:
+ * tests/io.test: fixed some test failures when tests are run from a
+ directory containing spaces.
+
+ * tests/fileSystem.test:
+ * generic/tclTest.c: added regression test for the modification date
+ setting of cross-platform file copies.
+
+2003-02-03 Kevin Kenny <kennykb@users.sourceforge.net>
+
+ * generic/tclBasic.c: Changed [trace add command] so that 'rename'
+ callbacks get fully qualified names of the command. [Bug 651271].
+ ***POTENTIAL INCOMPATIBILITY***
+ * tests/trace.test: Modified the test cases for [trace add command] to
+ expect fully qualified names on the 'rename' callbacks. Added a case
+ for renaming a proc within a namespace.
+ * doc/trace.n: Added language about use of fully qualified names in
+ trace callbacks.
+
+2003-02-01 Kevin Kenny <kennykb@users.sourceforge.net>
+
+ * generic/tclCompCmds.c: Removed an unused variable that caused
+ compiler warnings on SGI. [Bug 664379]
+
+ * generic/tclLoad.c: Changed the code so that if Tcl_StaticPackage is
+ called to report the same package as being loaded in two interps, it
+ shows up in [info loaded {}] in both of them (previously, it didn't
+ appear in the static package list in the second).
+
+ * tests/load.test Added regression test for the above bug. [Bug
+ 670042]
+
+ * generic/tclClock.c: Fixed a bug that incorrectly allowed [clock
+ clicks {}] and [clock clicks -] to be accepted as if they were [clock
+ clicks -milliseconds].
+
+ * tests/clock.test: Added regression tests for the above bug. [Bug
+ 675356]
+
+ * tests/unixNotfy.test: Added cleanup of working files. [Bug 675609]
+
+ * doc/Tcl.n: Added headings to the eleven paragraphs, to improve
+ formatting in the tools that attempt to extract tables of contents
+ from the manual pages. [Bug 627455]
+
+ * generic/tclClock.c: Expanded mutex protection around the setting of
+ env(TZ) and the thread-unsafe call to tzset(). [Bug 656660]
+
+2003-01-31 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/tcltest.test: Cleaned up management of file/directory
+ creation/deletion to improve "-debug 1" output. [Bug 675614]
+ The utility [slave] command failed to properly [list]-quote a
+ constructed [open] command, causing failure when the pathname
+ contained whitespace. [Bug 678415]
+
+ * tests/main.test: Stopped main.test from deleting existing file. Test
+ suite should not delete files that already exist. [Bug 675660]
+
+2003-01-28 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/main.test: Constrain tests that do not work on Windows. [Bug
+ 674387]
+
+2003-01-28 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclIOUtil.c: fix to setting modification date in
+ TclCrossFilesystemCopy. Also added 'panic' in
+ Tcl_FSGetFileSystemForPath under illegal calling circumstances which
+ lead to hard-to-track-down bugs.
+
+ * generic/tclTest.c: added test suite code to allow exercising a
+ vfs-crash-on-exit bug in Tcl's finalization caused by the encodings
+ being cleaned up before unloading occurs.
+ * tests/fileSystem.test: added new 'knownBug' test 7.1 to demonstrate
+ the crash on exit.
+
+2003-01-28 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * generic/tcl.h: Add TCL_PREFIX_IDENT and TCL_DEBUG_IDENT, used only
+ by TclpCreateProcess.
+ * unix/Makefile.in: Define TCL_DBGX.
+ * win/Makefile.in: Define TCL_DBGX.
+ * win/tclWinPipe.c (TclpCreateProcess): Check that the Tcl pipe dll
+ actually exists in the Tcl bin directory and panic if it is not found.
+ Incorporate TCL_DBGX into the Tcl pipe dll name. This fixes a really
+ mysterious error that would show up when exec'ing a 16 bit application
+ under Win95 or Win98 when Tcl was compiled with symbols. The error
+ seemed to indicate that the executable could not be found, but it was
+ actually the Tcl pipe dll that could not be found.
+
+2003-01-26 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/README: Update msys+mingw URL to release 6. This version bundles
+ gcc 3.
+
+2003-01-26 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/configure: Regen.
+ * win/configure.in: Add test that checks to see if the compiler can
+ cast to a union type.
+ * win/tclWinTime.c: Squelch compiler warning about union initializer
+ by casting to union type when compiling with gcc.
+
+2003-01-25 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * generic/tclIO.c (Tcl_CutChannel, Tcl_SpliceChannel): Invoke
+ TclpCutFileChannel and TclpSpliceFileChannel.
+ * generic/tclInt.h: Declare TclpCutFileChannel and
+ TclpSpliceFileChannel.
+ * unix/tclUnixChan.c (FileCloseProc, TclpOpenFileChannel,
+ (Tcl_MakeFileChannel, TclpCutFileChannel, TclpSpliceFileChannel):
+ Implement thread load data cut and splice for file channels. This
+ avoids an invalid memory ref when compiled with -DDEPRECATED.
+ * win/tclWinChan.c (FileCloseProc, TclpCutFileChannel,
+ (TclpSpliceFileChannel): Implement thread load data cut and splice for
+ file channels. This avoids an invalid memory ref that was showing up
+ in the thread extension.
+
+2003-01-25 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/tclWin32Dll.c (TclpCheckStackSpace, squelch_warnings):
+ * win/tclWinChan.c (Tcl_MakeFileChannel, squelch_warnings):
+ * win/tclWinFCmd.c (DoRenameFile, DoCopyFile, squelch_warnings):
+ Re-implement inline ASM SEH handlers for gcc. The esp and ebp
+ registers are now saved on the stack instead of in global variables so
+ that the code is thread safe. Add additional checks when TCL_MEM_DEBUG
+ is defined to be sure the values were recovered from the stack
+ properly. Remove squelch_warnings functions and add a dummy call in
+ the handler methods to squelch compiler warnings.
+
+2003-01-25 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/configure:
+ * win/configure.in: Define HAVE_ALLOCA_GCC_INLINE when we detect that
+ no alloca function is found in malloc.h and we are compiling with GCC.
+ Remove HAVE_NO_ALLOC_DECL define.
+ * win/tclWin32Dll.c (TclpCheckStackSpace): Don't define alloca as a
+ cdecl function. Doing this caused a tricky runtime bug because the
+ _alloca function expects the size argument to be passed in a register
+ and not on the stack. To fix this problem, we use inline ASM when
+ compiling with gcc to invoke _alloca with the size argument loaded
+ into a register.
+
+2003-01-24 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/tclWinDde.c (Dde_Init): clarified use of tsdPtr.
+ (DdeServerProc): better refcount handling of returnPackagePtr.
+
+ * generic/tclEvent.c (Tcl_Finalize): revert finalize change on
+ 2002-12-04 to correct the issue with extensions that have TSD needing
+ to finalize that before they are unloaded. This issue needs further
+ clarification.
+
+ * tests/unixFCmd.test: only do groups check on unix
+
+2003-01-24 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclStringObj.c: proper fixes for Tcl_SetObjLength and
+ Tcl_AttemptSetObjectLength dealing with string objects with both
+ pure-unicode and normal internal representations. Previous fix didn't
+ handle all cases correctly.
+ * generic/tclIO.c: Add 'Tcl_GetString()' to ensure the object has a
+ valid 'objPtr->bytes' field before manipulating it directly.
+
+ This fixes [Bug 635200] and [Bug 671138], but may reduce performance
+ of Unicode string handling in some cases. A further patch will be
+ applied to address this, once the code is known to be correct.
+
+2003-01-24 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/configure: Regen.
+ * win/configure.in: Add test to see if alloca is undefined in
+ malloc.h.
+ * win/tclWin32Dll.c (TclpCheckStackSpace): Rework the SEH exception
+ handler logic to avoid using the stack since alloca will modify the
+ stack. This was causing a nasty bug that would set the exception
+ handler to 0 because it tried to pop the previous exception handler
+ off the top of the stack.
+
+2003-01-23 Donal K. Fellows <fellowsd@cs.man.ac.uk>
+
+ * doc/lset.n: Fixed fault in return values from lset in documentation
+ examples [SF Bug #658463] and tidied up a bit at the same time.
+
+2003-01-21 Joe English <jenglish@users.sourceforge.net>
+
+ * doc/namespace.n (namespace inscope): Clarified documentation
+ [Patch 670110]
+
+2003-01-21 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/configure: Regen.
+ * win/tcl.m4 (SC_CONFIG_CFLAGS): Set SHLIB_SUFFIX so that
+ TCL_SHLIB_SUFFIX will be set to a useful value in the generated
+ tclConfig.sh. Set SHLIB_LD_LIBS to "" or '${LIBS}' based on the
+ --enable-shared flag. This matches the UNIX implementation.
+
+2003-01-18 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclCkalloc.c: change %ud to %u as appropriate.
+
+2003-01-17 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/tclWinDde.c (DdeServerProc): Deallocate the Tcl_Obj returned by
+ ExecuteRemoteObject if it was not saved in a connection object.
+
+2003-01-17 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * generic/tcl.h: Revert earlier change that defined TCL_WIDE_INT_TYPE
+ as long long and TCL_LL_MODIFIER as L when compiling with mingw. This
+ change ended up causing some test case failures when compiling with
+ mingw.
+ * generic/tclObj.c (UpdateStringOfWideInt): Describe the warning
+ generated by mingw and why it needs to be ignored so that someone is
+ not tempted to "fix" this problem again in the future.
+
+2003-01-16 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclStringObj.c: Tcl_SetObjLength fix for when the object has
+ a unicode string rep. [Bug 635200]
+ * tests/stringObj.test: removed 'knownBug' constraint from test 14.1
+ now that this bug is fixed.
+
+ * generic/tclInt.h:
+ * generic/tclBasic.c:
+ * generic/tclCmdMZ.z:
+ * tests/trace.test: execution and command tracing bug fixes and
+ cleanup. In particular fixed [Bug 655645], [Bug 615043], [Bug 571385]
+ - fixed some subtle cleanup problems with tracing. This required
+ replacing Tcl_Preserve/Tcl_Release with a more robust refCount
+ approach. Solves at least one known crash caused by memory
+ corruption.
+ - fixed some confusion in the code between new style traces (Tcl
+ 8.4) and the very limited 'Tcl_CreateTrace' which existed before.
+ - made behaviour consistent with documentation (several tests even
+ contradicted the documentation before).
+ - fixed some minor error message details
+ - added a number of new tests
+
+2003-01-16 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/tclWinSerial.c (SerialOutputProc): add casts for bytesWritten to
+ allow strict compilation (no warnings).
+
+ * tests/winDde.test:
+ * win/tclWinDde.c (Tcl_DdeObjCmd): Prevent crash when empty service
+ name is passed to 'dde eval' and goto errorNoResult in request and
+ poke error cases to free up any allocated data.
+
+2003-01-16 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/tclWin32Dll.c (squelch_warnings): Squelch compiler warnings from
+ SEH ASM code.
+ * win/tclWinChan.c (squelch_warnings): Squelch compiler warnings from
+ SEH ASM code.
+ * win/tclWinDde.c: Add casts to avoid compiler warnings. Pass pointer
+ to DWORD instead of int to avoid compiler warnings.
+ * win/tclWinFCmd.c (squelch_warnings): Add casts and fixup decls to
+ avoid compiler warnings. Squelch compiler warnings from SEH ASM code.
+ * win/tclWinFile.c: Add casts and fixup decls to avoid compiler
+ warnings. Remove unused variable.
+ * win/tclWinNotify.c: Declare as DWORD instead of int to avoid
+ compiler warning.
+ * win/tclWinReg.c: Add casts to avoid compiler warning. Fix assignment
+ in if expression bug.
+ * win/tclWinSerial.c: Add casts to avoid compiler warnings. Remove
+ unused variable.
+ * win/tclWinSock.c: Add casts and fixup decls to avoid compiler
+ warnings.
+
+2003-01-14 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclClock.c (FormatClock): corrected typo that incorrectly
+ conditionally defined savedTZEnv and savedTimeZone.
+
+2003-01-13 Mo DeJong <mdejong@users.sourceforge.net>
+
+ Fix mingw build problems and compiler warnings.
+
+ * generic/tcl.h: Add if defined(__MINGW32__) check to code that sets
+ the TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER.
+ * generic/tclClock.c (FormatClock): Don't define savedTimeZone and
+ savedTZEnv if we are not going to use them.
+ * generic/tclEnv.c: Add cast to avoid warning.
+ * win/tclWinChan.c: Use DWORD instead of int to avoid compiler warning
+ * win/tclWinThrd.c: Only define allocLock, allocLockPtr, and dataKey
+ when TCL_THREADS is defined. This avoid a compiler warning about
+ unused variables.
+
+2003-01-12 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/README: Update msys + mingw URL, the new release includes the
+ released 1.0.8 version of msys which includes a number of bug fixes.
+
+2003-01-12 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/configure: Regen.
+ * win/tcl.m4 (SC_CONFIG_CFLAGS): Pull in addition of shell32.lib to
+ LIBS_GUI that was added to the Tk tcl.m4 but never made it back into
+ the Tcl version.
+
+2003-01-12 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * generic/tcl.h: Skip Tcl's define of CHAR, SHORT, and LONG when
+ HAVE_WINNT_IGNORE_VOID is defined. This avoids a bunch of compiler
+ warnings when building with Cygwin or Mingw.
+ * win/configure: Regen.
+ * win/configure.in: Define HAVE_WINNT_IGNORE_VOID when we detect a
+ winnt.h that still defines CHAR, SHORT, and LONG when VOID has already
+ been defined.
+ * win/tcl.m4 (SC_LOAD_TCLCONFIG): Subst the TCL_DEFS loaded from
+ tclConfig.sh so that Tcl defines can make it into the Tk Makefile.
+
+2003-01-12 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/configure: Regen.
+ * win/configure.in: Check for typedefs like LPFN_ACCEPT in winsock2.h
+ and define HAVE_NO_LPFN_DECLS if not found.
+ * win/tclWinSock.c: Define LPFN_* typedefs if HAVE_NO_LPFN_DECLS is
+ defined. This fixes the build under Mingw and Cygwin, it was broken by
+ the changes made on 2002-11-26.
+
+2003-01-10 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * 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
+ filesystem.
+
+ * win/makefile.vc: fix to minor VC++ 5.2 syntax problem
+
+2003-01-09 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCompCmds.c (TclCompileReturnCmd): Corrected off-by-one
+ problem with recent commit. [Bug 633204]
+
+2003-01-09 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclFileName.c: remove unused variable 'macSpecialCase'
+ [Bug 664749]
+
+ * generic/tclIOUtil.c:
+ * generic/tclInt.h:
+ * unix/tclUnixFile.c:
+ * mac/tclMacFile.c:
+ * win/tclWinFile.c:
+ * win/tclWinInt.h:
+ * win/tclWin32Dll.c:
+ * tests/cmdAH.test: fix to non-ascii chars in paths when setting mtime
+ and atime through 'file (a|m)time $path $time'. [Bug 634151]
+
+2003-01-08 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclExecute.c (TclExprFloatError): Use the IS_NAN macro for
+ greater clarity of code.
+
+2003-01-07 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCompCmds.c (TclCompileReturnCmd):
+ * tests/compile.test: Corrects failure of bytecompiled [catch
+ {return}] to have result TCL_RETURN (not TCL_OK) [Bug 633204]. This
+ patch is a workaround for 8.4.X. A new opcode INST_RETURN is a better
+ long term solution for 8.5 and later.
+
+2003-01-04 David Gravereaux <davygrvy@pobox.com>
+
+ * win/makefile.vc:
+ * win/rules.vc: Fixed INSTALLDIR macro problem that blanked itself by
+ accident causing the install target to put the tree at the root of the
+ drive built on. Whoops..
+
+ Renamed the 'linkexten' option to be 'staticpkg'. Added 'thrdalloc' to
+ allow the switching _on_ of the thread allocator. Under testing, I
+ found it not to be benificial under windows for the purpose of the
+ application I was using it for. It was more important for this app
+ that resources for tcl threads be returned to the system rather than
+ saved/moved to the global recycler. Be extra clean or extra fast for
+ the default threaded build? Let's move to clean and allow it to be
+ switched on for users who find it benificial for their use of threads.
+
+ ******************************************************************
+ *** 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.2004 b/ChangeLog.2004
new file mode 100644
index 0000000..82acd5c
--- /dev/null
+++ b/ChangeLog.2004
@@ -0,0 +1,4619 @@
+2004-12-29 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/tcl.m4, win/configure: update MSVC CFLAGS_OPT to -O2, remove -Gs
+ (included in -O2) and -GD (outdated). Use "link -lib" instead of "lib"
+ binary and remove -YX for MSVC7 portability. Add -fomit-frame-pointer
+ for gcc OPT compiles. [Bug 1092952, 1091967] Align LIBS_GUI with Tk
+ head needs.
+
+2004-12-29 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclDate.c: Regen
+ * generic/tclGetDate.y (TclDatelex): Fixed a problem where a
+ four-digit group with >=2 leading zeroes appeared to be a two-digit
+ group, leading to misinterpreting the time 0012 as 1200. [Bug 1090413]
+ * library/clock.tcl: Added code to interpret correctly months outside
+ the range 01-12 as reduced modulo 12 with a corresponding adjustment
+ to the year. [Bug 1092789]
+ * tests/clock.test: Added regression test cases for the above two bugs
+ * unix/Makefile.in: Added --no-lines to the 'bison' command line to
+ * win/Makefile.in: help constrain the number of diffs in a cvs checkin
+
+2004-12-24 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompile.c:
+ * generic/tclCompile.h:
+ * generic/tclExecute.c:
+ * generic/tclInt.h:
+ * generic/tclLiteral.c:
+ * generic/tclProc.c:
+ Avoid sharing cmdName literals accross namespaces, and generalise
+ usage of the TclRegisterNewLiteral macro. [Patch 1090905]
+
+2004-12-20 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompile.c: moved TclInitCompiledLocals to tclProc.c
+ * generic/tclProc.c: new static InitCompiledLocals to allow for a
+ single pass over the proc's arguments at proc load time (instead of
+ two as previously). TclObjInterpProc() now allocates the
+ compiledLocals on the tcl execution stack, using the new
+ TclStackAlloc/Free functions.
+
+2004-12-16 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclInterp.c (Tcl_LimitSetTime, TimeLimitCallback):
+ (TclLimitRemoveAllHandlers, TclInitLimitSupport): Set a timer event to
+ trigger when the time limit runs out. All the time limit actually does
+ is check to see if the time limit has been exceeded, but this is
+ enough to fix [Bug 1085023].
+ * generic/tclInt.h (struct Interp): Added a field to hold the token
+ for the timer event handler associated with the current time limit.
+ * generic/tclEvent.c (Tcl_UpdateObjCmd, Tcl_VwaitObjCmd): Add error
+ message when limit exceeded.
+ * tests/interp.test (interp-34.[89]): Check that time limits handle
+ the two cases reported in [Bug 1085023]
+
+ * generic/tclTimer.c (TclCreateAbsoluteTimerHandler): New internal
+ function that allows setting a timer handler that will be triggered at
+ (or after) a specific time instead of at some number of milliseconds
+ in the future. This is a candidate for future exposure via a TIP.
+
+2004-12-15 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclBasic.c:
+ * generic/tclExecute.c:
+ * generic/tclInt.decls:
+ * generic/tclIntDecls.h:
+ * generic/tclNamesp.c:
+ * generic/tclProc.c:
+ * generic/tclStubInit.c:
+ * generic/tclTest.c: Added two new functions to allocate memory from
+ the execution stack (TclStackAlloc, TclStackFree). Added functions
+ TclPushStackFrame and TclPopStackFrame that do the work of
+ Tcl_PushCallFrame and Tcl_PopCallFrame, but using frames allocated in
+ the execution stack - i.e., heap instead of C-stack. The core uses
+ these two new functions exclusively; the old ones remain for backwards
+ compat, as at least two popular extensions (itcl, xotcl) are known to
+ use them.
+
+2004-12-14 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCmdIL.c:
+ * generic/tclInt.h:
+ * generic/tclProc.c:
+ * generic/tclVar.c: changing the isProcCallFrame field of the
+ CallFrame struct from a 0/1 field to flags. Should be perfectly
+ backwards compatible.
+
+2004-12-14 Don Porter <dgp@users.sourceforge.net>
+
+ * unix/configure.in: Added special processing to remove "$U" from
+ libraries in the LIBOBJS value. This is an auto-make-ism we need to
+ avoid. [Bug 1081541]
+
+ * unix/configure: autoconf-2.57
+
+2004-12-13 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tcl.h: Restored extern "C" guards so that C++ code sees
+ function pointer typedef linkage consistent with earlier Tcl releases.
+ [Bug 1082349]
+
+ * generic/tclEncoding.c: Plugged some memory leaks. Thanks to Rolf Ade
+ * generic/tclUtil.c: for reports and testing [Bug 1083082]
+
+2004-12-13 Kevin B. Kenny <kennykb@acm.org>
+
+ * doc/clock.n: Clarify that the [clock scan] command does not accept
+ the full range of ISO8601 point-in-time formats. [Bug 1075433]
+
+2004-12-12 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclVar.c (TclArrayObjCmd - ARRAY_NAMES): leaking an object
+ [Bug 1084111] - thanks to Rolf Ade.
+
+2004-12-12 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclObj.c (TclSetCmdNameObj): special handling for fully
+ qualified command names (as in fix [Patch 456668]).
+
+2004-12-11 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclInt.h:
+ * generic/tclNamesp.c: converting the static function
+ GetNamespaceFromObj() to MODULE_SCOPE TclGetNamespaceFromObj().
+
+2004-12-10 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * tools/tcl.wse.in, unix/tcl.spec, win/README.binary, README:
+ * win/configure.in, unix/configure.in, generic/tcl.h:
+ Bumped version number to 8.5a3 to distinguish HEAD of CVS development
+ from the recent 8.5a2 release.
+
+2004-12-10 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompile.c (TclInitCompiledLocals):
+ * generic/tclCompile.h:
+ * generic/tclInt.h:
+ * generic/tclProc.c (TclObjInterpProc, TclCreateProc): optimised
+ loops that initialise a proc's arguments and compiled local
+ variables, removing tests from inner loops.
+
+2004-12-10 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclInt.h: Move ensemble API decls here from tclNamesp.c
+
+2004-12-09 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclNamesp.c (TclMakeEnsembleCmd, TclSetEnsemble*)
+ (TclSetEnsemble*, TclFindEnsemble): Build an internal API for creating
+ and manipulating ensembles; they can be deleted using the normal
+ command-deletion API.
+
+ * doc/Async.3: Reword for better grammar, better nroff and get the
+ flag name right. (Reported by David Welton.)
+
+2004-12-07 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/unixInit.test (2.1-4): Added constraints so that when a value
+ of TCL_LIBRARY is required for process initialization, we skip the
+ tests that mess with that value.
+
+2004-12-07 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ *** 8.5a2 TAGGED FOR RELEASE ***
+
+ * unix/Makefile.in: add library/{tzdata,msgs} to dist target (kbk)
+
+ * doc/foreach.n: Adjust tabs to be friendlier to some HTML
+ converters. [Bug 1078760]
+
+2004-12-06 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/tclUnixNotfy.c (NotifierThreadProc): init numFdBits
+ [Bug 1079286]
+
+ * doc/error.n, doc/SaveResult.3, doc/Thread.3: minor nroff typos
+
+2004-12-06 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/safe.test: Trim auto_path to improve performance [1080039]
+
+ * tests/msgcat.test: makeFile/removeFile cleanup [1079117]
+
+2004-12-04 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclEncoding.c: Different fix for [Bug 1077005].
+ * generic/tclEvent.c: Broke apart TclpSetInitialEncodings() on
+ * generic/tclInt.h: Windows into TclpSetInterfaces(), that is
+ * unix/tclUnixInit.c: fundamentally essential, and the initialization
+ * win/tclWinInit.c: of the system encoding, which is not. Made
+ the TclpSetInterfaces call part of TclInitSubsystems so it cannot be
+ overlooked.
+
+2004-12-03 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * changes: updated for 8.5a2 release
+
+2004-12-02 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclUtil.c (TclSetProcessGlobalValue): Handle the case where
+ a ProcessGlobalValue might be assigned to itself.
+
+ * generic/tclEncoding.c (MakeFileMap): Correct refcounting errors
+ managing values returned by TclPathPart (with refCount of 1!) that led
+ to a memory leak. [Bug 1077474].
+
+2004-12-02 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclPathObj.c: fix and new tests for [Bug 1074671] to ensure
+ * tests/fileSystem.test: tilde paths are not returned specially by
+ 'glob'.
+
+2004-12-02 Kevin B. Kenny <kennykb@acm.org>
+
+ * win/Makefile.in: Added a 'sed' in the setting of ROOT_DIR_NATIVE to
+ compensate for a bug in cygpath (at least version 1.36) that leaves a
+ trailing backslash on the end of the converted path.
+
+2004-12-02 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclInterp.c (Alias,Target,Master): Rewrote these so that the
+ aliases that refer to an interpreter are stored in a list and not a
+ hashtable (which was only ever a convenience, and forced the use of a
+ global mutex to generate keys!) [FRQ 1077210]
+ * generic/tclNamesp.c (numNsCreated): Moved into thread-local storage
+ to remove a global mutex. [FRQ 1077210]
+
+2004-12-01 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclUtil.c (TclGetProcessGlobalValue): Narrowed the scope of
+ mutex locks.
+
+ * generic/tclUtil.c: Updated Tcl_GetNameOfExecutable() to
+ * generic/tclEncoding.c: make use of a ProcessGlobalValue for
+ * generic/tclEvent.c: storing the executable name. Added
+ internal routines Tcl(Get|Set)ObjNameOfExecutable() to access that
+ storage in Tcl_Obj, rather than string format.
+
+ * unix/tclUnixFile.c: Rewrote TclpFindExecutable() to use
+ * win/tclWinFile.c: TclSetObjNameOfExecutable to store the
+ executable name it computes.
+
+ * generic/tclInt.h: Added internal stub entries for
+ * generic/tclInt.decls: TclpFindExecutable and
+ Tcl(Get|Set)ObjNameOfExecutable.
+
+ * generic/tclIntDecls.h: make genstubs
+ * generic/tclStubInit.c:
+
+ * generic/tclCmdIL.c: Retrieve executable name in Tcl_Obj form
+ * win/tclWinPipe.c: instead of string form.
+
+ * unix/tclUnixTest.c: Update [testfindexecutable] command to use new
+ internal interfaces.
+
+ * generic/tclEncoding.c: Moved TclpSetInitialEncodings() call
+ from Tcl_FindExecutable() into TclInitEncodingSubsystem(). This is
+ important on Windows where it establishes whether the "ascii" or
+ "unicode" set of system routines will be used, and that needs to be
+ done earlier to support filesystem operations. [Bug 1077005]
+
+2004-12-01 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * tests/winDde.test: Rewritten to use tcltest2 features more
+ thoroughly (reducing the [catch] count!) and fix the problem with
+ winDde-6.1 being out of synch with the implementation.
+
+2004-11-30 Don Porter <dgp@users.sourceforge.net>
+
+ * library/init.tcl ([unknown]): Restored the save/restore of the
+ variables ::errorCode and ::errorInfo. This is needed when the
+ [::bgerror] command is auto-loaded (as it is by Tk).
+
+ Patch 976520 reworks several of the details involved with
+ startup/initialization of the Tcl library, focused on the activities
+ of Tcl_FindExecutable().
+
+ * generic/tclIO.c: Removed bogus claim in comment that encoding
+ "iso8859-1" is "built-in" to Tcl.
+
+ * generic/tclInt.h: Created a new struct ProcessGlobalValue,
+ * generic/tclUtil.c: routines Tcl(Get|Set)ProcessGlobalValue, and
+ function type TclInitProcessGlobalValueProc. Together, these take care
+ of the housekeeping for "values" (things that can be held in a
+ Tcl_Obj) that are global across a whole process. That is, they are
+ shared among multiple threads, and epoch and mutex protection must
+ govern the validity of cached copies maintained in each thread.
+
+ * generic/tclNotify.c: Modified TclInitNotifier() to tolerate being
+ called multiple times in the same thread.
+ * generic/tclEvent.c: Dropped the unused argv0 argument to
+ TclInitSubsystems(). Removed machinery to unsure only one
+ TclInitNotifier() call per thread, now that that is safe. Converted
+ Tcl(Get|Set)LibraryPath to use a ProcessGlobalValue, and moved them to
+ tclEncoding.c.
+ * generic/tclBasic.c: Updated caller.
+
+ * generic/tclInt.h: TclpFindExecutable now returns void.
+ * unix/tclUnixFile.c:
+ * win/tclWinFile.c:
+ * win/tclWinPipe.c:
+
+ * generic/tclEncoding.c: Built new encoding search initialization on a
+ foundation of ProcessGlobalValues, exposing new routines
+ Tcl(Get|Set)EncodingSearchPath. A cache of a map from encoding name to
+ directory pathname keeps track of where encodings are available for
+ loading. Tcl_FindExecutable greatly simplified into just three
+ function calls. The "library path" is now misnamed, as its only
+ remaining purpose is as a foundation for the default encoding search
+ path.
+
+ * generic/tclInterp.c: Inlined the initScript that is evaluated by
+ Tcl_Init(). Added verification after initScript evaluation that Tcl
+ can find its installed *.enc files, and that it has initialized
+ [encoding system] in agreement with what the environment expects.
+ [tclInit] no longer driven by the value of $::tcl_libPath; it largely
+ constructs its own search path now, rather than attempt to share one
+ with the encoding system.
+
+ * unix/tclUnixInit.c: TclpSetInitialEncodings factored so that a new
+ * win/tclWinInit.c: routine TclpGetEncodingNameFromEnvironment can
+ reveal that Tcl thinks the [encoding system] should be, even when an
+ incomplete encoding search path, or a missing *.enc file won't allow
+ that initialization to succeed. TclpInitLibraryPath reworked as an
+ initializer of a ProcessGlobalValue.
+
+ * unix/tclUnixTest.c: Update implementations of [testfindexecutable],
+ [testgetdefenc], and [testsetdefenc].
+
+ * tests/unixInit.test: Corrected tests to operate properly even when
+ a value of TCL_LIBRARY is required to find encodings.
+
+ * generic/tclInt.decls: New internal stubs: TclGetEncodingSearchPath,
+ TclSetEncodingSearchPath, TclpGetEncodingNameFromEnvironment. These
+ are candidates for public exposure by future TIPs.
+
+ * generic/tclIntDecls.h: make genstubs
+ * generic/tclStubInit.c:
+
+ * generic/tclTest.c: Updated [testencoding] to use
+ * tests/encoding.test: Tcl(Get|Set)EncodingSearchPath. Updated tests.
+
+2004-11-30 Kevin B. Kenny <kennykb@acm.org>
+
+ * library/clock.tcl: Corrected the regular expressions that match a
+ time zone to allow for time zones specified as +HH or -HH.
+ * tests/clock.test: Added regression test case for the above issue.
+ Thanks to Rolf Ade for reporting this issue [http://wiki.tcl.tk/13094]
+ * win/tclWinDde.c (Tcl_DdeObjCmd): Corrected a typo that caused a
+ compilation failure on VC++.
+
+2004-11-29 Andreas Kupries <andreask@activestate.com>
+
+ * win/Makefile.in (install-libraries): Brought entry '2004-10-26 Don
+ Porter (Tcl Modules)' into the windows world, actually the
+ win/configure buildsystem. The other windows buildsystems (.vc, .bc)
+ still have to be updated as well.
+
+2004-11-26 Andreas Kupries <andreask@activestate.com>
+
+ * win/tclWinDde.c (ExecuteRemoteObject): Removed bogus semicolon found
+ at the end of the header for the function definition, terminating it
+ early and preventing a compile. This is likely a fix for '2004-11-25
+ Donal'. I have to conclude that it is also unknown if the other
+ changes to this file actually pass the testsuite. Running testsuite
+ ... They don't. winDde-6.1 fails. This is only a message discrepance,
+ i.e. not too bad. Leaving resolution of that to Pat and Donal.
+
+2004-11-26 Don Porter <dgp@users.sourceforge.net>
+
+ * library/auto.tcl (tcl_findLibrary): Made sure the uniquifying
+ operations on the search path does not also normalize. [Bug 1072136]
+
+2004-11-26 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * unix/configure.in: Simplify the code to check for correctness of
+ strstr, strtoul and strtod.
+ * unix/tcl.m4 (SC_TCL_CHECK_BROKEN_FUNC): Split a complex stanza out
+ of configure.in into its own function. Also force it to do the right
+ thing with cacheing of results of AC_TRY_RUN to deal with issue raised
+ in [Patch 1073524]
+
+ * doc/foreach.n: Added simple example. [FRQ 1073334]
+
+2004-11-25 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclProc.c (TclObjInterpProc): Make it so that only
+ * generic/tclIndexObj.c (Tcl_WrongNumArgs): [proc] instances do
+ * tests/indexObj.test (indexObj-5.7): quoting of their first
+ arguments, so keeping [Bug 942757] fixed and making [Bug 1066837] be
+ fixed as well. Done with a load of #ifdef-ery because this hack is so
+ ugly nobody should keep it around once Itcl's fixed.
+
+2004-11-25 Reinhard Max <max@suse.de>
+
+ * tests/tcltest.test: The order in which [glob] returns the file names
+ is undefined, so tests should not depend on it.
+
+2004-11-25 Zoran Vasiljevic <vasiljevic@users.sf.net>
+
+ * doc/Thread.3:
+ * doc/Notifier.3: Added changes from the core-8-4-branch
+
+2004-11-25 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/dde.n: Synchronized the documentation of the commands with the
+ header of the docs and what the package actually does. Thanks to
+ Andreas Kupries for spotting this.
+ * win/tclWinDde.c (Tcl_DdeObjCmd): Much cleanup of argument parsing
+ code.
+
+2004-11-24 David Gravereaux <davygrvy@pobox.com>
+
+ * generic/tclPort.h: Relative include of tclWinPort.h returned as it
+ was requiring me set -I$(tcl_root)/win for my extensions that need to
+ include tclInt.h and doesn't appear to serve any purpose for windows
+ builds.
+
+2004-11-24 Kevin B. Kenny <kennykb@acm.org>
+
+ * unix/tcl.m4 (SC_ENABLE_THREADS): Corrected bad check for 3-argument
+ readdir_r [Bug 1001325].
+ * unix/configure: Regenerated.
+ * unix/tclUnixNotfy.c: Corrected all uses of 'select' to manage their
+ masks using the FD_CLR, FD_ISSET, FD_SET, and FD_ZERO macros rather
+ than bit-whacking that failed under Solaris-Sparc-64. [Bug 1071807]
+ * win/tclWinInit.c (TclpInitLibraryPath): Removed unused vars 'pathc'
+ and 'pathv' that caused compilation problems on VC++ with
+ --enable-symbols.
+
+2004-11-24 Don Porter <dgp@users.sourceforge.net>
+
+ * unix/tcl.m4 (SC_ENABLE_THREADS): Corrected failure to determine the
+ number of arguments for readdir_r on SunOS systems. [Bug 1071701]
+
+ * unix/configure: autoconf-2.57
+
+ * generic/tclCmdIL.c (InfoVarsCmd): Corrected segfault in new
+ * tests/info.test (info-19.6): trivial matching branch [Bug 1072654]
+
+2004-11-24 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * tools/man2html.tcl, tools/man2html1.tcl: Update to use Tcl 8.4.
+ * tools/man2html2.tcl: Fix broken .SS handling.
+
+2004-11-23 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * unix/Makefile.in: Add (commented-out) code to integrate tclConfig.h
+ into the dependency tree and 'make distclean'. [Bug 1068171]
+
+ * generic/tclResult.c (Tcl_AppendResultVA): Remove call to
+ Tcl_GetStringResult to speed up repeated calls to Tcl_AppendResult
+ with the side effect that code that wants to access interp->result
+ should always call Tcl_GetStringResult first. See [Patch 1041072]
+ discussion for more details.
+
+2004-11-22 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/configure: Regen.
+ * unix/tcl.m4 (SC_TCL_64BIT_FLAGS): Define HAVE_TYPE_OFF64_T only when
+ off64_t, open64(), and lseek64() are defined. IRIX 5.3 is known to not
+ include an open64 function. [Bug 1030465]
+
+2004-11-22 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/configure: Regen.
+ * unix/tcl.m4 (SC_ENABLE_THREADS): Check for a 2 argument version of
+ readdir_r that is known to exists under IRIX 5.3.
+ * unix/tclUnixThrd.c (TclpReaddir): Use either 2 arg or 3 arg version
+ of readdir_r. [Bug 1001325]
+
+2004-11-22 Don Porter <dgp@users.sourceforge.net>
+
+ * unix/tclUnixInit.c (TclpInitLibraryPath): Purged dead code that used
+ * win/tclWinInit.c (TclpInitLibraryPath): to extend the "library
+ path". Search path construction for init.tcl is now done within the
+ [tclInit] proc.
+ * generic/tclInterp.c: Restored several directories to the search
+ * tests/unixInit.test: path used to locate init.tcl within [tclInit].
+ This change does not restore any directories to the encoding search
+ path, so should still avoid the price of an unreasonably large number
+ of filesystem accesses during encoding initialization at startup
+ [Bug 976438]
+
+2004-11-22 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclPathObj.c: fix and new test for [Bug 1043129] in the
+ * tests/fileSystem.test: treatment of backslashes in file join on
+ Windows.
+
+2004-11-21 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/AddErrInfo.3: Typo corrections (Thanks Daniel South).
+ * doc/interp.n:
+
+2004-11-19 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/AddErrInfo.3: Docs for Tcl_(Get|Set)ReturnOptions. [TIP 227]
+
+ * doc/AddErrInfo.3:
+ * doc/Async.3: Documentation updates to replace references
+ * doc/BackgdErr.3: to global variable ::errorInfo and ::errorCode
+ * doc/SaveResult.3: and to the ::bgerror command with references
+ * doc/after.n: to their preferred replacements, the
+ * doc/bgerror.n: -errorinfo and -errorcode return options,
+ * doc/error.n: the Tcl_*InterpState routines, and the
+ * doc/exec.n: [interp bgerror] command.
+ * doc/exit.n:
+ * doc/fileevent.n:
+ * doc/interp.n:
+ * doc/return.n:
+ * doc/tclvars.n:
+ * doc/update.n:
+
+ * tests/unixInit.test: Removed "knownBug" constraints to prompt bug
+ fixing before 8.5a2 release.
+
+2004-11-19 Daniel Steffen <das@users.sourceforge.net>
+
+ * macosx/Makefile:
+ * unix/configure.in:
+ * unix/tclUnixInit.c (MacOSXGetLibraryPath): changed detection of tcl
+ framework build when determining tclLibPath from overloaded
+ TCL_LIBRARY to configuration define TCL_FRAMEWORK. [Bug 1068088]
+
+ * unix/configure: autoconf-2.57
+ * unix/tclConfig.h.in: autoheader-2.57
+
+2004-11-18 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/SaveResult.3: Documentation for Tcl_*InterpState (TIP 226).
+
+ * generic/tclEvent.c (HandleBgErrors): Simplified program flow.
+
+ * tests/basic.test: Updated functional (not testing) uses of
+ * tests/io.test: [bgerror] to make use of [interp bgerror].
+ * tests/socket.test:
+ * tests/timer.test:
+
+ * tests/interp.test (interp-36.*): [interp bgerror] tests.
+
+ * generic/tclInterp.c: Corrected [interp bgerror] error messages.
+
+2004-11-18 Reinhard Max <max@suse.de>
+
+ * unix/tcl.m4 (SC_CONFIG_MANPAGES): Applied an improved version of
+ * unix/configure.in: [Patch 996085], that introduces
+ * unix/Makefile.in: --enable-man-suffix.
+
+ * unix/installManPage: added
+ * unix/mkLinks.tcl: removed
+ * unix/mkLinks: removed
+ * unix/configure: generated
+
+ * unix/Makefile.in: Don't install tclConfig.h .
+
+2004-11-17 Don Porter <dgp@users.sourceforge.net>
+
+ * unix/configure.in: The change below reveals that the public data
+ type Tcl_StatBuf relies on config information. For now, disabled the
+ use of the tclConfig.h file until its full impact on Tcl's interface
+ can be assessed.
+
+ * unix/configure: autoconf-2.57
+
+ * generic/tcl.h: Moved the #include "tclConfig.h" out of
+ * generic/tclInt.h: tcl.h. The config settings are not part of
+ * generic/tclPort.: the public interface, and having it there
+ breaks compiled against uninstalled Tcl and extensions using
+ autoconf-2.5*.
+
+2004-11-16 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/tclUnixChan.c (TtySetOptionProc): fixed crash configuring
+ -ttycontrol on a channel. [Bug 1067708]
+
+2004-11-16 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclIOUtil.c (TclFSEpochOk): There were two code paths via
+ which the thread copy of filesystemEpoch could be synched with the
+ master copy, but only one kept the filesystem list cache up to date.
+ Fix routes everything through a single code path. [Bug 1035775].
+
+2004-11-16 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): Stop architecture flags to 'ld' from
+ getting lost when [load] is disabled. [Bug 1016796]
+
+2004-11-16 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tcl.h:
+ * unix/configure.in: changed HAVE_CONFIG_H to HAVE_TCL_CONFIG_H.
+
+ * unix/configure: autoconf-2.57
+
+2004-11-15 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclInt.h: Added comment warning that the old ERR_IN_PROGRESS
+ and ERROR_CODE_SET flag values should not be re-used for the sake of
+ those extensions that have accessed them.
+
+ * generic/tclCmdMZ.c (Tcl_TraceObjCmd): Fixed Bug 1065378 which failed
+ * tests/trace.test (trace-33.1): to permit a variable trace
+ created with [trace variable] to be destroyed with [trace remove].
+ Thanks to Keith Vetter for the report.
+
+2004-11-15 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/tclvars.n: Added section to documentation on global variables
+ that are specific to tclsh and wish. [Patch 1065732]
+
+2004-11-12 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclEncoding.c (TableFromUtfProc): correct crash condition
+ when TCL_UTF_MAX == 6. [Bug 1004065]
+
+2004-11-12 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/interp.n: Basic documentation of the TIP#221 API.
+
+2004-11-12 Don Porter <dgp@users.sourceforge.net>
+
+ TIP #221 IMPLEMENTATION
+ * generic/tclBasic.c: Define [::tcl::Bgerror] in new interps.
+ * generic/tclEvent.c: Update Tcl_BackgroundError to make use of the
+ registered [interp bgerror] command.
+ * generic/tclInterp.c: New [interp bgerror] subcommand.
+ * tests/interp.test: syntax tests updated.
+
+ TIP #226 IMPLEMENTATION
+ * generic/tcl.decls: Stubs for Tcl_(Save|Restore|Discard)InterpState
+ * generic/tcl.h: New public opaque type, Tcl_InterpState.
+ * generic/tclInt.h: Drop old private declarations. Add
+ Tcl(Get|Set)BgErrorHandler
+ * generic/tclResult.c: Tcl_*InterpState implementations.
+ * generic/tclDictObj.c: Update callers.
+ * generic/tclIOGT.c:
+ * generic/tclTrace.c:
+
+ TIP #227 IMPLEMENTATION
+ * generic/tcl.decls: Stubs for Tcl_(Get|Set)ReturnOptions.
+ * generic/tclInt.h: Drop old private declarations.
+ * generic/tclResult.c: Tcl_*ReturnOptions implementations.
+ * generic/tclCmdAH.c: Update callers.
+ * generic/tclMain.c:
+
+ * generic/tclDecls.h: make genstubs
+ * generic/tclStubInit.c:
+
+ * unix/tclAppInit.c: Removed tclConfig.h #include, now that tcl.h
+ takes care of it for us.
+
+ * generic/tclInt.h: Moved verification of ptrdiff_t typedef from
+ * generic/tclExecute.c: multiple .c files into one common header where
+ * generic/tclVar.c: it is verifiably after tclConfig.h inclusion.
+
+2004-11-12 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tcl.h:
+ * generic/tclInt.h:
+ * unix/Makefile.in: include tclConfig.h from tcl.h and install it as a
+ public header. Normalized compiler include path order to
+ -I${BUILD_DIR} -I${UNIX_DIR} -I${GENERIC_DIR}.
+
+ * unix/dltest/Makefile.in: add ${BUILD_DIR}/.. to include path to pick
+ up tclConfig.h.
+
+ * unix/tclUnixInit.c: moved check for HAVE_CFBUNDLE define after
+ #include "tclInt.h" to ensure tclConfig.h has been included.
+
+2004-11-12 Reinhard Max <max@suse.de>
+
+ * unix/config.h.in:
+ * unix/tclConfig.h.in: renamed
+
+ * unix/Makefile.in: Completed support for config header,
+ * unix/configure.in: fixed building outside of the unix dir,
+ * unix/tclAppinit.c: and reflected the name change of config.h.
+ * generic/tclInt.h:
+
+ * unix/configure: generated
+
+2004-11-12 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * unix/config.h.in: Allow configure to put all the C #defs into
+ * unix/configure.in: a file (called config.h) so that Unix builds
+ * unix/tcl.m4: now take far fewer lines of scrollback to
+ * unix/Makefile.in: proceed (making it less likely that any errors
+ * generic/tclInt.h: or warnings will get missed).
+ * unix/tclAppInit.c: Part of the TIP#34 upgrades.
+
+ * unix/tcl.m4, unix/tclUnixPort.h: Check for pthread_attr_get_np in
+ <pthread.h> before forcing the use of <pthread_np.h> to make things
+ work on NetBSD 2.0. [Bug 1064882]
+
+ * doc/binary.n, doc/upvar.n: More minor fixes.
+
+2004-11-12 Daniel Steffen <das@users.sourceforge.net>
+
+ * doc/CrtChannel.3:
+ * doc/Interp.3:
+ * doc/Limit.3:
+ * doc/binary.n:
+ * doc/dict.n:
+ * doc/tm.n:
+ * doc/upvar.n: fixed *roff errors uncovered by running 'make html'.
+
+ * tools/tcltk-man2html.tcl: added faked support for bullet point
+ lists, i.e. *nroff ".IP \(bu" syntax.
+
+2004-11-11 Daniel Steffen <das@users.sourceforge.net>
+
+ * tests/fCmd.test:
+ * unix/tclUnixFCmd.c (TraverseUnixTree): added option to rewind() the
+ readdir() loop whenever the source hierarchy has been modified by
+ traverseProc (e.g. by deleting files); this is required to ensure
+ complete traversal of the source hierarchy on certain filesystems like
+ HFS+. Added test for failing recursive delete on Mac OS X that was due
+ to this. [Bug 1034337]
+
+ * generic/tclListObj.c (Tcl_ListObjReplace): use memmove() instead of
+ manual copy loop to shift list elements. Decreases time spent in
+ Tcl_ListObjReplace() from 5.2% to 1.7% of overall runtime of tclbench
+ on a ppc 7455 (i.e. 200% speed increase). [Patch 1064243]
+
+ * generic/tclHash.c: hoisted some constant pointer dereferences out of
+ loops to eliminate redundant loads that the gcc optimizer didn't deal
+ with. Decreases time spend in Tcl_FindHashEntry() by 10% over a full
+ run of the tcl testuite on a ppc 7455. [Patch 1064243]
+
+ * tests/fileName.test:
+ * tests/fileSystem.test:
+ * tests/io.test:
+ * tests/msgcat.test:
+ * tests/tcltest.test:
+ * tests/unixInit.test: fixed bugs causing failures when running tests
+ with -tmpdir arg not set to working dir.
+
+ * macosx/Makefile: corrected path to html help inside framework.
+ Prevent parallel make from building several targets at the same time.
+
+ * macosx/tclMacOSXFCmd.c (struct fileinfobuf): force struct to be
+ packed to prevent failures when builing with -malign=natural.
+
+2004-11-10 Andreas Kupries <andreask@activestate.com>
+
+ * unix/tclUnixChan.c: [Bug 727786]. Exterminated the code marked
+ DEPRECATED. This code has not been used in over a year now, and we
+ have no complaints.
+
+2004-11-08 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinPipe.c: The pipe channel driver now respects the -blocking
+ option when closing is the same way the UNIX side works. This is to
+ avoid a hung shell when exiting due to open pipes that refuse to close
+ in a graceful manner.
+ * doc/open.n: Added a note about -blocking 0 and lack of exit status
+ as it had never been documented. [Bug 947693]
+
+ ***POTENTIAL INCOMPATIBILITY***
+
+ Scripts that use async pipes on windows, must (like the UNIX side) set
+ -blocking to 1 before calling [close] to receive the exit status.
+
+2004-11-07 David Gravereaux <davygrvy@pobox.com>
+
+ * tests/winFile.test: added contraint to winFile-4.0 to prevent it
+ being run on NT4 [Bug 981829]
+
+2004-11-05 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * tests/reg.test: Major reorganization so that this file is much
+ easier for a normal Tcl maintainer to comprehend. The test flags are
+ still very cryptic, but they appear to have to be that way. The number
+ of skipped tests has increased, but now the skipped tests have much
+ more meaningful content.
+
+ * tests/tm.test (genpaths): Add a [file normalize] so we pick up
+ Windows drive letters, etc. [Bug 1053568]
+
+2004-11-04 Don Porter <dgp@users.sourceforge.net>
+
+ * changes: Updates toward an 8.5a2 release.
+
+2004-11-03 Kevin B. Kenny <kennykb@acm.org>
+
+ * library/clock.tcl (FreeScan): Fixed a bug where scanning "Monday"
+ with a base time other than midnight incorrectly carried the base time
+ forward.
+
+ * test/clock.test (clock-33.{5,5a}): Made the test failure more
+ informative.
+
+ * tests/clock.test (clock-34.{28,44,45,46}): Removed 'knownBug'
+ constraints from tests that no longer fail.
+
+ Thanks to Don Porter for reporting these.
+
+2004-11-03 David Gravereaux <davygrvy@pobox.com>
+
+ * generic/tcl.h: Moved the preprocessor logic
+ * generic/tclDecls.h: from tclInt.h of setting the
+ * generic/tclInt.h: TCL_STORAGE_CLASS macro to the
+ * generic/tclIntDecls.h: tcl*Decls.h files now that no
+ * generic/tclIntPlatDecls.h: use of EXTERN is left in tclInt.h.
+ * generic/tclPlatDecls.h: Proto for Tcl_Main moved in tcl.h
+ * win/tclWinPort.h: to prior the inclusion of the Stubs
+ headers as they are now resetting TCL_STORAGE_CLASS. Removed
+ extraineous reset from tclWinPort.h. [Patch 1055668]
+
+ * generic/tclCompile.h: Removed extrainious reset of TCL_STORAGE_CLASS
+ missed in my last edit.
+
+2004-11-03 Don Porter <dgp@users.sourceforge.net>
+
+ * library/init.tcl ([unknown]): Corrections to the 2004-10-25 mods to
+ Aunt ??? in [unknown]. Flaws revealed by Itcl test suite, which still
+ apparently relies on this brokenness. Also added comment suggesting
+ the error message that any code using this hack *ought* to receive in
+ reply.
+
+ * generic/tclTrace.c (TclCallVarTraces): Improved ability to debug
+ * tests/incr-old.test (incr-old-2.6): errors during variable
+ * tests/incr.test (incr-{1,2}.28): traces by preserving the
+ * tests/set.test (set-{2,4}.4): -errorinfo data.
+ * tests/trace.test (trace-33.1): [Bug 527164]
+
+2004-11-02 David Gravereaux <davygrvy@pobox.com>
+
+ * generic/tclInt.h: added a check for #ifdef __cplusplus around the
+ #define of MODULE_SCOPE. About the only time it would be problem is
+ when someone is statically linking to Tcl and accessing internals from
+ a C++ file and has name mangling issues from the lack of "C" after
+ 'extern' [Patch 1055668].
+ * generic/tclCompile.h: Exchanged use of the EXTERN macro to the new
+ MODULE_SCOPE macro. Lowered exported internals count by 35. [Patch
+ 1055668]
+ * win/tclWinInt.h:
+ * win/tclWinPort.h: exported internals dropped by a count of 14.
+ * generic/tclFileSystem.h: Added use of MODULE_SCOPE on protos.
+ * generic/tclRegexp.h: manipulating TCL_STORAGE_CLASS unnecessary.
+
+2004-11-02 Don Porter <dgp@users.sourceforge.net>
+
+ * library/tcltest/tcltest.tcl: Corrected some misleading
+ * tests/tcltest.test (tcltest-26.1,2): displays of ::errorInfo and
+ ::errorCode information when the -setup, -body, and/or -cleanup scripts
+ return an unexpected return code. Thanks to Robert Seeger for the fix.
+ [RFE 1017151].
+
+2004-11-02 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclExecute.c (TclExecuteByteCode): Improved version of the
+ NaN fix from Miguel Sofer. [Bug 761471]
+
+2004-11-02 Kevin Kenny <kennykb@acm.org>
+
+ * library/tzdata/America/Cuiaba: Change to DST rules for
+ * library/tzdata/America/Havana: autumn of 2004.
+ [ftp://elsie.nci.nih.gov/pub/tzdata2004g.tar.gz]
+
+ * tools/tclZIC.tcl: Updated to be compatible with recent changes in
+ library/clock.tcl.
+
+2004-11-02 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * win/tclWinFile.c: Simplify TclpUtime to use Tcl_FSGetNativePath, and
+ add comments.
+
+2004-11-02 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclInt.h: Change uses of EXTERN to MODULE_SCOPE (defined in
+ this file too to be 'extern' if not overridden) as nothing declared in
+ tclInt.h is supposed to be visible outside the Tcl core. If there *is*
+ anything that extensions are actually using, we can open this up later
+ on. [Patch 1055668]
+
+ * doc/CrtChannel.3 (Tcl_GetChannelMode): Add synopsis. [Bug 1058446]
+
+2004-11-01 Kevin B. Kenny <kennykb@acm.org>
+
+ * win/tclWinFile.c (FromCTime, TclpUtime): Replaced a call to the
+ Posix 'utime' function with calls to Windows-API equivalents, to avoid
+ a bug where the VC++ versions misconvert times across a Daylight
+ Saving Time boundary. [Bug 926106]
+ * win/tclWinInt.h (TclWinProcs):
+ * win/tclWin32Dll.c (asciiProcs, unicodeProcs): Removed now-unused
+ reference to 'utime'.
+ * tests/cmdAH.test (cmdAH-24.12): Added test case for the above bug.
+
+2004-11-01 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclExecute.c (TclExecuteByteCode): Make INST_EQ and friends
+ handle NaN correctly in all cases. [Bug 761471]
+
+ * generic/tclNamesp.c (NamespaceInscopeCmd): Make the error message
+ generation the same as in NamespaceEvalCmd().
+ (Tcl_Import): Rationalized to use Tcl_EvalObjv().
+
+2004-10-31 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * tests/io.test (io-40.3): Convert umask2 test constraint into a form
+ that most people will be able to satisfy.
+
+ * tests/cmdAH.test (cmdAH-8.45): Removed broken test constraint. It
+ didn't do what it was intended to do, and it implied the other correct
+ constraint. [Bug 1053908]
+
+ * generic/tclCmdIL.c (InfoGlobalsCmd):
+ * tests/info.test (info-8.4): Strip leading global-namespace
+ specifiers from the pattern argument. [Bug 1057461]
+
+2004-10-30 Kevin Kenny <kennykb@acm.org>
+
+ * generic/clock.c: Replaced WIN32 macro with __WIN32__. [Bug 1054357].
+ Thanks to David Gravereaux for the patch.
+ * win/tclWinFile.c: Removed a long-standing bug that causes incorrect
+ conversion between file time and UTC time if the file time is recorded
+ in a different Daylight Saving Time status than the current one. [Bug
+ 926106]
+
+2004-10-29 Don Porter <dgp@users.sourceforge.net>
+
+ * library/tcltest/tcltest.tcl: Correct reaction to errors in the
+ obsolete processCmdLineArgsHook. [Bug 1055673]
+ * library/tcltest/pkgIndex.tcl: Bump to tcltest 2.2.7
+ * unix/Makefile.in:
+ * tests/all.tcl: Update to use [tcltest::configure].
+
+2004-10-29 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * library/tm.tcl (::tcl::tm::*): Use the core proc engine to generate
+ the wrong-num-args error messages for the path ensemble.
+
+ Ensembles can now (sometimes) rewrite the error messages of their
+ subcommands so they appear more like the arguments that the user
+ passed to the ensemble. Below is a description of changes involved in
+ doing this.
+
+ * tests/namespace.test (namespace-50.*): Tests of ensemble subcommand
+ error message rewriting.
+ * generic/tclProc.c (TclObjInterpProc): Make procedures implement
+ their wrong-num-args message using Tcl_WrongNumArgs instead of
+ something baked-at-home.
+ * generic/tclNamesp.c (TclIsEnsemble, NsEnsembleImplementationCmd):
+ Added test of ensemble-hood (available to rest of core) and made
+ ensembles set up the rewriting for Tcl_WrongNumArgs to take advantage
+ of.
+ * generic/tclInt.h (Interp.ensembleRewrite): Extra fields.
+ * generic/tclIndexObj.c (Tcl_WrongNumArgs): Add knowledge of what is
+ going on in ensembles' command rewriting so this command can generate
+ the right error message itself.
+ * generic/tclBasic.c (Tcl_CreateInterp, TclEvalObjvInternal): Added
+ code to initialize (as empty) the rewriting fields and reset them when
+ we leak outside an ensemble implementation.
+
+2004-10-28 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c (INST_START_CMD):
+ * tests/execute.test (execute-8.3): fix for execution stack corruption
+ [Bug 1055676]. Credit dgp for detective work and fix.
+
+2004-10-27 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/socket.test (socket-13.1): Balanced [makeFile] and
+ [removeFile] commands.
+
+ * tests/clock.test: Correct duplicate test names.
+ * tests/namespace.test:
+ * tests/string.test:
+ * tests/io.test (io-50.4): Use namespace variables.
+
+2004-10-27 David Gravereaux <davygrvy@pobox.com>
+
+ * generic/tclInt.decls: The following 9 functions were moved from
+ * generic/tclInt.h: tclInt.h to the private/int Stubs table for
+ * generic/tclIntDecls.h: use by the test suite. As tclTest.obj is
+ * generic/tclStubInit.c: linked to the shell, these functions need
+ "blessed" status so as to always be exported from the library. Being
+ placed in the Stubs table guarantees this [Bug 1054748]:
+ TclpObjRemoveDirectory, TclpObjCopyDirectory,
+ TclpObjCreateDirectory, TclpObjDeleteFile,
+ TclpObjCopyFile, TclpObjRenameFile,
+ TclpObjStat, TclpObjAccess,
+ TclpOpenFileChannel
+
+ * tests/registry.test: Fixed test files to load the correct
+ * tests/winDde.test: registry and dde packages by using the info
+ * win/Makefile.in: from makefiles to tell tcltest where to load
+ * win/makefile.vc: them from. This avoids grabbing the wrong
+ package from $auto_path which might be the install point rather than
+ the dev location. Kudos to Jennifer Hom for adding -load and
+ -loadfile to the tcltest package. [Bug 926088]
+
+ * win/tclWinThrd.c (TclFinalizeLock): release the critical section
+ before deleting it. [Bug 731778]
+
+ * generic/tcl.h: Removed the file level 'extern "C" {' and the
+ coresponding closing block as it serves no purpose given that all the
+ function prototypes have the proper extern usage already.
+
+ * unix/tclAppInit.c: When built as tcltest, TclThread_Init was
+ * win/tclAppInit.c: getting called twice. First by Tcltest_Init,
+ then again in Tcl_AppInit. The call from Tcl_AppInit is now removed.
+
+2004-10-27 Andreas Kupries <andreask@activestate.com>
+
+ * tests/tm.test: Expanded on the testsuite entered by Donal.
+ * library/tm.tcl: Even found bugs, these have been corrected.
+
+2004-10-26 Kevin Kenny <kennykb@acm.org>
+
+ * tests/format.test (format-19.1): Additional regression test for [Bug
+ 868489].
+
+2004-10-27 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/*.n: Many small general documentation fixes.
+
+2004-10-26 David Gravereaux <davygrvy@pobox.com>
+
+ * generic/tclPipe.c (TclCleanupChildren): bad cast of resolvedPid
+ caused PIDs on win95 to go negative. winpipe-4.2 brought this to the
+ surface. Fixed with sprintf in place of TclFormatInt. Thanks to hgiese
+ [Patch 767676]
+
+2004-10-26 Andreas Kupries <andreask@activestate.com>
+
+ * library/tm.tcl (::tcl::tm::Defaults): Added a second [file dirname]
+ around the location of the executable. This fixes [Bug 1038705].
+ Instable of a bogus "foo/bin/lib" we now have the correct "foo/lib" as
+ a base path for modules.
+
+2004-10-26 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclParse.c (Tcl_SubstObj): Fix for failed subst-12.3 test
+ * tests/subst.test (subst-12.3-5): More tests for Bug 1036649.
+
+ * unix/Makefile.in (install-libraries): Updated the installation of
+ the http, msgcat, and tcltest packages to install as Tcl Modules on
+ Unix systems. Other platform Makefiles still need updating. [Patch
+ 1054370]
+
+ * tests/basic.test: Added missing constraints.
+ * tests/compile.test:
+ * tests/fileSystem.test:
+
+ * tests/init.test (init-2.8): Updated to not rely on http package.
+
+2004-10-26 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclInt.h:
+ * generic/tclVar.c: removed more direct references to the VAR flags,
+ replaced with access macros.
+
+2004-10-26 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/expr.n: Clarified that non-num/non-bool literals require
+ quoting. [Bug 1027849]. Also listed booleans as acceptable values.
+
+2004-10-26 Kevin B. Kenny <kennykb@acm.org>
+
+ * library/clock.tcl (FreeScan): Fixed a bug that caused relative days
+ of the week in free-form [clock scan] to be evaluated in the wrong
+ time zone.
+ * tests/clock.test (clock-31.[456]): Made sure that there isn't an
+ env(TZ) or env(TCL_TZ) lying around that will override the time zone
+ that we're trying to establish with the simulated registry.
+ Both problems reported as [Bug 1054101].
+
+2004-10-25 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/string.n (map): Rewrote to clarify that we don't just map single
+ characters. [Bug 1048005]
+ * doc/info.n (procs): Clarified that the pattern argument may have
+ namespace separators in it. [Bug 1047928]
+
+ * tests/cmdAH.test (cmdAH-8.45): Simplify in the hope that the reasons
+ for [Bug 1053908] will become clearer.
+
+2004-10-25 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclExecute.c (IllegalExprOperandType,TclExecuteByteCode):
+ Removed several DECACHE_INFO/CACHE_INFO pairs that are no longer
+ needed for protection because routines like Tcl_SetErrorCode() and
+ Tcl_AddErrorInfo() can no longer re-enter bytecode execution.
+
+ * generic/tclResult.c (TclProcessReturn): Bug fix. Be sure that a
+ missing -errorinfo option when code == TCL_ERROR causes the errorInfo
+ field to get reset.
+
+ * tests/thread.test (thread-4.4): Test depended on a ::errorInfo value
+ initialized to "". Added code to test to setup that requirement.
+
+ * library/auto.tcl: Purged Tcl's script library of all
+ * library/clock.tcl: remaining references to global vars
+ * library/init.tcl: ::errorInfo and ::errorCode.
+
+ * generic/tclMain.c (Tcl_Main): Updated to make use of
+ TclGetReturnOptions instead of ::errorInfo variable.
+
+ * generic/tclInterp.c (tclInit): Bug fix. Access dict variables with
+ [dict get], not array syntax.
+
+2004-10-25 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * tests/tm.test: Rewrote the tests to actually perform syntax checks
+ on the public API. Added a new test (currently failing) to indicate
+ that the test suite is not complete yet.
+ * library/tm.tcl (path): Rewrote to turn this command into an ensemble
+ to make it faster and simpler.
+
+2004-10-24 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCmdIL.c:
+ * generic/tclExecute.c:
+ * generic/tclInt.h:
+ * generic/tclTrace.c: defined new macros to get/set the flags of
+ variables. The only files that still access the flag values directly
+ are tclCompCmds.c, tclCompile.c, tclProc.c and tclVar.c
+
+2004-10-24 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c (Tcl_LogCommandInfo,Tcl_AddObjErrorInfo): Shift
+ the initialization of errorCode to NONE to more central location.
+
+ * generic/tclEvent.c (BgError,Tcl_BackgroundError,HandleBgErrors):
+ Rewrite to build on the new TclGet/SetReturnOptions routines.
+
+ * generic/tclResult.c (TclGetReturnOptions): Add call to
+ Tcl_AddObjErrorInfo to be sure error fields are initialized.
+
+ * generic/tclResult.c (TclTransferResult): Rewrite to build on the new
+ TclGet/SetReturnOptions routines.
+
+2004-10-22 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/tm.n: Tightened up the documentation.
+ * tests/tm.test: Created (with partially dummy content) so TIP#189 can
+ be marked Final.
+
+ * generic/tclNamesp.c (NsEnsembleImplementationCmd): Make ensembles
+ cut their implementations out of error traces. This is the right thing
+ to do more often than not.
+
+2004-10-22 Kevin B. Kenny <kennykb@acm.org>
+
+ * library/clock.tcl: Fixed a typo where the fallback time zone became
+ ::localtime instead of :localtime. Fixed a bug where time zone names
+ containing hyphens could not be loaded.
+ * tests/clock.test: Added regression test cases that covers both bugs.
+ Thanks to Todd M. Helfter <tmh@jumpgate.itsp.purdue.edu> for finding
+ these bugs.
+
+2004-10-22 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclExecute.c (TclCompEvalObj, Tcl_ExprObj):
+ * generic/tclProc.c (TclProcCompileProc): Always call object
+ freeIntRepProc's in the same way.
+
+2004-10-22 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclVar.c: fixed bug in commit of 2004-07-23, which was
+ causing a leak of Proc structures and failure of compile-12.1. Two
+ lines were 'zombies' from the previous way localVarNames worked.
+ Credit dgp for finding this.
+
+2004-10-21 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclInt.h (Interp):
+ * generic/tclBasic.c (Tcl_CreateInterp,Tcl_DeleteInterp):
+ * generic/tclResult.c (GetKeys,ReleaseKeys,etc.): Moved the key values
+ of the return options dictionary out of private fields of the Interp
+ struct and into thread-static values managed in tclResult.c.
+
+ * generic/tclCmdAH.c (Tcl_CatchObjCmd, Tcl_ErrorObjCmd): Updated to
+ call the new TclGet/SetReturnOptions routines to do much of their
+ work.
+
+ * generic/tclInt.h (TclGetReturnOptions,TclSetReturnOptions):
+ * generic/tclResult.c (TclGetReturnOptions,TclSetReturnOptions): New
+ utility routines to get/set the return options of an interp. Intent is
+ that these routines will be converted to public routines after TIP
+ approval.
+
+ * generic/tclCmdMZ.c (TclProcessReturn,TclMergeReturnOptions):
+ * generic/tclResult.c (TclProcessReturn,TclMergeReturnOptions): Move
+ internal utility routines from tclCmdMZ.c to tclResult.c.
+
+ * generic/tclBasic.c (Tcl_CreateInterp, Tcl_DeleteInterp):
+ * generic/tclResult.c (TclTransferResult): Rework so that
+ iPtr->returnOpts can be NULL when there are no special options.
+
+ * generic/tclResult.c (TclRestoreInterpState): Plug potential memory
+ leak.
+
+2004-10-21 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclBasic.c: Various changes to [clock format] that,
+ * generic/tclClock.c: together, make it roughly twice as fast
+ * generic/tclInt.h: while all tests in the test suite
+ * library/clock.tcl: continue to pass.
+
+2004-10-20 Andreas Kupries <andreask@activestate.com>
+
+ * win/Makefile.in (install-msgs): Fixed a problem with the
+ * win/Makefile.in (install-tzdata): installation of timezone data and
+ message catalogs. They used the installed tcl library directory, not
+ the source library. Before it was installed. Switched to source lib
+ dir. Thanks to Kevin for the help in figuring this out.
+
+2004-10-20 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclThreadTest.c (ThreadEventProc): Corrected subtle bug
+ where the returned (char *) from Tcl_GetStringResult(interp) continued
+ to be used without copying or refcounting, while activity on the
+ interp continued. That's not safe, and recent changes demonstrated the
+ lack of safety with failing tests thread-4.3 and thread-4.5.
+
+2004-10-19 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclDictObj.c (DictWithCmd): Make sure all paths (that are
+ not themselves error paths) do not lose the result code.
+
+2004-10-19 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclInt.h (Tcl*InterpState): New internal routines
+ * generic/tclResult.c (Tcl*InterpState): TclSaveInterpState,
+ TclRestoreInterpState, and TclDiscardInterpState are superior
+ replacements for Tcl_(Save|Restore|Discard)Result. Intent is that
+ these routines will be converted to public routines after TIP
+ approval. Interfaces for these routines were shamelessly stolen from
+ Itcl.
+
+ * generic/tclBasic.c (TclEvalObjvInternal):
+ * generic/tclDictObj.c (DictUpdateCmd, DictWithCmd):
+ * generic/tclIOGT.c (ExecuteCallback):
+ * generic/tclTrace.c (Trace*Proc,TclCheck*Traces,TclCallVarTraces):
+ Callers of Tcl_*Result updated to call the new routines. The calls
+ were relocated in several cases to perform save/restore operations
+ only when needed.
+
+ * generic/tclEvent.c (HandleBgErrors):
+ * generic/tclFCmd.c (CopyRenameOneFile): Calls to Tcl_*Result that
+ were eliminated because they appeared to serve no useful purpose,
+ typically saving/restoring an error message, only to throw it away.
+
+2004-10-18 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c (Tcl_CreateInterp,Tcl_DeleteInterp):
+ * generic/tclCmdAH.c (Tcl_CatchObjCmd):
+ * generic/tclCmdMZ.c (TclMergeReturnOptions,TclProcessReturn):
+ * generic/tclCompCmds.c (TclCompileReturnCmd):
+ * generic/tclExecute.c (TclCompEvalObj):
+ * generic/tclInt.h (Interp):
+ * generic/tclProc.c (TclUpdateReturnInfo): Place primary storage of
+ the -level and -code information in private fields of the Interp
+ struct, rather than in a DictObj. This should significantly improve
+ performance of TclUpdateReturnInfo.
+
+2004-10-17 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclResult.c: removed unused variable [Bug 1048588]. Thanks
+ to Daniel South.
+
+2004-10-15 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCmdMZ.c (TclProcessReturn): Now that primary
+ * generic/tclProc.c (TclUpdateReturnInfo): storage for the
+ errorInfo and errorCode values are internal fields, we can set them at
+ the time of the [return] command, and not have to wait until the
+ specified number of "-level"s have popped.
+
+ * generic/tclBasic.c (Tcl_CreateInterp, Tcl_DeleteInterp)
+ (TclEvalObjvInternal, Tcl_LogCommandInfo, TclAddObjErrorInfo):
+ * generic/tclCmdAH.c (Tcl_CatchObjCmd):
+ * generic/tclEvent.c (BgError, ErrAssocData, Tcl_BackgroundError)
+ (HandleBgErrors, BgErrorDeleteProc):
+ * generic/tclExecute.c (TclCreateExecEnv, TclDeleteExecEnv):
+ * generic/tclIOUtil.c (comments only):
+ * generic/tclInt.h (ExecEnv,Interp, ERR_IN_PROGRESS):
+ * generic/tclInterp.c ([tclInit]):
+ * generic/tclMain.c (comments only):
+ * generic/tclNamesp.c (Tcl_CreateNamespace, Tcl_DeleteNamespace)
+ (TclTeardownNamespace):
+ * generic/tclProc.c (TclUpdateReturnInfo):
+ * generic/tclResult.c (Tcl_ResetResult, TclTransferResult):
+ * generic/tclTrace.c (CallVarTraces):
+ Reworked management of the "errorInfo" data of an interp. That
+ information is now primarily stored in a new private (Tcl_Obj *) field
+ of the Interp struct, rather than using a global variable ::errorInfo
+ as the primary storage. The ERR_IN_PROGRESS flag bit value is no
+ longer required to manage the value in its new location, and is
+ removed. Variable traces are established to support compatibility for
+ any code expecting the ::errorInfo variable to hold the information.
+
+ ***POTENTIAL INCOMPATIBILITY***
+ Code that sets traces on the ::errorInfo variable may notice a
+ difference in timing of the firing of those traces. Code that uses the
+ value ERR_IN_PROGRESS.
+
+2004-10-14 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ TIP#217 IMPLEMENTATION
+
+ * generic/tclCmdIL.c (Tcl_LsortObjCmd): Add -indices option from James
+ Salsman. [Patch 1017532]
+
+ * generic/tclUtil.c (TclMatchIsTrivial): Detect degenerate cases of
+ glob matching that let us avoid scanning through hash tables.
+ * generic/tclCmdIL.c (InfoCommandsCmd, InfoGlobalsCmd, InfoProcsCmd):
+ (InfoVarsCmd): Use this to speed up some [info] subcommands.
+
+2004-10-12 Kevin B. Kenny <kennykb@acm.org>
+
+ * library/tzdata/America/Campo_Grande:
+ * library/tzdata/America/Cuiaba:
+ * library/tzdata/America/Sao_Paulo
+ * library/tzdata/America/Argentina/Mendoza:
+ * library/tzdata/America/Argentina/San_Juan:
+ Synchronized to Olson's 'tzdata2004e'.
+
+2004-10-08 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ TIP#201 AND TIP#212 IMPLEMENTATIONS
+
+ * doc/dict.n, doc/expr.n: Documentation for new functionality.
+ * tests/expr.test: Basic tests of 'in' and 'ni' behaviour.
+ * tests/dict.test (dict-21.*,dict-22.*): Tests for [dict update] and
+ [dict with].
+ * generic/tclExecute.c (TclExecuteByteCode): Implementation of the
+ INST_LIST_IN and INST_LIST_NOT_IN bytecodes.
+ * generic/tclParseExpr.c (GetLexeme): Parse the 'in' and 'ni'
+ operators for TIP#201.
+ * generic/tclDictObj.c (DictUpdateCmd,DictWithCmd): Core of
+ implementation of TIP#212; docs and tests still to do...
+
+2004-10-07 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclTest.c (TestsetobjerrorcodeCmd): Simplified.
+
+2004-10-07 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclFileName.c:
+ * generic/tclFileSystem.h:
+ * generic/tclIOUtil.c:
+ * generic/tclPathObj.c:
+ * unix/tclUnixFile.c:
+ * win/tclWinFile.c:
+ * tests/fileName.test:
+ * tests/winFCmd.test: code reorganization for better generic/platform
+ code splitting [Bug 925620] removing the need for several #ifdef's,
+ and tests and fix for an unreported Windows glob problem ('glob -dir
+ C: -tails *').
+
+2004-10-07 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * *.3: Convert CONST to const and VOID to void so we document how
+ people should actually use the Tcl API and not the compatability hacks
+ that it has to have.
+
+ * doc/man.macros, *.3: Update .AS macro so it can know how wide to
+ make the third column of the argument list. Update documentation for C
+ API (only users) to take advantage of this.
+
+ * doc/FileSystem.3: Formatting fixes for greater documentation
+ clarity.
+
+2004-10-06 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclFileName.c (DoGlob, TclGlob): Stop messy sharing of
+ interpreter result and instead use a private object for collecting the
+ result of the glob. This simplifies TclGlob quite a lot.
+ * generic/tclIOUtil.c (Tcl_FSMatchInDirectory): Simplify by removing
+ some nesting. Also standardize variable names.
+ (FsAddMountsToGlobResult): Force updates to the list to be done
+ in-place, putting a side-condition of non-shared-ness on the resultPtr
+ argument to Tcl_FSMatchInDirectory, but everything would have broken
+ before if that was shared *anyway*.
+
+ * generic/tclEncoding.c (LoadTableEncoding): Removed reference to Tcl
+ interpreter; it wasn't needed as direct object use is more efficient.
+
+ * generic/tclPathObj.c: Made this file follow the style rules in the
+ Engineering Manual more closely, and also take advantage of the
+ internal object manipulation macros more.
+
+ * generic/tclCmdMZ.c (Tcl_SwitchObjCmd): Reorganized to have fewer
+ magic flag variables and to separate the code that scans for a match
+ from the code that processes a match body.
+
+2004-10-06 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c:
+ * generic/tclBinary.c:
+ * generic/tclCmdAH.c:
+ * generic/tclCmdIL.c:
+ * generic/tclCmdMZ.c:
+ * generic/tclCompExpr.c:
+ * generic/tclDictObj.c:
+ * generic/tclEncoding.c:
+ * generic/tclExecute.c:
+ * generic/tclFCmd.c:
+ * generic/tclHistory.c:
+ * generic/tclIndexObj.c:
+ * generic/tclInterp.c:
+ * generic/tclIO.c:
+ * generic/tclIOCmd.c:
+ * generic/tclNamesp.c:
+ * generic/tclObj.c:
+ * generic/tclPkg.c:
+ * generic/tclResult.c:
+ * generic/tclScan.c:
+ * generic/tclTimer.c:
+ * generic/tclTrace.c:
+ * generic/tclUtil.c:
+ * generic/tclVar.c:
+ * unix/tclUnixFCmd.c:
+ * unix/tclUnixPipe.c:
+ * win/tclWinDde.c:
+ * win/tclWinFCmd.c:
+ * win/tclWinPipe.c:
+ * win/tclWinReg.c:
+ It is a poor practice to directly set or append to the value of the
+ objResult of an interp, because that value might be shared, and in
+ that circumstance a Tcl_Panic() will be the result. Searched for
+ example of this practice and replaced with safer alternatives, often
+ using the Tcl_AppendResult() routine that dkf just rehabilitated.
+ * library/dde/pkgIndex.tcl: Bump to dde 1.3.1
+ * library/reg/pkgIndex.tcl: Bump to registry 1.1.5
+
+2004-10-06 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/SetResult.3: Made Tcl_AppendResult non-deprecated; better that
+ people use it than most of the common alternatives!
+ * generic/tclResult.c (Tcl_AppendResultVA): Make this work better with
+ Tcl_Objs. [Patch 1041072]
+ (Tcl_SetResult, Tcl_AppendElement): Change string to stringPtr to
+ avoid C++ keywords.
+
+2004-10-05 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c (TclObjInvoke): More simplification of the
+ TclObjInvoke routine toward unification with the rest of the
+ evaluation stack.
+
+ * generic/tclBasic.c (Tcl_CreateInterp, Tcl_DeleteInterp)
+ (TclEvalObjvInternal, Tcl_LogCommandInfo):
+ * generic/tclCmdAH.c (Tcl_CatchObjCmd):
+ * generic/tclEvent.c (BgError, Tcl_BackgroundError, HandleBgErrors):
+ * generic/tclInt.h (Interp, ERROR_CODE_SET):
+ * generic/tclNamesp.c (Tcl_CreateNamespace, Tcl_DeleteNamespace)
+ (TclTeardownNamespace):
+ * generic/tclResult.c (Tcl_ResetResult, Tcl_SetObjErrorCode)
+ (TclTransferResult):
+ * generic/tclTrace.c (CallVarTraces):
+ Reworked management of the "errorCode" data of an interp. That
+ information is now primarily stored in a new private (Tcl_Obj *) field
+ of the Interp struct, rather than using a global variable ::errorCode
+ as the primary storage. The ERROR_CODE_SET flag bit value is no longer
+ required to manage the value in its new location, and is removed.
+ Variable traces are established to support compatibility for any code
+ expecting the ::errorCode variable to hold the information.
+
+ ***POTENTIAL INCOMPATIBILITY***
+ Code that sets traces on the ::errorCode variable may notice a
+ difference in timing of the firing of those traces.
+
+ * generic/tclNamesp.c (Tcl_PopCallFrame): Removed Bug 1038021
+ workaround. That bug is now fixed.
+
+2004-10-04 Kevin B. Kenny <kennykb@acm.org>
+
+ * tests/clock.test (clock-34.*): Removed an antibug that forced
+ comparison of [clock scan] results with the :localtime time zone. Now
+ that [clock scan] uses the current time zone instead, the antibug
+ caused several tests to fail. [Bug 1038554]
+
+2004-10-04 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclParseExpr.c (GetLexeme): Ensure that the 'eq' and 'ne'
+ operators are followed by non-alphabetic characters so lexemes can't
+ run together. [Bug 884830]
+
+ * doc/DictObj.3, doc/dict.n: Clarified that a dictionary is not
+ order-preserving. [Bug 1032243] Also added another example to show off
+ more ways of using a dictionary and a few other formatting
+ improvements.
+
+2004-10-02 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclDictObj.c (TraceDictPath, Tcl_DictObjPutKeyList): Add
+ support for automatic creation of dictionary paths since that is what
+ everyone seems to actually expect of the API! [Bug 1037235]
+ (Tcl_DictObjNext): Make calling this after Tcl_DictObjDone non-fatal
+ as that simplifies a number of internal APIs. This doesn't break any
+ existing working code as it is a case which previously caused a panic.
+
+2004-10-02 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/namespace.test (namespace-8.7): Another test for save/restore
+ of ::errorInfo and ::errorCode during global namespace teardown.
+
+2004-10-01 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclProc.c (TclObjGetFrame, Tcl_UplevelObjCmd):
+ * generic/tclVar.c (Tcl_UpvarObjCmd): Cache stackframe level
+ references in the level object for speed.
+
+2004-09-30 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c (Tcl_CreateInterp):
+ * generic/tclInt.h (Interp): Removed the flag bit value
+ EXPR_INITIALIZED. It was set during interp creation and never tested.
+ Whatever purpose it had is in the past.
+
+ * generic/tclBasic.c (Tcl_EvalObjEx): Removed the flag bit value
+ * generic/tclInt.h (Interp): USE_EVAL_DIRECT. It was used
+ * generic/tcLTest.c (TestevalexObjCmd): only in the testing command
+ * tests/parser.test (parse-9.2): [testevalex] and nothing in
+ the test suite made use of the capability it enabled.
+
+ * generic/tclBasic.c (Tcl_AddObjErrorInfo): More re-organization
+ * generic/tclCmdAH.c (Tcl_ErrorObjCmd): of the management of
+ * generic/tclCmdMZ.c (TclProcessReturn): the errorCode value.
+ * tests/error.test (error-6.4-9):
+
+ * generic/tclNamespace.c (TclTeardownNamespace): Tcl_Obj-ified
+ * tests/namespace.test (namespace-8.5,6): the save/restore of
+ ::errorInfo and ::errorCode during global namespace teardown. Revised
+ the comment to clarify why this is done, and added tests that will
+ fail if this is not done.
+
+ * generic/tclResult.c (TclTransferResult): Added safety checks so that
+ unexpected undefined ::errorInfo or ::errorCode will not lead to a
+ segfault.
+
+ * generic/tclTrace.c (TclCallVarTraces): Save/restore the flag values
+ * tests/var.test (var-16.1): that define part of the
+ interpreter state during variable traces. [Bug 1038021].
+
+2004-09-30 Miguel Sofer <msofer@users.sf.net>
+
+ * tests/subst.test (12.1-2): added tests for [Bug 1036649]
+
+2004-09-29 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/basic.test (49.*): New tests for TCL_EVAL_GLOBAL.
+
+2004-09-29 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclVar.c (TclObjLookupVar, TclObjLookupVar):
+ (TclObjUnsetVar2, SetArraySearchObj):
+ * generic/tclUtil.c (SetEndOffsetFromAny):
+ * generic/tclStringObj.c (Tcl_SetStringObj):
+ (Tcl_SetUnicodeObj, SetStringFromAny):
+ * generic/tclResult.c (ResetObjResult):
+ * generic/tclRegexp.c (Tcl_GetRegExpFromObj):
+ * generic/tclPathObj.c (TclFSMakePathRelative, SetFsPathFromAny):
+ (TclFSMakePathFromNormalized, Tcl_FSNewNativePath):
+ * generic/tclObj.c (TclFreeObj, Tcl_SetBooleanObj, SetBooleanFromAny):
+ (Tcl_SetDoubleObj, SetDoubleFromAny, Tcl_SetIntObj):
+ (SetIntOrWideFromAny, Tcl_SetLongObj, SetWideIntFromAny):
+ (Tcl_SetWideIntObj, TclSetCmdNameObj, SetCmdNameFromAny):
+ * generic/tclNamesp.c (SetNsNameFromAny, MakeCachedEnsembleCommand):
+ * generic/tclListObj.c (Tcl_SetListObj, SetListFromAny):
+ * generic/tclIndexObj.c (Tcl_GetIndexFromObjStruct):
+ * generic/tclDictObj.c (SetDictFromAny):
+ * generic/tclCompile.c (TclInitByteCodeObj):
+ * generic/tclBinary.c (Tcl_SetByteArrayObj, SetByteArrayFromAny):
+ * generic/tclInt.h (TclFreeIntRep): Factorize out deletion of object
+ internal representation to a shared macro, so simplifying much code.
+
+2004-09-27 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclBasic.c (TclObjInvoke): fix for bogus gcc warning about
+ uninitialised variable.
+
+2004-09-27 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c: Removed internal routines TclInvoke,
+ * generic/tclInt.decls: TclGlobalInvoke, TclObjInvokeGlobal and the
+ * tests/basic.test: portion of TclObjInvoke that handles calls
+ without TCL_INVOKE_HIDDEN enabled. None of this code is called any
+ longer within the core, and the superior public interface,
+ Tcl_EvalObjv, is available for any external callers.
+
+ * generic/tclIntDecls.h: make genstubs
+ * generic/tclStubInit.c:
+
+ * generic/tclEvent.c (HandleBgErrors): Updated [bgerror] invocations
+ to make use of Tcl_Obj based routines, dropping the calls to
+ TclGlobalInvoke()
+
+2004-09-27 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclFileName.c:
+ * generic/tclFileSystem.h:
+ * generic/tclIOUtil.c:
+ * generic/tclPathObj.c:
+ * tests/cmdAH.test:
+ * tests/fileSystem.test:
+ * tests/winFCmd.test: fix to bad error message with 'cd' on windows,
+ when permissions are inadequate [Bug 1035462] and to treatment of a
+ volume-relative pwd on Windows [Bug 1018980].
+
+ * doc/FileSystem.3: added missing Tcl_GlobTypeData documentation [Bug
+ 935853]
+
+2004-09-27 Kevin Kenny <kennykb@acm.org>
+
+ * compat/strftime.c (Removed):
+ * generic/tclClock.c (removed TclClockOldscanObjCmd):
+ * generic/tclDate.c (Regenerated):
+ * generic/tclGetDate.y:
+ * generic/tclInt.decls (removed TclGetDate and TclpStrftime):
+ * generic/tclInt.h (removed TclGetDateInfo):
+ * generic/tclIntDecls.h (Regenerated):
+ * generic/tclStubInit.c (Regenerated):
+ * library/clock.tcl:
+ * unix/tclUnixTime.c (removed TclpStrftime):
+ * win/Makefile.in:
+ * win/makefile.bc:
+ * win/makefile.bc:
+ * win/tcl.dsp:
+ Continued refactoring of [clock] for TIP 173 changes. Broke the
+ free-form parser apart so that the Bison parser is responsible for
+ only parsing, while clock.tcl handles relative times like "next
+ Thursday", "next January". This change is needed to make timezones
+ other than :localtime and :Etc/UTC work with free-form scanning. This
+ change closes out the issue identified as being "for another day" in
+ my log message of 2004-09-08. The refactored code also eliminates the
+ last known references to TclpStrftime and TclGetDate, so those
+ routines (including compat/strftime.c) have been removed. The
+ refactoring also has the benefit that all storage in the Bison parser
+ is now on the C stack, eliminating any need for mutex protection
+ around [clock scan]. Also, changed the Makefiles so that 'make
+ gendate' is available on Windows as well as Unix.
+
+ * generic/tclCmdAH.c (Tcl_FormatObjCmd): Removed some grubby
+ * generic/tclObj.c (SetBooleanFromAny): work-around code that was
+ needed only because of Bug 868489.
+
+ * generic/tclBasic.c (TclObjInvoke): Removed three unused variables to
+ silence a compiler warning in VC++.
+
+2004-09-27 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * doc/FileSystem.3: fix to small typo.
+
+2004-09-26 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompCmds.c:
+ * generic/tclCompExpr.c:
+ * generic/tclCompile.c:
+ * generic/tclCompile.h:
+ * generic/tclInt.h:
+ * generic/tclProc.c:
+ * tests/compExpr-old.test:
+ * tests/compExpr.test:
+ * tests/expr.test:
+ * tests/for.test:
+ * tests/if.test:
+ * tests/incr.test:
+ * tests/while.test:
+ Report compilation errors at runtime, [Patch 1033689] by dgp.
+
+2004-09-23 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/dltest/Makefile.in (clean): Fixup make clean rule so that it
+ does not delete all files when SHLIB_SUFFIX is set to the empty string
+ in a static build. [Bug 1016726]
+
+2004-09-23 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c: Corrections to the 2004-09-21 commit
+ * generic/tclExecute.c: regarding ERR_ALREADY_LOGGED. That commit
+ * generic/tclNamesp.c: caused Tk test send-10.7 to fail. Added
+ * tests/namespace.test (25.7,8): tests in the Tcl test suite
+ * tests/pkg.test (2.25,26): to catch this error without the aid
+ of Tk in the future.
+
+ * generic/tclCmdAH.c (Tcl_ExprObjCmd): Simplified the TclObjCmdProc
+ of [expr] with a call to Tcl_ConcatObj.
+
+2004-09-22 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCmdMZ.c (TclProcessReturn): Support the -errorline
+ * generic/tclCompile.c (TclCompileScript): option to [return].
+ * tests/compile.test (16.23.*): Use that capability to defer reporting
+ * tests/misc.test (1.2): of parse errors until runtime. Updated
+ tests to reflect change. [Bug 1032805]
+
+2004-09-22 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c (INST_START_CMD):
+ * tests/proc.test (7.2-3): fix for [Bug 729692] was incorrect whenever
+ a loop exception was returned.
+
+2004-09-22 Kevin B. Kenny <kennykb@acm.org>
+
+ * library/tzdata/America/Montevideo: Updated to reflect
+ ftp://elsie.nci.nih.gov/pub/tzdata2004d.tar.gz. (Changes to
+ Asia/Jerusalem were in the comments only.) [Routine maintenance - no
+ bug] Spanish-language description of the change at
+ http://www.presidencia.gub.uy/decretos/2004091502.htm
+
+2004-09-21 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCompCmds.c: Tolerate [append] syntax errors
+ * tests/appendComp.test (8.1): at compile time, and allow runtime to
+ raise the error (or succeed if a redefined [append] allows).
+
+ * generic/tclBasic.c: Reworked management of the interp flag
+ * generic/tclCompile.c: ERR_ALREADY_LOGGED, to reduce its exposure.
+ * generic/tclExecute.c: Still left several referebces that are just
+ * generic/tclNamesp.c: too nice on performace to do away with. These
+ changes also resolve an inconsistency in the ::errorInfo values
+ produced by [namespace eval x error foo bar] and [namespace eval x
+ {error foo bar}].
+
+ * generic/tclExecute.c (TclCompEvalObj): Simplified the
+ TclCompEvalObj routine. Much housekeeping now reliably happens
+ elsewhere. [Patch 1031949]
+
+2004-09-21 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/interp.n: Tighten up wording on how [interp eval] and [interp
+ invokehidden] operate w.r.t. stack frames. [Bug 926590]
+
+2004-09-20 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/error.test (error-6.2,3): Added more tests to verify
+ ::errorCode setting by/after a [catch].
+
+2004-09-19 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCmdAH.c: removed outdated comment [Bug 1029518].
+
+2004-09-18 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclAppInit.c: Dde package can load into a safe interp. Claim
+ this fact for the Tcl_StaticPackage() call when the shell is built
+ with the TCL_USE_STATIC_PACKAGES option.
+
+2004-09-18 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclExecute.c (TEBC-INST_LSHIFT,INST_RSHIFT): Ensure that
+ large shifts end up shifting correctly. [Bug 868467]
+
+ * doc/FileSystem.3, doc/OpenFileChnl.3: More documentation fixes from
+ Mikhail Kolesnitchenko. [Patch 1022527]
+ * doc/*: Standardize highlighting of symbols defined in tcl.h
+
+2004-09-17 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c (Tcl_AddObjErrorInfo, Tcl_LogCommandInfo):
+ * generic/tclCmdAH.c ([catch], [error]):
+ * generic/tclCmdMZ.c ([return]):
+ * generic/tclProc.c (TclUpdateReturnInfo):
+ * generic/tclResult.c (Tcl_SetErrorCodeVA, Tcl_SetObjErrorCode)
+ (TclTransferResult): Refactored so that all errorCode setting flows
+ through Tcl_SetObjErrorCode(). This greatly reduces the number of
+ different places in the code that need to know details about an
+ internal bitflag field of the Interp struct. Also places errorCode
+ setting in one place for easier future mods.
+
+2004-09-17 Kevin B.Kenny <kennykb@acm.org>
+
+ * generic/tclDate.c: Revised tclGetDate.y to use bison instead of
+ * generic/tclGetDate.y: yacc to build the parser, eliminating all the
+ * generic/tclInt.h: complicated hackery involving 'sed'
+ * unix/Makefile.in: postprocessing. Rebuilt the parser.
+
+2004-09-14 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclClock.c (ClockOldscanObjCmd): Silenced a compiler warning
+ (long passed as a param where unsigend long was expected). 'Unsigned
+ long' is wrong, but the fix is really to change the signature of
+ TclGetDate to return a structure of its 'yy' variables and then do the
+ remaining work inside clock.tcl. But, as I said on 2004-09-08, that's
+ a job for another day. [Bug 1027993]
+
+2004-09-10 Miguel Sofer <msofer@users.sf.net>
+
+ * doc/interp.n:
+ * generic/tclInterp.c (TclPreventAliasLoop, AliasCreate):
+ * tests/interp.test (17.4-6, 19.3-4): fixing problems with renaming of
+ aliases [Bugs 707104 1026493]. Fix designed by dgp.
+
+2004-09-13 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclNamesp.c (NsEnsembleImplementationCmd): Add token field
+ to internal rep of EnsembleCmdRep structure so that we can check it to
+ see if the subcommand object is really being used with the same
+ ensemble. [Bug 1026903]
+
+2004-09-11 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclClock.c (TclMktimeObjCmd): Corrected a bad check for
+ error return from 'mktime'.
+ * generic/tclObj.c (Tcl_GetIntFromObj): Corrected a problem where
+ demoting a wide to an int failed on a big-endian machine. [Bug
+ 1026125].
+ * tests/clock.test (clock-43.1): Added regression test for error
+ return from 'mktime'.
+
+2004-09-11 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c (INST_CONCAT1): fix for [Bug 1025834]; avoid
+ unnecessary string copies.
+
+2004-09-10 David Gravereaux <davyrgvy@pobox.com>
+
+ * tests/tcltest.test: tcltest-12.3-4 needed to have
+ ::tcltest::loadScript set to empty in their -setup
+
+2004-09-10 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclObj.c (SetIntOrWideFromAny): Rewritten integral value
+ parsing code so that values do not flip so easily between numeric
+ representations. Thanks to KBK for this! [Bug 868489]
+
+ * generic/tclIO.c (Tcl_Seek): Make sure wide seeks do not fail to set
+ ::errorCode on error. [Bug 1025359]
+
+2004-09-10 Andreas Kupries <andreask@activestate.com>
+
+ * generic/tcl.h: Micro formatting fixes.
+ * generic/tclIOGT.c: Channel version fixed, must be 3, to have
+ wideseekProc. Thanks to David Graveraux <davygrvy@pobox.com>.
+
+2004-09-11 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclNamespace.c (TclGetNamespaceForQualName): Resolved
+ longstanding inconsistency in the treatment of the TCL_NAMESPACE_ONLY
+ flag revealed by testing the 2004-09-09 commits against Itcl.
+ TCL_NAMESPACE_ONLY now acts as specified in the pre-function comment,
+ forcing resolution in the passed in context namespace. It has been
+ incorrectly forcing resolution in the interp's current namespace.
+
+2004-09-10 Kevin Kenny <kennykb@acm.org>
+
+ * library/clock.tcl: Fixed a bug where %z always put a plus sign on
+ the time zone in :localtime.
+ * tests/clock.test: Added test case for the above bug.
+
+2004-09-10 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c (INST_CONCAT1): added a peephole optimisation
+ for concatting an empty string. This enables replacing the idiom 'K $x
+ [set x {}]' by '$x[set x {}]' for fastest execution.
+
+2004-09-09 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinConsole.c: Calls to WriteFile and WriteConsoleA changed to
+ WriteConsole for simplicity.
+
+2004-09-09 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclNamesp.c (Tcl_ForgetImport): Corrected faulty
+
+ * tests/namespace.test: logic that relied exclusively on string
+ matching and failed in the presence of [rename]s. [Bug 560297] Also
+ corrected faulty prevention of [namespace import] cycles. [Bug 1017299]
+
+2004-09-08 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c (Tcl_CreateInterp): Removed obsolete field
+ for storing the string-based command procedure of built-in commands.
+ We no longer have any string-based built-in commands!
+
+2004-09-08 Kevin B. Kenny <kennykb@acm.org>
+
+ * compat/strftime.c (_conv): Corrected a problem where hour 0 would
+ format as a blank format group with %k.
+ * doc/clock.n: Corrected a buglet in the header information. [Bug
+ 1024058]
+ * generic/tclClock.c (TclClockMktimeObjCmd): Fixed a bug where the
+ month was scanned incorrectly in -timezone :localtime.
+ * tests/clock.test (clock-34.*,clock-40.1, clock-41.1): Adjusted the
+ clock-34.* test cases so that the consistency check is performed in
+ :localtime rather than the current time zone. This change allows
+ dealing with issues where the C library has a different idea of DST
+ conversion than Tcl. (Real fix would be to break TclGetDate into
+ separate parser and time converter, and do the time conversion in
+ clock.tcl. That's for another day.) Added regression test case for the
+ bug where month was scanned incorrectly in -timezone :localtime. [Bug
+ 1023779] Added regression test case for %k at the zero hour.
+
+2004-09-07 David Gravereaux <davygrvy@pobox.com>
+
+ * win/makefile.vc: some quoting needed to be removed as it was
+ breaking with VC7. [Bug 1023150]
+
+2004-09-07 Kevin B. Kenny <kennykb@acm.org>
+
+ * doc/clock.n: Documented the default -format, and changed references
+ to a (nonexistent) msgcat command to refer to the msgcat package. [Bug
+ 1023870]
+ * generic/tclTimer.c: Removed a premature optimisation that attempted
+ to store the assoc data in the client data; the optimisation caused a
+ bug that [after] would overwrite its imports. [Bug 1016167]
+ * library/clock.tcl (InitTZData, ClearCaches): Changed so that the
+ in-memory time zone :UTC (and its aliases) always gets reinitialised,
+ in case tzdata is absent. [Bug 1019537, 1023779]
+ * library/tzdata/*: Regenerated.
+ * tests/clock.test (clock-31.*, clock-39.1): Corrected a problem where
+ the 'system' locale tests fail on a non-English Windows machine. [Bug
+ 1023761]. Added a test to make sure that alias time zones load
+ correctly. [Bug 1023779].
+ * tests/timer.test (timer-1.1, timer-2.1): Changed to (one hopes!) be
+ more resilient on an overloaded system, if [after 200] sleeps for 300
+ ms or longer.
+ * tools/tclZIC.tcl (writeLinks): Corrected a problem where alias time
+ zone names were written incorrectly, causing them to fail to load at
+ run time. [Bug 1023779].
+ * win/tclWinTime.c (Tcl_GetTime): Eliminated CPUID tests on Win64 -
+ assuming that HAL vendors now do a better job of keeping the
+ performance counters synchronized among CPU's. [Bug 1020445]
+
+2004-09-06 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/tclvars.n, doc/tcltest.n, doc/tclsh.1, doc/safe.n, doc/expr.n
+ * doc/WrongNumArgs.3, doc/Utf.3, doc/TraceVar.3, doc/Thread.3
+ * doc/TCL_MEM_DEBUG.3, doc/SubstObj.3, doc/StdChannels.3
+ * doc/SetResult.3, doc/RegExp.3, doc/RegConfig.3, doc/RecEvalObj.3
+ * doc/PrintDbl.3, doc/ParseCmd.3, doc/Panic.3, doc/ObjectType.3
+ * doc/Object.3, doc/Namespace.3, doc/Interp.3, doc/IntObj.3
+ * doc/Hash.3, doc/GetOpnFl.3, doc/GetIndex.3, doc/Eval.3
+ * doc/Encoding.3, doc/DoubleObj.3, doc/DictObj.3, doc/CrtTimerHdlr.3
+ * doc/CrtObjCmd.3, doc/CrtMathFnc.3, doc/CrtCommand.3, doc/CrtChannel.3
+ * doc/ChnlStack.3, doc/ByteArrObj.3, doc/AssocData.3, doc/Alloc.3:
+ More documentation fixes from Mikhail Kolesnitchenko. [Patch 1022527]
+
+2004-09-03 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * unix/tclUnixFCmd.c: Stop NULL interp arguments from triggering a
+ crash when an error happens. [Bug 1020538]
+
+2004-09-02 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/lsearch.n: Clarified meaning of -dictionary. [Bug 759545]
+
+2004-09-02 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * win/makefile.vc: clock.tcl needs to be installed.
+
+2004-09-01 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/tclWinReg.c (BroadcastValue): WIN64 cast corrections
+
+ * win/tclWinDde.c (DdeClientWindowProc):
+ (DdeServicesOnAck, DdeEnumWindowsCallback): WIN64 corrections
+
+ * win/tclWin32Dll.c (TclWinCPUID): need _asm for WIN64 (Itanium),
+ until we have it, just return unknown. [Bug 1020445]
+
+2004-09-01 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/regsub.n, doc/RegConfig.3, doc/Environment.3:
+ * doc/CrtChannel.3, doc/safe.n: Use correct abbreviations.
+
+2004-08-31 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/trace.n, doc/socket.n, doc/registry.n, doc/pid.n:
+ * doc/namespace.n, doc/msgcat.n, doc/lsort.n, doc/lsearch.n:
+ * doc/linsert.n, doc/info.n, doc/http.n, doc/history.n:
+ * doc/format.n, doc/file.n, doc/exec.n, doc/dde.n, doc/clock.n:
+ * doc/catch.n, doc/binary.n: More spelling and grammar fixes from
+ Mikhail Kolesnitchenko. [Patch 1018486]
+
+2004-08-31 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * doc/FileSystem.3:
+ * generic/tclIOUtil.c: Clarified documentation regarding ability of a
+ filesystem to say that it doesn't support a given operation using the
+ EXDEV posix error code (copyFileProc, renameFileProc, etc), and
+ updated one piece of code to ensure correct behaviour when an
+ operation is not supported [Bug 1017072]
+
+ * tests/fCmd.test: fix to test suite problem [Bug 1002884]
+
+2004-08-31 Daniel Steffen <das@users.sourceforge.net>
+
+ * unix/Makefile.in (install-libraries): portable sh fix.
+
+2004-08-30 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd): Stop [string map] from
+ crashing when its map and input string are the same object.
+
+2004-08-27 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclNamesp.c (FindEnsemble): Factor out the code to convert a
+ command name into an ensemble configuration and add support for
+ ignoring [namespace import] link chains. [Bug 1017022]
+ (NamespaceWhichCmd): Rework to use newer option parsing API.
+
+2004-08-27 Daniel Steffen <das@users.sourceforge.net>
+
+ * unix/Makefile.in: added customization of default module path roots
+ via TCL_MODULE_PATH makefile variable.
+ * macosx/Makefile: add platform standard locations to default module
+ path roots. [Patch 942881]
+
+ * tests/env.test: macosx fixes.
+
+2004-08-25 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/timer.test (timer-10.1): Test for Bug 1016167.
+ * generic/tclTimer.c: Workaround for situation when a [namespace
+ import] causes the objv[0] value to be something other than what
+ Tcl_AfterObjCmd expects. [Bug 1016167].
+
+2004-08-25 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclNamesp.c (NsEnsembleImplementationCmd): Use the ensemble
+ command token to get the name of the ensemble for passing to the
+ -unknown handler instead of relying on objv[0], which may contain
+ useless info in the presence of [namespace import]. Problem found by
+ Don Porter when investigating [Bug 1016167].
+
+2004-08-24 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclProc.c: The routine TclProcInterpProc was a
+ * generic/tclTestProcBodyObj.c: specific instance of the general
+ service already provided by TclObjInvokeProc. Removed
+ TclProcInterpProc and TclGetInterpProc from the code...
+
+ * generic/tclInt.decls: ...and from the internal stubs table.
+ * generic/tclIntDecls.h
+ * generic/tclStubInit.c
+
+2004-08-24 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/string.n: Added clarifying note.
+
+2004-08-23 Don Porter <dgp@users.sourceforge.net>
+
+ * library/auto.tcl: Updated [tcl_findLibrary] search path to
+ include any [<pkg>::pkgconfig get scriptdir,runtime] directory, as
+ well as the $::auto_path. [RFE 695441]
+
+2004-08-21 Kevin B. Kenny <kennykb@acm.org>
+
+ * tests/clock.test (clock-38.1): Changed TZ setting to specify CET in
+ excruciating detail to deal with systems that lack the Posix defaults
+ for DST changes (and to be formally correct with the change dates for
+ CET).
+
+2004-08-19 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclScan.c (Tcl_ScanObjCmd, ValidateFormat): Ensure that the
+ %ld conversion works correctly on 64-bit platforms. [Bug 1011860]
+
+2004-08-19 Kevin Kenny <kennykb@acm.org>
+
+ * library/clock.tcl (format): Changed default timezone format from
+ alphabetic to numeric to produce scannable times in more locales.
+ * tests/clock.test (clock-37.1): Removed now-unused 'needPST'
+ constraint and the comments that refer to it.
+
+2004-08-18 Andreas Kupries <andreask@activestate.com>
+
+ * library/init.tcl: Integrated TIP #189. We source a separate file
+ (see below), instead of inlining the contents of that file. This
+ should beeasier to maintain, and easier to backport/install in 8.4
+ installations.
+
+ Note: Usage of Tcl Modules is restricted to non-safe interps. It
+ cannot be loaded into a safe interp.
+
+ * library/tm.tcl: New file, the v2 reference implementation for TIP
+ #189, Tcl Modules.
+
+ * doc/tm.n: New file, documentation for Tcl Modules, based on the TIP.
+
+ * unix/mkLinks: Regenerated.
+ * win/makefile.vc: Added tm.tcl to list of files to install.
+
+2004-08-18 Kevin Kenny <kennykb@acm.org>
+
+ * tests/httpd (httpdRespond): Corrected an abuse of the [clock]
+ command that caused test failures for some values of [clock clicks].
+
+ * doc/clock.n
+ * generic/tclBasic.c (Tcl_CreateInterp, Tcl_HideUnsafeCommands):
+ * generic/tclClock.c (all):
+ * generic/tclInt.h:
+ * generic/tclInterp.c (CreateSlave):
+ * library/clock.tcl: (new file)
+ * library/init.tcl (clock):
+ * library/msgs/*.msg:(new files)
+ * library/tzdata/*:
+ * library/tzdata/*/*:
+ * library/tzdata/*/*/*: (new files)
+ * tools/installData.tcl: (new file)
+ * tools/loadICU.tcl: (new file)
+ * tools/makeTestCases.tcl: (new file)
+ * tools/tclZIC.tcl: (new file)
+ * unix/Makefile.in:
+ * unix/configure: (regenerated)
+ * unix/tcl.m4:
+ * tests/clock.test (all):
+ * win/Makefile.in:
+ * win/Makefile.vc:
+ Implementation of TIPs #173 and #209.
+
+ The [clock] command is now a Tcl ensemble, with most of its
+ functionality written in Tcl and callouts to C code only to access
+ low-level functions such as localtime, mktime and tzset.
+
+ In addition to the functionality changes called out in the two TIPs,
+ it is worth noting that the [clock] command in a safe slave
+ interpreter is now an alias to the [clock] command in the master, and
+ that [clock] is otherwise not expected to function entirely correctly
+ in safe interps. C code that simply does Tcl_MakeSafe needs to be
+ aware that [clock] may need special handling. (It appears unlikely
+ that such code actually exists.)
+
+ One incompatibility of note is that if the time zone cannot be
+ determined from the TZ, TCL_TZ environment variables, or from the
+ Windows control panel, so that the C library must be used for date and
+ time conversions, then times outside the range of time_t will fail;
+ they used to return bad data silently.
+
+ Many thanks to all the many people who assisted with testing,
+ debugging, criticism of the specification, and localisation. Deserving
+ of particular mention are Joe English, Clif Flynt, Donal K. Fellows,
+ Jeff Hobbs, Cameron Laird, Arjen Markus, Reinhard Max, Christopher
+ Nelson, Steve Offutt, Donald G. Porter, Pascal Scheffers, Peter da
+ Silva and Richard Suchenwirth-Bauersachs.
+
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2004-08-16 Miguel Sofer <msofer@users.sf.net>
+
+ * doc/SetVar.3:
+ * generic/tclTest.c (TestseterrorcodeCmd):
+ * generic/tclVar.c (TclPtrSetVar):
+ * tests/result.test (result-4.*, result-5.*): [Bug 1008314] detected
+ and fixed by dgp.
+
+2004-08-13 Don Porter <dgp@users.sourceforge.net>
+
+ * library/msgcat/msgcat.tcl: Added checks to prevent [mclocale]
+ * tests/msgcat.test: from registering filesystem paths to possibly
+ malicious code to be evaluated by a later [mcload].
+
+2004-08-10 Zoran Vasiljevic <vasiljevic@users.sf.net>
+
+ * unix/tclUnixThrd.c (TclpThreadCreate): changed handling of the
+ returned thread ID since broken on 64-bit systems (Cray). Thanks to
+ Rob Ratcliff for reporting the bug.
+
+2004-08-03 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclNamesp.c (MakeCachedEnsembleCommand): Initialize the
+ epoch field cached in the subcommand. [Bug 989298]
+ (NsEnsembleImplementationCmd): Plug a leak (thanks to Miguel Sofer for
+ spotting it with valgrind) and reduce the number of goto labels to
+ make the code clearer.
+
+2004-08-02 Don Porter <dgp@users.sourceforge.net>
+
+ * library/package.tcl (pkg_mkIndex): Updated [pkg_mkIndex] to make
+ use of [glob -directory $dir -tails] and return options.
+
+ TIP#207 IMPLEMENTATION
+
+ * doc/interp.n: Added support for a -namespace option to the
+ * generic/tclBasic.c: [interp invokehidden] command. Also added an
+ * generic/tclInt.h: internal routine TclObjInvokeNamespace() and
+ * generic/tclInterp.c: corrected the flag names TCL_FIND_ONLY_NS and
+ * generic/tclNamesp.c: TCL_CREATE_NS_IF_UNKNOWN that are passed to the
+ * generic/tclTrace.c: internal routine TclGetNamespaceForQualName().
+ * tests/interp.test: [Patch 981841]
+
+ * generic/tclLiteral.c (TclCleanupLiteralTable): Corrected
+ * tests/compile.test (compile-12.4): flawed deletion of literal
+ internal reps that could lead to accessing of freed memory. Thanks to
+ Kevin Kenny for test case and fix [Bug 1001997].
+
+2004-07-30 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/safe.test (safe-2.1): Disabled senseless test. [Bug 999612]
+
+ * library/auto.tcl (auto_reset): Removed "protected" list of commands
+ from [auto_reset]. All entries in the auto_index can be re-loaded.
+ * library/package.tcl: Updated comment to reflect 2004-07-28 commit.
+
+ * generic/tclEvent.c (Tcl_Finalize): Re-organized Tcl_Finalize so
+ that Tcl_ExitProc's that call Tcl_Finalize recursively do not cause
+ deadlock. [Patch 999084 fixes Tk Bug 714956]
+
+2004-07-30 Daniel Steffen <das@users.sourceforge.net>
+
+ * unix/configure:
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): Darwin: instead of setting PLAT_OBJS
+ to explict object files in tcl.m4, refer to MAC_OSX_OBJS makefile var.
+ * unix/Makefile.in: added MAC_OSX_OBJS variable.
+
+2004-07-29 Don Porter <dgp@users.sourceforge.net>
+
+ * library/package.tcl: [::pkg::create] is now an alias. Test safe-2.1
+ will now fail until Bug 999612 is corrected.
+
+2004-07-28 Don Porter <dgp@users.sourceforge.net>
+
+ * library/package.tcl: Moved private command
+ * library/tclIndex: [pkg_compareExtension] into ::tcl::Pkg.
+ * tests/pkg_mkIndex.test: Also moved implementation of
+ [::pkg::create] to [::tcl::Pkg::Create].
+
+2004-07-25 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ * tests/io.test: Make io-61.1 create file as binary to pass on Win32
+
+2004-07-23 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclVar.c: simplify tclLocalVarNameType, removing the
+ reference to the corresponding proc. The reference is now seen as
+ unnecessary, and it may cause leaking circular references under some
+ circumstances (see for example [Bug 994838]).
+
+2004-07-22 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/eofchar.data (removed): Test io-61.1 now generates its own
+ * tests/io.test: file of test data as needed.
+
+2004-07-20 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclEvent.c: Correct threaded obj allocator to
+ * generic/tclInt.h: fully cleanup on exit and allow for
+ * generic/tclThreadAlloc.c: reinitialization. [Bug 736426]
+ * unix/tclUnixThrd.c: (mistachkin, kenny)
+ * win/tclWinThrd.c:
+
+2004-07-21 Kevin Kenny <kennykb@acm.org>
+
+ * generic/tclBasic.c (DeleteInterpProc):
+ * generic/tclLiteral.c (TclCleanupLiteralTable):
+ * generic/tclInt.h: added a TclCleanupLiteralTable function, called
+ from DeleteInterpProc, that frees internal representations of shared
+ literals early when an interpreter is being deleted. This change
+ corrects a number of memory mismanagement issues in the cases where
+ the internal representation of one literal contains a reference to
+ another, and avoids conditions such as resolved variable names
+ referring to procedure and namespace contexts that no longer exist.
+ [Bug 994838]
+
+2004-07-20 Daniel Steffen <das@users.sourceforge.net>
+
+ * unix/Makefile.in:
+ * win/Makefile.in: added 'install-private-headers' makefile target to
+ allow optionally installing private tcl headers. [FR 922727]
+
+ * macosx/Makefile: use new 'install-private-headers' target to install
+ private headers into framework. [FR 922727]
+
+ * unix/tclUnixFile.c (NativeMatchType): added support for readonly
+ matching of user immutable files (where available).
+
+ * macosx/tclMacOSXBundle.c: dynamically acquire address for
+ CFBundleOpenBundleResourceMap symbol, since it is only present in full
+ CoreFoundation on Mac OS X and not in CFLite on pure Darwin.
+
+2004-07-19 Zoran Vasiljevic <vasiljevic@users.sf.net>
+
+ * win/tclwinThrd.c: redefined MASTER_LOCK to call TclpMasterLock.
+ Fixes [Bug 987967]
+
+2004-07-17 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclIOUtil.c: fix to rare 'cd' infinite loop in normalization
+ with vfs [Bug 991420].
+ * tests/fileSystem.test: added test for above bug.
+
+ * doc/FileSystem.3: clarified documentation of posix error codes in
+ 'remove directory' FS proc - 'EEXIST' is used to signify a non-empty
+ directory error (bug reported against tclvfs).
+
+2004-07-16 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/Makefile.in, unix/tcl.m4: move (C|LD)FLAGS after their
+ * unix/configure.in, unix/configure: _DEFAULT to allow for env setting
+ to override m4 switches. Move SC_MISSING_POSIX_HEADERS up and
+ consolidate calls to limit redundancy in configure.
+ (CFLAGS_WARNING): Remove -Wconversion
+ (SC_ENABLE_THREADS): Set m4 to force threaded build when built against
+ a threaded Tcl core.
+
+2004-07-16 Andreas Kupries <andreask@activestate.com>
+
+ * generic/tclIOCmd.c (Tcl_FcopyObjCmd): Corrected a typo in the
+ generation of error messages and simplified by reusing data in a
+ variable instead of retrieving the string again. Fixes [Bug 835289].
+
+ * doc/OpenFileChnl.3: Added description of the behaviour of
+ Tcl_ReadChars when its 'charsToRead' argument is set to -1. Fixes [Bug
+ 934511].
+
+ * doc/CrtCommand.3: Added note that the arguments given to the command
+ proc of a Tcl_CreateCommand are in utf8 since Tcl 8.1. Closing [Patch
+ 414778].
+
+ * doc/ChnlStack.3: Removed the declaration that the interp argument to
+ Tcl_(un)StackChannel can be NULL. This fixes [Bug 881220], reported by
+ Marco Maggi <marcomaggi@users.sourceforge.net>.
+
+ * tests/socket.test: Accepted two new testcases by Stuart Casoff
+ <stwo@users.sourceforge.net> checking that -server and -async don't go
+ together [Bug 796534].
+
+ * unix/tclUnixNotfy.c (NotifierThreadProc): Accepted Joe Mistachkin's
+ patch for [Bug 990500], properly closing the notifier thread when its
+ exits.
+
+2004-07-15 Andreas Kupries <andreask@activestate.com>
+
+ * unix/tclUnixThrd.c (TclpFinalizeMutex): Accepted Joe Mistachkin's
+ patch for [Bug 990453], closing leakage of mutexes. They were not
+ destroyed properly upon finalization.
+
+2004-07-15 Andreas Kupries <andreask@activestate.com>
+
+ * generic/tclIO.h (CHANNEL_INCLOSE): New flag. Set in
+ * generic/tclIO.c (Tcl_UnregisterChannel): 'Tcl_Close' while the
+ * generic/tclIO.c (Tcl_Close): close callbacks are
+ run. Checked in 'Tcl_Close' and 'Tcl_Unregister' to prevent recursive
+ call of 'close' in the close-callbacks. This is a possible error made
+ by implementors of virtual filesystems based on 'tclvfs', thinking
+ that they have to close the channel in the close handler for the
+ filesystem.
+
+2004-07-14 Andreas Kupries <andreask@activestate.com>
+
+ * generic/tclIO.c:
+ * generic/tclIO.h:
+ * Not reverting, but #ifdef'ing the changes from May 19, 2004 out of
+ the core. This removes the ***POTENTIAL INCOMPATIBILITY*** for channel
+ drivers it introduced. This has become possible due to Expect gaining
+ a BlockModeProc and now handling blockingg and non-blocking modes
+ correctly. Thus [SF Tcl Bug 943274] is still fixed if a recent enough
+ version of Expect is used.
+
+ * doc/CrtChannel.3: Added warning about usage of a channel without a
+ BlockModeProc.
+
+2004-07-15 Andreas Kupries <andreask@pliers.activestate.com>
+
+ * generic/tclIOCmd.c (Tcl_PutsObjCmd): Added length check to the old
+ depreceated newline syntax, to ensure that only "nonewline" is
+ accepted. [Tcl SF Bug 985869], reported by Joe Mistachkin
+ <mistachkin@users.sourceforge.net>.
+
+2004-07-15 Zoran Vasiljevic <vasiljevic@users.sf.net>
+
+ * generic/tclEvent.c (Tcl_Finalize): stuffed memory leak incurred by
+ re-initializing of TSD slots after the last call to
+ TclFinalizeThreadData (done from within Tcl_FinalizeThread()). We
+ basically just repeat the TclFinalizeThreadData() once more before
+ tearing down TSD keys in TclFinalizeSynchronization(). There should be
+ more elaborate mechanism in place for handling such issues, based on
+ thread cleanup handlers registered on the OS level. Such change
+ requires much more work and would also require TIP because some
+ visible parts of Tcl API would have to be modified. In the meantime,
+ this will do.
+
+ * generic/tclNotify.c (TclFinalizeNotifier): Added conditional
+ notifier finalization based on the fact that an TclInitNotifier has
+ been called for the current thread. This fixes the [Bug 770053] again.
+ Hopefully this time w/o unwanted side-effects.
+
+2004-07-15 Kevin Kenny <kennykb@acm.org>
+
+ * generic/tclLiteral.c (TclReleaseLiteral): Removed unused variable
+ 'codePtr' to silence a message from VC++.
+
+2004-07-15 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompile.c (TclCompileScript):
+ * generic/tclLiteral.c (TclReleaseLiteral): fix for [Bug 467523],
+ which resurfaced with the latest changes. The previous strategy was to
+ have special code in TclReleaseLiteral to handle the self-references
+ generated by empty scripts. The new approach avoids the self-reference
+ altogether, by having empty scripts return an unshared literal.
+
+2004-07-15 Zoran Vasiljevic <vasiljevic@users.sf.net>
+
+ * generic/tclEvent.c (NewThreadProc): Backout of changes to fix the
+ [Bug 770053]. See SF bugreport for more info.
+
+2004-07-11 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclBasic.c (Tcl_EvalEx): leak fix by dgp, release
+ objv[objectsUsed] on error.
+
+2004-07-11 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclParse.c (Tcl_SubstObj): leak fix by dgp, release result
+ on error.
+
+2004-07-11 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclNamesp.c (BuildEnsembleConfig): Don't forget to clean out
+ references when deleting the hash table.
+ * generic/tclDictObj.c (Tcl_DictObjRemoveKeyList): Oops, forgot to
+ delete value object when removing the hash entry. [Bug 989093 in part]
+
+2004-07-11 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c (TEBC): fixed leak of expandNestList objs when
+ there is an error while an expansion is in progress (code added at
+ checkForCatch).
+
+2004-07-11 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclIOUtil.c: fix to 'cd' bug when vfs is active [tclvfs Bug
+ 986944] - this bug recently introduced by some threading fixes. Need
+ to work out how to add tests for this.
+
+2004-07-10 Kevin Kenny <kennykb@acm.org>
+
+ * tests/clock.test (clock-2.11): Changed the test so that it isn't an
+ infinite loop when run under valgrind on a slow virtual machine.
+ Thanks to Miguel Sofer for the bug report. Also put in code to restore
+ env(LC_TIME) after tests complete, silencing a warning from 'make
+ TESTFLAGS="-debug 1" test'.
+
+2004-07-08 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclBasic.c (DeleteInterpProc): reverted the modification of
+ 3 days ago, as the leak of [Bug 983660] is now handled by the change
+ in TclCleanupByteCode.
+ * generic/tclCompile.c (TclCleanupByteCode): let each bytecode remove
+ its references to literals at interp deletion, without updating the
+ dying literal table.
+ * generic/tclLiteral.c (TclDeleteLiteralTable): with the above change
+ to TclCleanupByteCode, this function now removes a single reference to
+ the literal object and cleans up its own structures.
+
+2004-07-08 Kevin Kenny <kennykb@acm.org>
+
+ * win/tclWinInit.c (AppendEnvironment): Silenced a compilation warning
+ about a type mismatch.
+
+2004-07-07 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompile.c (TclCompileScript): fix for [Bug 458361].
+ Single-word scripts are compiled with an unshared cmdName to avoid
+ shimmering between bytecode and cmdName reps.
+
+2004-07-07 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCmdMZ.c (TclMergeReturnOptions): Simplified logic and
+ removed potential memory leak. [Bug 986257].
+
+2004-07-07 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * tools/man2help2.tcl (setTabs, IPmacro): Added support for the more
+ advanced *roff macros used in Tk's doc/bind.n
+
+ * generic/tclObj.c (TclInitObjSubsystem): Declare all current object
+ types.
+
+2004-07-06 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/cmdMZ.test (cmdMZ-return-2.17): Added a test that a word
+ containing backslash-quoted value is treated correctly.
+
+ * generic/tclCompile.c (TclWordKnownAtCompileTime): [Bug 986196]
+ Corrected flaw above and the flaw that caused TCL_TOKEN_SIMPLE_WORDs
+ to have their original word value copied ( "{a b}" ) rather than the
+ actual value ( "a b" ). Thanks to Kevin Kenny for report and tests.
+
+2004-07-06 Kevin B. Kenny <kennykb@acm.org>
+
+ * tests/cmdMZ.test (cmdMZ-return-2.15,cmdMZ-return-2.16): Added a test
+ that a return code containing spaces is correctly returned.
+
+2004-07-06 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * tools/man2html2.tcl (IPmacro, setTabs): Added support for the more
+ advanced *roff macros used in Tk's doc/bind.n
+
+2004-07-05 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclBasic.c (DeleteInterpProc): fix for [Bug 983660], found
+ by pspjuth. Tear down the global namespace before freeing the interp
+ handle, to allow the bytecodes to free their non-shared literals.
+ * generic/tclLiteral.c (TclReleaseLiteral): moved special code for
+ self-ref so that it is also used for non-shared literals. Possible bug
+ found by inspection.
+
+2004-07-03 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c (ExprRoundFunc):
+ * tests/expr-old.test (39.1): added support for wide integers to
+ round(); [Bug 908375], reported by Hemang Lavana.
+
+2004-07-03 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompile.h:
+ * generic/tclInt.decls:
+ * generic/tclIntDecls.h:
+ * generic/tclStubInit.c: Moved declaration of TclCompEvalObj() from
+ tclCompile.h to the internal stubs table, for compiler
+ experimentation.
+
+2004-07-02 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/regcomp.c (stid): correct minor pointer size error
+
+ * generic/tclPipe.c (TclCreatePipeline): applied TIP #202 patch that
+ * doc/exec.n, tests/exec.test: adds 2>@1 as a special case
+ redirection of stderr to the result output.
+
+2004-07-02 Kevin B. Kenny <kennykb@acm.org>
+
+ * tests/io.test: Changed several tests to run the event loop rather
+ than just calling [update] periodically, avoiding intermittent
+ failures (usually in io-29.32) that stemmed from unreaped processes on
+ Windows.
+ * tests/winPipe.test (winpipe-1.11): Fixed a bug that caused test to
+ fail if the path name of the working directory contained whitespace
+ [Bug 678430]
+
+2004-07-01 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * tests/fileSystem.test: Added test for [Bug 970529]
+
+2004-07-01 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * win/README.binary, win/README: Updated references to Tcl and Tk 8.4
+ to point to 8.5 instead. Thanks to Theo Verelst for spotting this.
+ * generic/tcl.h: Added note to help prevent those changes from getting
+ missed in the future.
+
+ * doc/Namespace.3, doc/load.n, doc/Limit.3: Typo fixes and remove
+ duplicate documentation. [Bug 983146]
+
+2004-06-30 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/fileSystem.test: Minor correction to new fileSystem-9.X tests
+ so that they clean up temporary directories correctly.
+
+2004-06-30 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * doc/filename.n: clarified behaviour concerning trailing slashes in
+ filenames [Bug 971976]
+
+ * win/tclWinFile.c:
+ * tests/fileSystem.test: fix and tests for [Bug 979879]
+
+2004-06-30 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ TIP#188 IMPLEMENTATION
+
+ * doc/string.n, tests/string.test: Add 'wideinteger' to things
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd): that can be tested for with
+ the [string is] subcommand. [Patch 940915, by Kevin Kenny]
+
+2004-06-29 Don Porter <dgp@users.sourceforge.net>
+
+ * win/tclWinInit.c: Corrected reference counting flaw in recent
+ changes. Thanks to Pat Thoyts. [Bug 981893].
+
+2004-06-29 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * win/tclWin32Dll.c: fix to compilation with VC++ 5.2
+
+2004-06-29 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * library/safe.tcl: Make sure that the temporary variable is local to
+ the namespace and not inadvertently global. [Bug 981733]
+
+2004-06-24 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * tests/unixNotfy.test: Modified constraints so that testing with a
+ threaded tclsh (not tcltest) will not hang.
+
+2004-06-23 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclThreadStorage.c: Corrected type casting errors that led
+ to calculation of a negative index value, thus accesses outside the
+ threadStorageCache array, thus memory corruption. Crash observed on
+ Mac OS X platform.
+
+2004-06-23 Joe Mistachkin <joe@mistachkin.com>
+
+ * generic/tclThread.c: Implements platform independent thread storage
+ * generic/tclThreadStorage.c: mechanism and fixes associated bugs on
+ platforms where there is limited thread local storage space
+ (Win98/WinNT4). [Patch 976496]
+
+ * generic/tclInt.decls:
+ * generic/tclIntDecls.h: Added thread storage functions to the
+ * generic/tclStubInit.c: internal stubs table.
+
+ * unix/Makefile.in:
+ * unix/configure:
+ * unix/tcl.m4:
+ * win/makefile.vc:
+ * win/rules.vc:
+ * win/Makefile.in: Modified the unix, VC++, and Cygwin build systems
+ * win/configure: to include the new "tclThreadStorage.c" and the new
+ * win/tcl.m4: USE_THREAD_STORAGE define.
+
+2004-06-23 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ * tests/io.test: Added -force to 18.1 and 18.2. This was failing on
+ WinXP.
+
+ * tests/winFCmd.test: Added a cleanup to winFCmd-16.11 to avoid a
+ failure in 16.12.
+
+ * tests/eofchar.data: Added -kb option to ensure a binary checkout to
+ win32 systems. This fixes a failure in io-61.1
+
+ * win/makefile.vc: fix for [Bug 977369] about launching tclsh to
+ generate a tclConfig.sh with the nmake build system
+
+2004-06-23 Kevin B. Kenny <kennykb@acm.org>
+
+ * tests/winDde.test (createChildProcess): Added a 200-ms delay (with
+ the event loop live) when shutting down the test DDE server process.
+ With the delay in place, nuisance failures of tests winDde-4.2, -6.5,
+ and -6.6 appear to be much less frequent. [Bug 957449]
+
+2004-06-23 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * tests/*.test: Standardize use of platform constraints.
+
+ * unix/tclUnixInit.c (GetStackSize, TclpCheckStackSpace):
+ * unix/tclUnixThrd.c (TclpThreadGetStackSize): Added code to check
+ whether the C stack is about to be exceeded, from [Patch 746378] by
+ Joe Mistachkin but with substantial revisions.
+
+2004-06-22 Kevin Kenny <kennykb@acm.org>
+
+ * generic/tclEvent.c (NewThreadProc): Fixed broken build on Windows
+ caused by missing TCL_THREAD_CREATE_RETURN.
+
+ * tests/stack.test (stack-3.1): Corrected nuisance error in threaded
+ builds.
+
+2004-06-22 Zoran Vasiljevic <vasiljevic@users.sf.net>
+
+ * generic/tclEvent.c:
+ * generic/tclInt.h:
+ * unix/tclUnixNotfy.c:
+ * unix/tclUnixThrd.c:
+ * win/tclWinThrd.c: [Bug 770053]. See bug report for more information
+ about what it does.
+
+ * tests/unixNotfy.test: rewritten to use tcltest::threadReap to
+ gracefully wait for the test thread to exit. Otherwise we got a race
+ condition with main thread exiting before the test thread. This
+ exposed the long-standing Tcl lib issue with resource
+ garbage-collection on application exit.
+
+2004-06-21 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/tclWin32Dll.c (DllMain, _except_dllmain_detach_handler)
+ (TclpCheckStackSpace, _except_checkstackspace_handler)
+ (TclWinCPUID, _except_TclWinCPUID_detach_handler):
+ * win/tclWinChan.c (Tcl_MakeFileChannel)
+ (_except_makefilechannel_handler):
+ * win/tclWinFCmd.c (DoRenameFile, _except_dorenamefile_handler)
+ (DoCopyFile, _except_docopyfile_handler):
+ Rework pushing of exception handler function pointer so that compiling
+ with gcc -O3 works. Remove empty function call to avoid compiler
+ warning. Mark the DllMain function as noinline to avoid compiler error
+ from duplicated asm labels in generated code.
+
+2004-06-21 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclThreadAlloc.c (Ptr2Block): Rewrote so as to maximize the
+ chance of detecting and reporting a memory inconsistency without
+ relying on things being consistent. [Bug 975895]
+
+2004-06-18 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/load.test: Relaxed strictness of error message matching
+ for test load-2.3 so that it will pass on Mac OSX.
+
+ * generic/tclEncoding.c: Static TclFindEncodings -> FindEncodings.
+ * generic/tclInt.h: Updated TclpFindExecutable() so that failed
+ * generic/tclUtil.c: attempts to find the executable are saved
+ * unix/tclUnixFile.c: just as successful finds are. [Patch 966053]
+ * unix/tclUnixTest.c:
+
+2004-06-18 Kevin B. Kenny <kennykb@acm.org>
+
+ * tests/winFCmd.test (winFCmd-16.12): Changed test to compute the
+ target directory, so as not to fail if the user's HOME isn't the root.
+
+2004-06-19 Daniel Steffen <das@users.sourceforge.net>
+
+ * unix/tcl.m4: autoconf 2.5 fixes in Darwin section.
+ * unix/configure: autoconf-2.57
+
+2004-06-18 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * unix/tclUnixInit.c (localeTable): Added some more locale to encoding
+ mapping info from Jim Huang <jserv@kaffe.org>
+
+ * generic/tclInt.h (PendingObjData,TclFreeObjMacro,etc):
+ * generic/tclObj.c (TclFreeObj): Added scheme for making TclFreeObj()
+ avoid blowing up the C stack when freeing up very large object trees.
+ [Bug 886231]
+
+ * win/tclWinInit.c (SetDefaultLibraryDir): Fix logic, simplify and add
+ comments.
+
+2004-06-17 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclObj.c: Added missing space in panic message.
+
+ * win/tclWinInit.c: Inform [tclInit] about the default library
+ directory via the ::tclDefaultLibrary variable. This should correct a
+ problem with my 2004-06-11 commit. Better solutions still in the
+ works. Thanks to Joe Mistachkin for pointing out the breakage.
+
+2004-06-16 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/library.n: Moved variables ::auto_oldpath and
+ * library/auto.tcl: ::unknown_pending into ::tcl namespace.
+ * library/init.tcl: [Bugs 808319, 948794]
+
+2004-06-15 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/binary.n: Added some notes to the documentation of the 'a'
+ format to address the point raised in [RFE 768852].
+
+2004-06-15 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/tclConfig.sh.in (TCL_EXTRA_CFLAGS): set to @CFLAGS@, which is
+ the configure-time CFLAGS. Addendum to m4 change on 2004-05-26.
+
+2004-06-14 Kevin Kenny <kennykb@acm.org>
+
+ * win/Makefile.in: Corrected compilation flags for tclPkgConfig.c so
+ that it doesn't require Stubs.
+ * generic/tclBasic.c (Tcl_CreateInterp): Removed comment stating that
+ TclInitEmbeddedConfigurationInformation needs Stubs; with the change
+ above, the comment is now erroneous.
+
+2004-06-11 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/Encoding.3: Removed bogus claims about tcl_libPath.
+
+ * generic/tclInterp.c (Tcl_Init): Stopped setting the
+ tcl_libPath variable. [tclInit] can get all its directories without it.
+
+ * tests/unixInit.test: Modified test code that made use of
+ tcl_libPath variable.
+
+ * unix/tclUnixInit.c: Stopped setting the tclDefaultLibrary variable,
+ execept on the Mac OS X platform with HAVE_CFBUNDLE. In that
+ configuration we should seek some way to make use of the TIP 59
+ facilities and get rid of that usage of tclDefaultLibrary as well.
+
+ * generic/tclInterp.c: Updated [tclInit] to make $env(TCL_LIBRARY) an
+ absolute path, and to include the scriptdir,runtime configuration value
+ on the search path for init.tcl.
+
+ * unix/tclUnixInit.c: The routines Tcl_Init() and TclSourceRCFile()
+ * win/tclWinInit.c: had identical implementations for both win and
+ * generic/tclInterp.c: unix. Moved to a single generic implementation.
+ * generic/tclMain.c:
+ * library/init.tcl:
+ * generic/tclInitScript.h (removed):
+ * unix/Makefile.in:
+ * win/tcl.dsp:
+
+ * unix/configure.in: Updated TCL_PACKAGE_PATH value to handle
+ * win/configure.in: --libdir configuration.
+
+ * unix/configure.in: autoconf-2.57
+ * win/configure.in:
+
+ * generic/tclBasic.c (Tcl_CreateInterp): Moved call to
+ TclInitEmbeddedConfigurationInformation() earlier in
+ Tcl_CreateInterp() so that other parts of interp creation and
+ initialization may access and use the config values.
+
+2004-06-11 Kevin Kenny <kennykb@acm.org>
+
+ * win/tclAppInit.c: Restored the 'setargv' procedure when compiling
+ with mingw. Apparently, the command line parsing in mingw doesn't work
+ as well as that in vc++, and the result was (1) that winPipe-8.19
+ failed, and (2) that 'make test' would work at all only with
+ TESTFLAGS='-singleproc 1'. [Bug 967195]
+
+2004-06-10 Zoran Vasiljevic <vasiljevic@users.sf.net>
+
+ * generic/tclIOUtil.c: removed forceful setting of the private cached
+ current working directory rep from within the Tcl_FSChdir(). We
+ delegate this task to the Tcl_FSGetCwd() which does this task anyway.
+ The relevant code is still present but disabled temporarily until the
+ change proves correct. The Tcl test suite passes all test with the
+ given change so I suppose it is good enough.
+
+2004-06-10 Don Porter <dgp@users.sourceforge.net>
+
+ * unix/tclUnixInit.c (TclpInitLibraryPath): Disabled addition of
+ * win/tclWinInit.c (TclpInitLibraryPath): relative-to-executable
+ directories to the library search path. A first step in reform of
+ Tcl's startup process.
+
+ ***POTENTIAL INCOMPATIBILITY***
+ Attempts to directly run ./tclsh or ./tcltest out of a build directory
+ will either fail, or will make use of an installed script library in
+ preference to the one in the source tree. Use `make shell` or `make
+ runtest` instead.
+
+ * tests/unixInit.test: Modified tests to suit above changes.
+
+ * generic/tclPathObj.c: Corrected [file tail] results when operating
+ on a path produced by TclNewFSPathObj(). [Bug 970529]
+
+2004-06-09 Zoran Vasiljevic <vasiljevic@users.sf.net>
+
+ * generic/tclIOUtil.c: partially corrected [Bug 932314]. Also
+ corrected return values of Tcl_FSChdir() to reflect those of the
+ underlying platform-specific call. Originally, return codes were mixed
+ with those of Tcl.
+
+2004-06-08 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompile.c:
+ * generic/tclExecute.c: handle warning [Bug 969066]
+
+2004-06-08 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclHash.c (RebuildTable): Move declaration of variable so it
+ is only declared when it is used. [Bug 969068]
+
+2004-06-07 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/lsearch.n: Added correct option to example. [Bug 968219]
+
+2004-06-05 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tcl.h: Corrected Tcl_WideInt declarations so that the mingw
+ build works again.
+ * generic/tclDecls.h: Changes to the tests for clock
+ * generic/tclInt.decls: frequency in Tcl_WinTime so
+ * generic/tclIntDecls.h: that any clock frequency is
+ * generic/tclIntPlatDecls.h: accepted provided that all
+ * generic/tclPlatDecls.h: CPU's in the system share a
+ * generic/tclStubInit.c: common chip, and hence,
+ * tests/platform.test (platform-1.3): presumably, a common clock.
+ * win/tclWin32Dll.c (TclWinCPUID): This change necessitated a
+ * win/tclWinTest.c (TestwincpuidCmd) small burst of assembly code
+ * win/tclWinTime.c (Tcl_GetTime): to read CPU ID information,
+ which was added as TclWinCPUID in the internal Stubs. To test this
+ code in the common case of a single-processor machine, a
+ 'testwincpuid' command was added to tclWinTest.c, and a test case in
+ platform.test. Thanks to Jeff Godfrey and Richard Suchenwirth for
+ reporting this bug. [Bug 976722]
+
+2004-06-04 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tcl.h: Restored #include <stdio.h> to tcl.h,
+ rejecting the "fix" for "Bug" 945570. Tcl_FSSeek() needs the values of
+ SEEK_SET, etc. and too many extensions rely on tcl.h providing stdio.h
+ for them.
+
+2004-06-02 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/tclWinFile.c (TclpFindExecutable): when using GetModuleFileNameA
+ (Win9x), convert from CP_ACP to WCHAR then convert back to utf8.
+ Adjunct to 2004-04-07 fix.
+
+2004-06-02 David Gravereaux <davygrvy@pobox.com>
+
+ * tests/winPipe.test (winpipe-6.1): blocking set to 1 before closing
+ to ensure we get an exitcode. The windows pipe channel driver doesn't
+ differentiate between a blocking and non-blocking close just yet, but
+ will soon. Part of [Bug 947693]
+
+2004-06-02 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * doc/file.n: fix to documentation of 'file volumes' (Bug 962435)
+
+2004-06-01 David Gravereaux <davygrvy@pobox.com>
+
+ * win/makefile.vc: check for either MSDEVDIR or MSVCDIR being in the
+ environment, for VC7. [Bug 942214]
+
+ * generic/tclIO.c (Tcl_SetChannelOption): -buffersize wasn't
+ understanding hexidecimal notation nor was reporting number conversion
+ errors. The behavior to silently ignore settings outside the
+ acceptable range of Tcl_SetChannelBufferSize (<10 or >1M) is
+ unchanged. This silent ignoring behavior might be up for review soon.
+
+2004-05-30 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinPipe.c:
+ * win/tclWinPort.h: Reworked the win implementation of Tcl_WaitPid to
+ support exitcodes in the 'signed short' range. Even though this range
+ is non-portable, it is valid on windows. Detection of exception codes
+ are now more accurate. Previously, an application that exited with
+ ExitProcess((DWORD)-1); was improperly reported as exiting with
+ SIGABRT.
+
+2004-05-30 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclInterp.c: Added comments describing the purposes of each
+ function in the limit implementation and rewrote the names of some
+ non-public functions for greater clarity of purpose.
+ * doc/interp.n: Added note about what happens when a limited
+ interpreter creates a slave interpreter.
+ * doc/Limit.3: Added manual page for the resource limit subsystem's C
+ API. [Bug 953903]
+
+2004-05-29 Joe English <jenglish@users.sourceforge.net>
+
+ * doc/global.n, doc/interp.n, doc/lrange.n: Fix minor markup errors.
+
+2004-05-28 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/*.n: Added examples to many (too many to list) more man pages.
+
+2004-05-25 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c:
+ * generic/tclVar.c: using (ptrdiff_t) instead of (int) casting to
+ correct compiler warnings [Bug 961657], reported by Bob Techentin.
+
+2004-05-27 Kevin B. Kenny <kennykb@acm.org>
+
+ * tests/clock.test: Added a single test for the presence of %G in
+ [clock format], and conditioned out the clock-10.x series if they're
+ all going to fail because of a broken strftime() call. [Bug 961714]
+
+2004-05-27 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclHash.c (CompareStringKeys): Added #ifdef to allow people
+ to instruct this function to use strcmp(). [FRQ 951168]
+
+ * generic/tclVar.c: Moved declarations into #if guards so they only
+ happen when required.
+ * unix/tclUnixPort.h: Guard declaration of strtod() so it is only
+ enabled when we don't have a declaration in stdlib.h
+ * unix/tclUnixThrd.c (Tcl_CreateThread): Added declarations
+ * unix/tclUnixTest.c (AlarmHandler): and casts so that
+ * unix/tclUnixChan.c (TtyModemStatusStr): all functions are
+ * generic/tclScan.c (Tcl_ScanObjCmd): defined before use
+ * generic/tclDictObj.c (InvalidateDictChain): and no cross-type
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd): uses are performed.
+
+ The overall effect is to make building with gcc with the additional
+ flags -Wstrict-prototypes -Wmissing-prototypes produce no increase in
+ the total number of warnings (except for main(), which is undeclared
+ for traditional reasons.)
+
+2004-05-26 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/Makefile.in: Rework configure ordering to TCL_LINK_LIBS,
+ * unix/tcl.m4: ENABLE_SHARED, CONFIG_CFLAGS, & ENABLE_SYMBOLS
+ * unix/configure: before TCL_EARLY_FLAGS and TCL_64BIT_FLAGS
+ * unix/configure.in: (about 400 lines earlier) in configure.in. This
+ forces CFLAGS configuration to be done before many tests, which is
+ needed for 64-bit builds and may affect other builds. Also make
+ CONFIG_CFLAGS append to CFLAGS directly instead of using EXTRA_CFLAGS,
+ and have LDFLAGS append to any existing value. [Bug 874058]
+ * unix/dltest/Makefile.in: change EXTRA_CFLAGS to DEFS
+
+2004-05-26 Don Porter <dgp@users.sourceforge.net>
+
+ * library/tcltest/tcltest.tcl: Correction to debug prints and testing
+ * library/tcltest/pkgIndex.tcl: if TCLTEST_OPTIONS value. Corrected
+ * tests/tcltest.test: double increment of numTestFiles in
+ -singleproc 1 configurations. Updated tcltest-19.1 to tcltest 2.1
+ behavior. Corrected tcltest-25.3 to not falsely report a failure in
+ tcltest.test. Bumped to tcltest 2.2.6. [Bugs 960560, 960926]
+
+2004-05-25 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * doc/http.n (http::config): add -urlencoding option (default utf-8)
+ * library/http/http.tcl: that specifies encoding conversion of
+ * library/http/pkgIndex.tcl: args for http::formatQuery. Previously
+ * tests/http.test: undefined, RFC 2718 says it should be
+ utf-8. 'http::config -urlencoding {}' returns previous behavior, which
+ will throw errors processing non-latin-1 chars. Bumped http package to
+ 2.5.0.
+
+2004-05-25 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclInterp.c (DeleteScriptLimitCallback): Move all deletion
+ of script callback hash table entries to happen here so the entries
+ are correctly removed at the right time. [Bug 960410]
+
+2004-05-25 Miguel Sofer <msofer@users.sf.net>
+
+ * docs/global.n: added details for qualified variable names [Bug
+ 959831]
+
+2004-05-25 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclNamesp.c (Tcl_FindNamespaceVar):
+ * tests/namespace.test (namespace-17.10-12): reverted commit of
+ 2004-05-23 and removed the tests, as it interferes with the varname
+ resolver and there are apps that break (AlphaTk). A fix will have to
+ wait for Tcl9.
+
+ * generic/tclVar.c: Caching of namespace variables disabled: no simple
+ way was found to avoid interfering with the resolver's idea of
+ variable existence. A cached varName may keep a variable's name in the
+ namespace's hash table, which is the resolver's criterion for
+ existence.
+
+ * tests/namespace.c (namespace-17.10): testing for interference
+ between varname caching and name resolver.
+
+2004-05-25 Kevin Kenny <kennykb@acm.org>
+
+ * tests/winFCmd.test: Correct test for the presence of a CD-ROM so
+ that it doesn't misdetect some other sort of filesystem with a
+ write-protected root as being a CD-ROM drive. [Bug 918267]
+
+2004-05-25 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/winPipe.test: Protect against path being set
+ * tests/unixInit.test: Unset path when done.
+ * tests/unload.test (unload-3.1): Verify [pkgb_sub] does not exist.
+ Delete interps when done.
+ * tests/stringComp.test: stop re-use of string.test test names
+ * tests/regexpComp.test: stop re-use of regexp.test test names
+ * tests/namespace.test (namespace-46.3): Verify [p] does not exist.
+ * tests/http.test: Clear away the custom [bgerror] when done.
+ * tests/io.test: Take care to use namespace variables.
+ * tests/autoMkindex.test (autoMkindex-5.2): Use variable "result"
+ that gets cleaned up.
+ * tests/exec.test: Clean up the "path" array.
+ * tests/interp.test (interp-9.3): Initialize res, so prior values
+ cannot make the test fail.
+ * tests/execute.test (execute-8.1): Updated to remove the trace set
+ on ::errorInfo. When left in place, that trace can cause later tests
+ to fail.
+
+2004-05-25 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclBasic.c: Removed references to Tcl_RenameCommand from
+ * generic/tcl.h: comments. [Bug 848440, second part]
+
+ * tests/fCmd.test: Rewrote tests that failed consistently on NFS so
+ they either succeed (through slightly more liberal matching of the
+ results) or are constrained to not run. [Bug 931312]
+
+ * doc/bgerror.n: Use idiomatic open flags for working with log
+ files. [Bug 959602]
+
+2004-05-24 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclExecute.c (VerifyExprObjType): use GET_WIDE_OR_INT to
+ properly have tclIntType used for smaller values. This corrects [TclX
+ Bug 896727] and any other 3rd party extension that created math
+ functions but was not yet WIDE_INT aware in them.
+
+2004-05-24 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclInterp.c (TclInitLimitSupport): Made limits work on
+ platforms where sizeof(void*)!=sizeof(int). [Bug 959193]
+
+2004-05-24 Miguel Sofer <msofer@users.sf.net>
+
+ * doc/set.n: accurate description of name resolution process,
+ referring to namespace.n for details [Bug 959180]
+
+2004-05-23 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclNamesp.c (Tcl_FindNamespaceVar): [Bug 959052] fixed,
+ insuring that no "zombie" variables are found.
+ * generic/tclVar.c (TclLookupSimpleVar): comments re [Bug 736729]
+ (predecessor of [Bug 959052]) removed.
+ * tests/namespace.test: added tests 17.10-12
+
+ The patch modifies non-documented behaviour, and passes every test in
+ the testsuite. However, scripts relying on the old behaviour may
+ break.
+ Note that the only behaviour change concerns the creative writing of
+ unset variables. More precisely, which variable will be created when
+ neither a namespace variable nor a global variable by that name
+ exists, as defined by [info vars]. The new behaviour is that the
+ namespace resolution process deems a variable to exist exactly when
+ [info vars] finds it - ie, either it has value, or else it was "fixed"
+ by a call to [variable].
+ Note: this patch was removed on 2002-05-25.
+
+2004-05-22 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclVar.c (TclObjLookupVar, TclObjUnsetVar2): fix for new (in
+ tcl8.4) exteriorisations of [Bug 736729] due to the use of
+ tclNsVarNameType obj types. Reenabling the use of this objType ("VAR
+ ref absolute" benchmark down to 66 ms, from 230). Added comments in
+ TclLookupSimpleVar explaining my current understanding of [Bug
+ 736729].
+
+2004-05-22 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclVar.c: fix for [Bug 735335]. The use of tclNsVarNameType
+ objs is still disabled, pending resolution of [Bug 736729].
+
+2004-05-21 Miguel Sofer <msofer@users.sf.net>
+
+ * tests/namespace.test (namespace-41.3): removed the {knownBug}
+ constraint: [Bug 231259] is closed since nov 2001, and the fix of [Bug
+ 729692] (INST_START_CMD) makes the test succeed.
+
+2004-05-21 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclExecute.c (TclExecuteByteCode): Move a few declarations a
+ short distance so pre-C99 compilers can cope. Also fix so
+ TCL_COMPILE_DEBUG path compiles...
+
+2004-05-21 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c (TclExecuteByteCode): reorganised TEBC
+ automatic variables, defining them in tight blocks instead of at the
+ function level. This has three purposes:
+ - it simplifies the analysis of individual instructions
+ - it is preliminary work to the non-recursive engine
+ - it allows a better register allocation by the optimiser; under
+ gcc3.3, this results in up to 10% runtime in some tests
+
+2004-05-20 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclInterp.c (TclLimitRemoveAllHandlers):
+ * generic/tclBasic.c (DeleteInterpProc):
+ * tests/interp.test (interp-34.7): Ensure that all limit callbacks are
+ deleted when their interpreters are deleted. [Bug 956083]
+
+2004-05-19 Kevin B. Kenny <kennykb@acm.org>
+
+ * win/tclWinFile.c (TclpMatchInDirectory): fix for an issue where
+ there was a sneak path from Tcl_DStringFree to SetErrorCode(0). The
+ result was that the error code could be reset between a call to
+ FindFirstFileEx and the check of its status return, leading to a
+ bizarre error return of {POSIX unknown {No error}}. (Found in
+ unplanned test - no incident logged at SourceForge.)
+
+2004-05-19 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * tests/interp.test (interp-34.3): Rewrite this test to see if a time
+ limit can catch a tight bytecode loop, a maximally aggressive
+ denial-of-service attack.
+ * generic/tclInterp.c (Tcl_LimitCheck): Fix the sense of checks to see
+ whether a time limit has been extended.
+
+ * tests/*.test: Many minor fixes, including ensuring that every test
+ is run (so constraints control whether the test is doing anything) and
+ making sure that constraints are always set using the API instead of
+ poking around inside tcltest's internal datastructures. Also got rid
+ of all trailing whitespace lines from the test suite!
+
+2004-05-19 Andreas Kupries <andreask@activestate.com>
+
+ * generic/tclIO.c: Fixed [SF Tcl Bug 943274]. This is the same problem
+ * generic/tclIO.h: as [SF Tcl Bug 462317], see ChangeLog entry
+ 2001-09-26. The fix done at that time is incomplete. It is possible to
+ get around it if the actual read operation is defered and not executed
+ in the event handler itself. Instead of tracking if we are in an read
+ caused by a synthesized fileevent we now track if the OS has delivered
+ a true event = actual data and bypass the driver if a read finds that
+ there is no actual data waiting. The flag is cleared by a short or
+ full read.
+
+ ***POTENTIAL INCOMPATIBILITY*** for channel drivers.
+
+2004-05-17 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclPathObj.c: fix to (Bug 956063) in 'file dirname'.
+ * tests/cmdAH.test: added test for this bug.
+
+ * doc/FileSystem.3: better documentation of refCount requirements of
+ some FS functions (Bug 956126)
+
+2004-05-19 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclTest.c (TestgetintCmd): Made the tests in get.test check
+ * tests/get.test: Tcl_GetInt() since the core now
+ avoids that function.
+
+2004-05-18 Kevin B. Kenny <kennykb@acm.org>
+
+ * compat/strftime.c (_fmt, ISO8601Week):
+ * doc/clock.n:
+ * tests/clock.test: Major rework to the handling of ISO8601 week
+ numbers. Now passes all the %G and %V test cases on Windows, Linux and
+ Solaris [Bugs 500285, 500389, and 852944]
+
+2004-05-18 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/append.n, doc/upvar.n: Added example.
+
+2004-05-18 David Gravereaux <davygrvy@pobox.com>
+
+ * win/makefile.vc: now generates a tclConfig.sh from Pat Thoyts [Patch
+ 909911]
+
+2004-05-18 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/lsearch.n: Improve clarity (based on [Patch 955361] by Peter
+ Spjuth)
+
+ * tools/man2help2.tcl (macro,SHmacro): Added support for subsection
+ (.SS) header macros.
+
+ * doc/interp.n: Added user documentation for the TIP#143 resource
+ limits and some examples.
+
+ * generic/tclInterp.c (Tcl_LimitCheck, Tcl_LimitTypeReset): Reset the
+ limit-exceeded flag when removing a limit.
+
+2004-05-18 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c (TclExecuteByteCode): added comments to
+ classify the variables according to their use in TEBC.
+
+2004-05-17 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/global.n, doc/uplevel.n: Added an example.
+
+ * tests/info.test (info-3.1): Corrected test result back to what it
+ used to be in Tcl 7.* now that command counts are being correctly kept
+
+ * generic/tclExecute.c (TEBC:INST_START_CMD): Make sure that the
+ command-count is always advanced. Allows TIP#143 limits to tell that
+ work is being done.
+
+ * doc/list.n: Updated example to fit with the unified format.
+ * doc/seek.n: Added some examples.
+
+2004-05-17 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * win/tclWinFile.c:
+ * tests/cmdAH.test: fix to (Bug 954263) where 'file executable' was
+ case-sensitive.
+
+2004-05-17 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/OpenFileChnl.3: Documented type of 'offset' argument to Tcl_Seek
+ was wrong. [Bug 953374]
+
+2004-05-16 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c (TclExecuteByteCode): remove one level of
+ indirection for compiledLocals addressing.
+
+2004-05-16 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c (INST_CALL_FUNC1): bugfix; restored
+ (DE)CACHE_STACK_INFO pair around the call - the user defined math
+ function could cause a recursive call to TEBC.
+
+2004-05-16 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclBasic.c (Tcl_DeleteInterp):
+ * generic/tclExecute.c (INST_START_CMD): interp deletion now modifies
+ the compileEpoch, eliminating the need for the check for interp
+ deletion in INST_START_CMD.
+
+2004-05-16 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompile.h:
+ * generic/tclCompile.c:
+ * generic/tclExecute.c: changed implementation of {expand}, last
+ chance while in alpha as ...
+
+ ***POTENTIAL INCOMPATIBILITY***
+ Scripts precompiled with ProComp under previous tcl8.5a versions may
+ malfunction due to changed instruction numbers for
+ INST_LIST_INDEX_IMM, INST_LIST_RANGE_IMM and INST_START_CMD.
+
+2004-05-14 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclInt.decls: Promoted TclpLocaltime and TclpGmtime
+ * generic/tclIntDecls.h: from Unix-specific stubs to the generic
+ * generic/tclIntPlatDecls.h: internal Stubs table. Reran 'genstubs'
+ * generic/tclStubInit.c:
+ * unix/tclUnixPort.h:
+
+ * generic/tclClock.c: Changed a buggy 'GMT' timezone specification
+ to the correct 'GMT0'. [Bug 922848]
+
+ * unix/tclUnixThrd.c: Moved TclpGmtime and TclpLocaltime to
+ unix/tclUnixTime.c where they belong.
+
+ * unix/tclUnixTime.c (TclpGmtime, TclpLocaltime, TclpGetTimeZone,
+ ThreadSafeGMTime [removed],
+ ThreadSafeLocalTime [removed],
+ SetTZIfNecessary, CleanupMemory):
+ Restructured to make sure that the same mutex protects all calls to
+ localtime, gmtime, and tzset. Added a check in front of those calls to
+ make sure that the TZ env var hasn't changed since the last call to
+ tzset, and repeat tzset if necessary. [Bug 942078] Removed a buggy
+ test of the Daylight Saving Time information in 'gettimeofday' in
+ favor of applying 'localtime' to a known value. [Bug 922848]
+
+ * tests/clock.test (clock-3.14): Added test to make sure that changes
+ to $env(TZ) take effect immediately.
+
+ * win/tclWinTime.c (TclpLocaltime, TclpGmtime): Added porting layer
+ for 'localtime' and 'gmtime' calls.
+
+2004-05-14 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c:
+ * generic/tclCompile.h: the math functions receive a pointer to top of
+ the stack (tosPtr) instead of the execution environment (eePtr). First
+ step towards a change in the execution stack management - it is now
+ only used within TEBC.
+
+2004-05-13 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ TIP#143 IMPLEMENTATION
+
+ * generic/tclExecute.c (TclCompEvalObj, TclExecuteByteCode):
+ * generic/tclBasic.c (TclEvalObjvInternal): Enable limit checking.
+ * generic/tclInterp.c (Tcl_Limit*): Public limit API.
+ * generic/tcl.decls:
+ * tests/interp.test: Basic tests of command limits.
+
+ * doc/binary.n: TIP#129 IMPLEMENTATION [Patch 858211]
+ * generic/tclBinary.c: Note that the test suite probably has many more
+ * tests/binary.test: failures now due to alterations in constraints.
+
+2004-05-12 Miguel Sofer <msofer@users.sf.net>
+
+ Optimisations for INST_START_CMD [Bug 926164].
+ * generic/tclCompile.c (TclCompileScript): avoid emitting
+ INST_START_CMD as the first instruction in a bytecoded Tcl_Obj. It is
+ not needed, as the checks are done before calling TEBC.
+ * generic/tclExecute.c (TclExecuteByteCode): runtime peephole
+ optimisation: check at INST_POP if the next instruction is
+ INST_START_CMD, in which case we fall through.
+
+2004-05-11 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/split.n, doc/join.n: Updated examples and added more.
+
+2004-05-11 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * doc/glob.n: documented behaviour of symbolic links with 'glob -types
+ d' (Bug 951489)
+
+2004-05-11 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/scan.n: Updated the examples to be clearer about their relevance
+ to the scan command.
+
+2004-05-10 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/scan.n: Added examples.
+
+2004-05-10 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinPipe.c (BuildCommandLine): Moved non-obvious appending
+ logic to outside the loop and added commentary for its purpose. Also
+ use the existence of contents in the linePtr rather than the scratch
+ DString post the append, as this more clear.
+
+ (TclpCreateProcess): When under NT, with no console, and executing a
+ DOS application, the path priming does not need an ending space as
+ BuildCommandLine() will do this for us.
+
+2004-05-08 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclFileName.c:
+ * generic/tclIOUtil.c: remove some compiler warnings on MacOS X.
+
+2004-05-07 Chengye Mao <chengye.geo@yahoo.com>
+
+ * win/tclWinPipe.c: refixed bug 789040 re-entered in rev 1.41. Let's
+ be careful and don't re-enter previously fixed bugs.
+
+2004-05-08 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/format.n: Added examples.
+
+2004-05-07 Miguel Sofer <msofer@users.sf.net>
+
+ * doc/unset.n: added upvar.n to the "see also" list
+
+2004-05-07 Reinhard Max <max@suse.de>
+
+ * generic/tclEncoding.c:
+ * tests/encoding.test: added support and tests for translating
+ embedded null characters between real nullbytes and the internal
+ representation on input/output [Bug 949905].
+
+2004-05-07 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclFileName.c:
+ * generic/tclIOUtil.c:
+ * generic/tclFileSystem.h:
+ * tests/fileSystem.test: fix for [Bug 943995], in which vfs-registered
+ root volumes were not handled correctly as glob patterns in all
+ circumstances.
+
+2004-05-06 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclInt.h:
+ * generic/tclObj.c (TclFreeObj): made TclFreeObj use the new macro
+ TclFreeObjMacro(), so that the allocation and freeing of Tcl_Obj is
+ defined in a single spot (the macros in tclInt.h), with the exception
+ of the TCL_MEM_DEBUG case.
+ The #ifdef logic for the corresponding macros has been reformulated to
+ make it clearer.
+
+2004-05-05 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/break.n, doc/continue.n, doc/for.n, doc/while.n: More examples.
+
+2004-05-05 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/unixInit.test (unixInit-2.10): Test correction for Mac OSX.
+ Be sure to consistently compare normalized path names. Thanks to
+ Steven Abner (tauvan). [Bug 948177]
+
+2004-05-05 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/CrtObjCmd.3: Remove reference to Tcl_RenameCommand; there is no
+ such API. [Bug 848440]
+
+2004-05-05 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinSock.c (SocketEventProc) : connect errors should fire both
+ the readable and writable handlers because this is how it works on
+ UNIX [Bug 794839]
+
+ * generic/tclEncoding.c (TclFinalizeEncodingSubsystem):
+ FreeEncoding(systemEncoding); moved to before the hash table iteration
+ as it was causing a double free attempt under some conditions.
+
+ * win/coffbase.txt: Added the tls extension to the list of preferred
+ load addresses.
+
+2004-05-04 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * tests/fileSystem.test (filesystem-1.39): replace 'file volumes'
+ * tests/fileName.test (filename-12.9,10): lindex with direct C:/
+ hard-coded because A:/ was being used and that is empty for most.
+
+ * tests/winFCmd.test (winFCmd-16.12): test volumerelative $HOME
+
+2004-05-04 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclAlloc.c: Make sure Tclp*Alloc* routines get
+ * generic/tclInt.h: declared in the TCL_MEM_DEBUG and
+ * generic/tclThreadAlloc.c: TCL_THREADS configuration. [Bug 947564]
+
+ * tests/tcltest.test: Test corrections for Mac OSX. Thanks to Steven
+ Abner (tauvan). [Bug 947440]
+
+2004-05-04 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclEvent.c (TclSetLibraryPath): Suppress a warning.
+
+2004-05-03 Andreas Kupries <andreask@activestate.com>
+
+ * Applied [Patch 868853], fixing a mem leak in TtySetOptionProc.
+ Report and Patch provided by Stuart Cassoff <stwo@users.sf.net>.
+
+2004-05-03 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclProc.c (TclCreateProc): comments corrected.
+
+2004-05-03 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompile.c (TclCompileScript): setting the compilation
+ namespace outside of the loop.
+
+2004-05-03 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompile.c:
+ * generic/tclInt.h: reverted fix for [Bug 926445] of 2004-04-02,
+ restoring TCL_ALIGN to the header file. Todd Helfter reported that the
+ macro is required by tbcload.
+
+2004-05-03 Kevin Kenny <kennykb@acm.org>
+
+ * win/tclWin32Dll.c (TclpCheckStackSpace):
+ * tests/stack.test (stack-3.1): Fix for undetected stack overflow in
+ TclReExec on Windows. [Bug 947070]
+
+2004-05-03 Don Porter <dgp@users.sourceforge.net>
+
+ * library/init.tcl: Corrected unique prefix matching of
+ interactive command completion in [unknown]. [Bug 946952]
+
+2004-05-02 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclProc.c (TclObjInvokeProc):
+ * tests/proc.test (proc-3.6): fix for bad quoting of multi-word proc
+ names in error messages [Bug 942757]
+
+2004-04-30 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/glob.n, doc/incr.n, doc/set.n: More examples.
+ * doc/if.n, doc/rename.n, doc/time.n:
+
+2004-04-30 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclInt.h: Replaced Kevin Kenny's temporary
+ * generic/tclThreadAlloc.c: fix for Bug 945447 with a cleaner,
+ more permanent replacement.
+
+2004-04-30 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclThreadAlloc.c: Added a temporary (or so I hope!)
+ inclusion of "tclWinInt.h" to avoid problems when compiling on
+ Win32-VC++ with --enable-threads. [Bug 945447]
+
+2004-04-30 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/puts.n: Added a few examples.
+
+2004-04-29 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/execute.test (execute-8.2): Avoid crashes when there is
+ limited system stack space (threads-enabled).
+
+2004-04-28 Miguel Sofer <msofer@users.sf.net>
+
+ * doc/global.n:
+ * doc/upvar.n:
+ * generic/tclVar.c (ObjMakeUpvar):
+ * tests/upvar.test (upvar-8.11):
+ * tests/var.test (var-3.11): Avoid creation of unusable variables:
+ [Bug 600812] [TIP 184].
+
+2004-04-28 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/lsearch.n: Fixed fault in documentation of -index option [943448]
+
+2004-04-26 Don Porter <dgp@users.sourceforge.net>
+
+ * unix/tclUnixFCmd.c (TclpObjNormalizePath): Corrected improper
+ positioning of returned checkpoint. [Bug 941108]
+
+2004-04-26 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/open.n, doc/close.n: Updated (thanks to David Welton) to be
+ clearer about pipeline errors and added example to open(n) that shows
+ simple pipeline use. [Patches 941377,941380]
+
+ * doc/DictObj.3: Added warning about the use of Tcl_DictObjDone and an
+ example of use of iteration. [Bug 940843]
+
+ * doc/Thread.3: Reworked to remove references to testing interfaces
+ and instead promote the use of the Thread package. [Patch 932527]
+ Also reworked and reordered the page for better readability.
+
+2004-04-25 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tcl.h: Removed obsolete declarations and #include's.
+ * generic/tclInt.h: [Bugs 926459, 926486]
+
+2004-04-24 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWin32Dll.c (DllMain): Added DisableThreadLibraryCalls() for
+ the DLL_PROCESS_ATTACH case. We're not interested in knowing about
+ DLL_THREAD_ATTACH, so disable the notices.
+
+2004-04-24 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tclPort.h:
+ * macosx/Makefile:
+ * unix/Makefile.in: followup on tcl header reform [FR 922727]: removed
+ use of relative #include paths in tclPort.h to allow installation of
+ private headers outside of tcl source tree; added 'unix' dir to
+ compiler header search path; add newly required tcl private headers to
+ Tcl.framework on Mac OSX.
+
+2004-04-23 Andreas Kupries <andreask@activestate.com>
+
+ * generic/tclIO.c (Tcl_SetChannelOption): Fixed [SF Tcl Bug 930851].
+ When changing the eofchar we have to zap the related flags to prevent
+ them from prematurely aborting the next read.
+
+2004-04-25 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclPathObj.c: fix to [Bug 940281]. Tcl_FSJoinPath will now
+ always return a valid Tcl_Obj when the input is valid.
+ * generic/tclIOUtil.c: fix to [Bug 931823] for a more consistent
+ Tcl_FSPathSeparator() implementation which allows filesystems not to
+ implement their Tcl_FSFilesystemSeparatorProc if they wish to use the
+ default '/'. Also fixed associated memory leak seen with, e.g., tclvfs
+ package.
+ * doc/FileSystem.3: documented Tcl_FSJoinPath return values more
+ clearly, and Tcl_FSFilesystemSeparatorProc requirements.
+
+2004-04-23 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWin32Dll.c: Removed my mistake from 4/19 of adding an exit
+ handler to TclWinInit. TclWinEncodingsCleanup called from
+ TclFinalizeFilesystem does the Tcl_FreeEncoding for us.
+
+ * win/tclWinChan.c (Tcl_MakeFileChannel): Case for CloseHandle
+ returning zero and not throwing a
+ RaiseException(EXCEPTION_INVALID_HANDLE) now being done.
+
+2004-04-22 David Gravereaux <davygrvy@pobox.com>
+
+ * generic/tclEvent.c: TclSetLibraryPath's use of caching the stringrep
+ of the pathPtr object to TclGetLibraryPath called from another thread
+ was ineffective if the original's stringrep had been invalidated as
+ what happens when it gets muted to a list.
+
+ * win/tclWinTime.c: If the Tcl_ExitProc (StopCalibration) is called
+ from the stack frame of DllMain's PROCESS_DETACH, the wait operation
+ should timeout and continue.
+
+ * generic/tclInt.h:
+ * generic/tclThread.c:
+ * generic/tclEvent.c:
+ * unix/tclUnixThrd.c:
+ * win/tclWinThrd.c: Provisions made so masterLock, initLock, allocLock
+ and joinLock mutexes can be recovered during Tcl_Finalize.
+
+2004-04-22 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/switch.n: Reworked the examples to be more systematically named
+ and to cover some TIP#75 capabilities.
+
+ * doc/cd.n: Documentation clarification from David Welton.
+
+ * doc/exec.n: Added some examples, Windows ones from Arjen Markus and
+ Unix ones by myself.
+
+2004-04-21 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/Hash.3: Added note to Tcl_{First,Next}HashEntry docs that
+ deleting the element they return is supported (and is in fact the only
+ safe update you can do to the structure of a hashtable while an
+ iteration is going over it.)
+
+ * doc/bgerror.n: Added example from David Welton. [Patch 939473]
+
+ * doc/after.n: Added examples from David Welton. [Patch 938820]
+
+2004-04-19 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWin32Dll.c: Added an exit handler in TclWinInit() so
+ tclWinTCharEncoding could be freed during Tcl_Finalize().
+
+ * generic/tclEncoding.c: Added FreeEncoding(systemEncoding) in
+ TclFinalizeEncodingSubsystem because its ref count was incremented in
+ TclInitEncodingSubsystem.
+
+2004-04-19 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/read.n: Added example from David Welton. [Patch 938056]
+
+2004-04-19 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclObj.c (Tcl_GetDoubleFromObj) Corrected "short circuit"
+ conversion of int to double. Reported by Jeff Hobbs on the Tcl'ers
+ Chat.
+
+2004-04-16 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/lreplace.n, doc/lrange.n, doc/llength.n: More examples for
+ * doc/linsert.n, doc/lappend.n: the documentation.
+
+2004-04-16 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * doc/FileSystem.3: Corrected documentation of Tcl_FSUtime, and the
+ corresponding filesystem driver Tcl_FSUtimeProc. [Bug 935838]
+
+2004-04-16 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/socket.n: Added example from [Patch 936245].
+ * doc/gets.n: Added example based on [Patch 935911].
+
+2004-04-15 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclClock.c (Tcl_ClockObjCmd): Minor fault in a [clock
+ clicks] error message.
+
+2004-04-07 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/tclWinInit.c (TclpSetInitialEncodings): note that WIN32_CE is
+ also a unicode platform.
+ * generic/tclEncoding.c (TclFindEncodings, Tcl_FindExecutable):
+ * generic/tclInt.h: Correct handling of UTF
+ * unix/tclUnixInit.c (TclpInitLibraryPath): data that is actually
+ * win/tclWinFile.c (TclpFindExecutable): "clean", allowing the
+ * win/tclWinInit.c (TclpInitLibraryPath): loading of Tcl from paths
+ that contain multi-byte chars on Windows [Bug 920667]
+
+ * win/configure: define TCL_LIB_FLAG, TCL_BUILD_LIB_SPEC,
+ * win/configure.in: TCL_LIB_SPEC, TCL_PACKAGE_PATH in tclConfig.sh.
+
+2004-04-06 Don Porter <dgp@users.sourceforge.net>
+
+ Patch 922727 committed. Implements three changes:
+
+ * generic/tclInt.h: Reworked the Tcl header files into a clean
+ * unix/tclUnixPort.h: hierarchy where tcl.h < tclPort.h < tclInt.h
+ * win/tclWinInt.h: and every C source file should #include
+ * win/tclWinPort.h: at most one of those files to satisfy its
+ declaration needs. tclWinInt.h and tclWinPort.h also better organized
+ so that tclWinPort.h includes the Windows implementation of
+ cross-platform declarations, while tclWinInt.h makes declarations that
+ are available on Windows only.
+
+ * generic/tclBinary.c (TCL_NO_MATH): Deleted the generic/tclMath.h
+ * generic/tclMath.h (removed): header file. The internal Tcl
+ * macosx/Makefile (PRIVATE_HEADERS): header, tclInt.h, has a
+ * win/tcl.dsp: #include <math.h> directly,
+ and file external to Tcl needing libm should do the same.
+
+ * win/Makefile.in (WIN_OBJS): Deleted the win/tclWinMtherr.c file.
+ * win/makefile.bc (TCLOBJS): It's a vestige from matherr() days
+ * win/makefile.vc (TCLOBJS): gone by.
+ * win/tcl.dsp:
+ * win/tclWinMtherr.c (removed):
+
+ End Patch 922727.
+
+ * tests/unixInit.test (unixInit-3.1): Default encoding on Darwin
+ systems is utf-8. Thanks to Steven Abner (tauvan). [Bug 928808]
+
+2004-04-06 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * tests/cmdAH.test (cmdAH-18.2): Added constraint because
+ access(...,X_OK) is defined to be permitted to be meaningless when
+ running as root, and OSX exhibits this. [Bug 929892]
+
+2004-04-02 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompile.c:
+ * generic/tclInt.h: removed the macro TCL_ALIGN() from tclInt.h,
+ replaced by the static macro ALIGN() in tclCompile.c [Bug 926445]
+
+2004-04-02 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompile.h: removed redundant #ifdef _TCLINT [Bug 928415],
+ reported by tauvan.
+
+2004-04-02 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/tcltest.test: Corrected constraint typos: "nonRoot" ->
+ "notRoot". Thanks to Steven Abner (tauvan). [Bug 928353]
+
+2004-04-01 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclInt.h: Removed obsolete tclBlockTime* declarations. [Bug
+ 926454]
+
+2004-04-01 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclIOUtil.c: Fix to privately reported vfs bug with 'glob
+ -type d -dir . *' across a vfs boundary. No tests for this are
+ currently possible without effectively moving tclvfs into Tcl's test
+ suite.
+
+2004-03-31 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/msgcat.n: Clarified message catalog file encodings. [Bug 811457]
+ * library/msgcat/msgcat.tcl: Updated internals to make use of [dict]s
+ to store message catalog data and to use [source -encoding utf-8] to
+ access catalog files. Thanks to Michael Sclenker. [Patch 875055, RFE
+ 811459] Corrected [mcset] to be able to successfully set a translation
+ to the empty string. [mcset $loc $src {}] was incorrectly set the $loc
+ translation of $src back to $src. Also changed [ConvertLocale] to
+ minimally require a non-empty "language" part in the locale value. If
+ not, an error raised prompts [Init] to keep looking for a valid locale
+ value, or ultimately fall back on the "C" locale. [Bug 811461].
+ * library/msgcat/pkgIndex.tcl: Bump to msgcat 1.4.1.
+
+2004-03-30 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclHash.c (HashStringKey): Cleaned up. This function is not
+ faster, but it is a little bit clearer.
+ * generic/tclLiteral.c (HashString): Applied logic from HashObjKey.
+ * generic/tclObj.c (HashObjKey): Rewrote to fix fault which hashed
+ every single-character object to the same hash bucket. The new code is
+ shorter, simpler, clearer, and (happily) faster.
+
+2004-03-30 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c (TEBC): reverting to the previous method for
+ async tests in TEBC, as the new method turned out to be too costly.
+ Async tests now run every 64 instructions.
+
+2004-03-30 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompile.c: New instruction code INST_START_CMD that
+ * generic/tclCompile.h: allows checking the bytecode's validity
+ * generic/tclExecute.c: [Bug 729692] and the interp's readyness
+ * tests/interp.test (18.9): [Bug 495830] before running the command.
+ * tests/proc.test (7.1): It also changes the mechanics of the async
+ * tests/rename.test (6.1): tests in TEBC, doing it now at command
+ start instead of every 16 instructions.
+
+2004-03-30 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclFileName.c: Fix to Windows glob where the pattern is a
+ * generic/tclIOUtil.c: volume relative path or a network share [Bug
+ * tests/fileName.test: 898238]. On windows 'glob' will now return
+ * tests/fileSystem.test: the results of 'glob /foo/bar' and 'glob
+ \\foo\\bar' as 'C:/foo/bar', i.e. a correct absolute path (rather than
+ a volume relative path).
+
+ Note that the test suite does not test commands like
+ 'glob //Machine/Shared/*' (on a network share).
+
+2004-03-30 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclPathObj.c: Fix to filename bugs recently
+ * tests/fileName.test: introduced [Bug 918320].
+
+2004-03-29 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclMain.c (Tcl_Main, StdinProc): Append newline only
+ * tests/basic.test (basic-46.1): to incomplete scripts
+ as part of multi-line script construction. Do not add an extra
+ trailing newline to the complete script. [Bug 833150]
+
+2004-03-28 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompile.c (TclCompileScript): corrected possible segfault
+ when a compilation returns TCL_OUTLINE_COMPILE after having grown the
+ compile environment [Bug 925121].
+
+2004-03-27 Miguel Sofer <msofer@users.sf.net>
+
+ * doc/array.n: added documentation for trace-realted behaviour of
+ 'array get' [Bug 449893]
+
+2004-03-26 Don Porter <dgp@users.sourceforge.net>
+
+ * README: Bumped version number to 8.5a2 to distinguish
+ * tools/tcl.wse.in: HEAD of CVS development from the recent 8.5a1
+ * unix/configure.in: release.
+ * unix/tcl.spec:
+ * win/README.binary:
+ * win/configure.in:
+
+ * unix/configure: autoconf-2.57
+ * win/configure:
+
+2004-03-26 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclPathObj.c: Fix to Windows-only volume relative path
+ * tests/fileSystem.test: normalization. [Bug 923568]. Also fixed
+ another volume relative bug found while testing.
+
+2004-03-24 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclNamesp.c (NsEnsembleImplementationCmd): Fix messed up
+ handling of strncmp result which just happened to work in some libc
+ implementations. [Bug 922752]
+
+2004-03-23 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/StringObj.3: Inverted the sense of the documentation of how the
+ bytes parameter is documented to match behaviour. [Bug 921464]
+
+2004-03-19 Kevin B. Kenny <kennykb@acm.org>
+
+ * compat/strtoll.c:
+ * compat/strtoull.c:
+ * generic/tclIntDecls.h:
+ * generic/tclMain.c:
+ * generic/tclObj.c:
+ * win/tclWinDde.c:
+ * win/tclWinReg.c:
+ * win/tclWinTime.c: Made HEAD build on Windows VC++ again.
+
+2004-03-19 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclIntDecls.h: Made HEAD build on Solaris again by applying
+ fix recommended by Don Porter.
+
+2004-03-18 Reinhard Max <max@suse.de>
+
+ * generic/tclIntDecls.h: Removed TclpTime_t. It wasn't really needed,
+ * generic/tclInt.h: but caused warnings related to
+ * generic/tclInt.decls: strict aliasing with GCC 3.3.
+ * generic/tclClock.c:
+ * generic/tclDate.c:
+ * generic/tclGetDate.y:
+ * win/tclWinTime.c:
+ * unix/tclUnixTime.c:
+
+ * generic/tclNamesp.c: Added temporary pointer variables to work
+ * generic/tclStubLib.c: around warnings related to
+ * unix/tclUnixChan.c: strict aliasing with GCC 3.3.
+
+ * unix/tcl.m4: Removed -Wno-strict-aliasing.
+
+2004-03-18 Daniel Steffen <das@users.sourceforge.net>
+
+ Removed support for Mac OS Classic platform [Patch 918142]
+
+ * README:
+ * compat/string.h:
+ * doc/Encoding.3:
+ * doc/FileSystem.3:
+ * doc/Init.3:
+ * doc/Macintosh.3 (removed):
+ * doc/OpenFileChnl.3:
+ * doc/OpenTcp.3:
+ * doc/SourceRCFile.3:
+ * doc/Thread.3:
+ * doc/clock.n:
+ * doc/exec.n:
+ * doc/fconfigure.n:
+ * doc/file.n:
+ * doc/filename.n:
+ * doc/glob.n:
+ * doc/open.n:
+ * doc/puts.n:
+ * doc/resource.n (removed):
+ * doc/safe.n:
+ * doc/source.n:
+ * doc/tclvars.n:
+ * doc/unload.n:
+ * generic/README:
+ * generic/tcl.decls:
+ * generic/tcl.h:
+ * generic/tclAlloc.c:
+ * generic/tclBasic.c:
+ * generic/tclCmdAH.c:
+ * generic/tclDate.c:
+ * generic/tclDecls.h:
+ * generic/tclFCmd.c:
+ * generic/tclFileName.c:
+ * generic/tclGetDate.y:
+ * generic/tclIOCmd.c:
+ * generic/tclIOUtil.c:
+ * generic/tclInitScript.h:
+ * generic/tclInt.decls:
+ * generic/tclInt.h:
+ * generic/tclIntDecls.h:
+ * generic/tclIntPlatDecls.h:
+ * generic/tclMain.c:
+ * generic/tclMath.h:
+ * generic/tclNotify.c:
+ * generic/tclPathObj.c:
+ * generic/tclPlatDecls.h:
+ * generic/tclPort.h:
+ * generic/tclStubInit.c:
+ * generic/tclTest.c:
+ * generic/tclThreadJoin.c:
+ * library/auto.tcl:
+ * library/init.tcl:
+ * library/package.tcl:
+ * library/safe.tcl:
+ * library/tclIndex:
+ * mac/AppleScript.html (removed):
+ * mac/Background.doc (removed):
+ * mac/MW_TclAppleScriptHeader.h (removed):
+ * mac/MW_TclAppleScriptHeader.pch (removed):
+ * mac/MW_TclBuildLibHeader.h (removed):
+ * mac/MW_TclBuildLibHeader.pch (removed):
+ * mac/MW_TclHeader.h (removed):
+ * mac/MW_TclHeader.pch (removed):
+ * mac/MW_TclHeaderCommon.h (removed):
+ * mac/MW_TclStaticHeader.h (removed):
+ * mac/MW_TclStaticHeader.pch (removed):
+ * mac/MW_TclTestHeader.h (removed):
+ * mac/MW_TclTestHeader.pch (removed):
+ * mac/README (removed):
+ * mac/bugs.doc (removed):
+ * mac/libmoto.doc (removed):
+ * mac/morefiles.doc (removed):
+ * mac/porting.notes (removed):
+ * mac/tclMac.h (removed):
+ * mac/tclMacAETE.r (removed):
+ * mac/tclMacAlloc.c (removed):
+ * mac/tclMacAppInit.c (removed):
+ * mac/tclMacApplication.r (removed):
+ * mac/tclMacBOAAppInit.c (removed):
+ * mac/tclMacBOAMain.c (removed):
+ * mac/tclMacChan.c (removed):
+ * mac/tclMacCommonPch.h (removed):
+ * mac/tclMacDNR.c (removed):
+ * mac/tclMacEnv.c (removed):
+ * mac/tclMacExit.c (removed):
+ * mac/tclMacFCmd.c (removed):
+ * mac/tclMacFile.c (removed):
+ * mac/tclMacInit.c (removed):
+ * mac/tclMacInt.h (removed):
+ * mac/tclMacInterupt.c (removed):
+ * mac/tclMacLibrary.c (removed):
+ * mac/tclMacLibrary.r (removed):
+ * mac/tclMacLoad.c (removed):
+ * mac/tclMacMath.h (removed):
+ * mac/tclMacNotify.c (removed):
+ * mac/tclMacOSA.c (removed):
+ * mac/tclMacOSA.r (removed):
+ * mac/tclMacPanic.c (removed):
+ * mac/tclMacPkgConfig.c (removed):
+ * mac/tclMacPort.h (removed):
+ * mac/tclMacProjects.sea.hqx (removed):
+ * mac/tclMacResource.c (removed):
+ * mac/tclMacResource.r (removed):
+ * mac/tclMacSock.c (removed):
+ * mac/tclMacTclCode.r (removed):
+ * mac/tclMacTest.c (removed):
+ * mac/tclMacThrd.c (removed):
+ * mac/tclMacThrd.h (removed):
+ * mac/tclMacTime.c (removed):
+ * mac/tclMacUnix.c (removed):
+ * mac/tclMacUtil.c (removed):
+ * mac/tcltkMacBuildSupport.sea.hqx (removed):
+ * tests/all.tcl:
+ * tests/binary.test:
+ * tests/cmdAH.test:
+ * tests/cmdMZ.test:
+ * tests/fCmd.test:
+ * tests/fileName.test:
+ * tests/fileSystem.test:
+ * tests/interp.test:
+ * tests/io.test:
+ * tests/ioCmd.test:
+ * tests/load.test:
+ * tests/macFCmd.test (removed):
+ * tests/osa.test (removed):
+ * tests/resource.test (removed):
+ * tests/socket.test:
+ * tests/source.test:
+ * tests/unload.test:
+ * tools/cvtEOL.tcl (removed):
+ * tools/genStubs.tcl:
+ * unix/Makefile.in:
+ * unix/README:
+ * unix/mkLinks:
+ * unix/tcl.spec:
+ * win/README.binary:
+ * win/tcl.dsp:
+
+2004-03-17 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/lsearch.n: Improved examples on the advanced capabilities of
+ lsearch (with the right options, set element removal can be done)
+ following discussion on tkchat.
+
+2004-03-16 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/catch.n: Compiled [catch] no longer fails to catch syntax
+ errors. Removed the claims in the documentation that it does.
+ * doc/return.n: Updated example to use [dict merge].
+
+2004-03-16 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/configure, unix/tcl.m4: add -Wno-strict-aliasing for GCC to
+ suppress useless type puning warnings.
+
+2004-03-16 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/file.n: *roff formatting fix. [Bug 917171]
+
+2004-03-15 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinNotify.c: Fixed a mistake where the return value of
+ MsgWaitForMultipleObjectsEx for "a message is in the queue" wasn't
+ accurate. I removed the check on the case result==(WAIT_OBJECT_0 + 1)
+ This was having the error of falling into GetMessage and waiting there
+ by accident, which wasn't alertable through Tcl_AlertNotifier. I'll do
+ some more study on this and try to find-out why.
+
+2004-03-12 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ IMPLEMENTATION OF TIP#163
+ * generic/tclDictObj.c (DictMergeCmd): This is based on work by Joe
+ * tests/dict.test (dict-20.*): English in Tcl [FRQ 745851]
+ * doc/dict.n: but not exactly.
+
+2004-03-10 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclGetDate.y (TclGetDate): Fix so that [clock scan
+ <timeOfDay> -gmt true] uses the GMT base date instead of the local
+ one. [Bug 913513]
+ * tests/clock.test: Added test cases for wrong ISO8601 week number
+ [Bug 500285] and wrong GMT base date [Bug 913513]. Several tests still
+ fail on Windows, and these are actual faults in [clock scan]. Fix is
+ still pending.
+ * generic/tclDate.c: Regenerated.
+
+2004-03-08 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclFileName.c: Fix to 'glob -path' near the root
+ * tests/fileName.test: of the filesystem. [Bug 910525]
+
+2004-03-08 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclParse.c (TclParseInit): Modified TclParseInit so
+ * generic/tclTest.c ([testexprparser]): that Tcl_Parse initialization
+ conforms to documented promised about what fields will not be
+ modified by what Tcl_Parse* routines. [Bug 910595]
+
+2004-03-05 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/configure: Regen.
+ * win/configure.in: Check for define of MWMO_ALERTABLE in winuser.h.
+ * win/tclWinPort.h: If MWMO_ALERTABLE is not defined in winuser.h then
+ define it. This is needed for Mingw.
+
+2004-03-05 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclTest.c: Modified TesteventObjCmd to use a
+ Tcl_QueuePosition in place of an 'int' for the enumerated queue
+ position, to avoid a compiler warning on SGI. [Bug 771960]
+
+2004-03-05 Kevin B. Kenny <kennykb@acm.org>
+
+ * tests/registry.test: Applied fix from [Patch 910174] to make the test
+ for an English-language system include any country code, rather than
+ just English-United States.1252. Thanks to Pat Thoyts for the changes.
+
+2004-03-04 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ * tests/registry.test: Applied fixed from [Bug 766159] to skip two
+ tests on Win98 that depend on a Unicode registry (NT specific).
+
+2004-03-04 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclInt.h (TclParseInit): Factored the common code
+ * generic/tclParse.c (TclParseInit): for initializing a Tcl_Parse
+ * generic/tclParseExpr.c: struct into one routine.
+
+2004-03-04 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ * library/reg/pkgIndex.tcl: Added TIP #100 support to the
+ * win/tclWinReg.c: registry package [patch 903831]
+ This provides a Windows test of the TIP #100 mechanism and a sample to
+ show how unloading an extension can be done.
+
+2004-03-04 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * unix/dltest/pkgua.c: Fix minor syntax problems. [Bug 909288]
+
+2004-03-03 Jeff Hobbs <jeffh@ActiveState.com>
+
+ *** 8.5a1 TAGGED FOR RELEASE ***
+
+ * changes: updated for 8.5a1
+
+2004-03-03 David Gravereaux <davygrvy@pobox.com>
+
+ * win/makefile.vc: default environment variable for VC++ is %MSDevDir%
+ not %MSVCDir%, although vcvars32.bat sets both.
+
+ * win/tclWinNotify.c (Tcl_WaitForEvent) : Allows an idling notifier to
+ service "Asynchronous Procedure Calls" from its wait state. Only
+ useful for extension authors who decide they might want to try
+ "completion routines" with WriteFileEx(), as an example. From
+ experience, I recommend that "completion ports" should be used instead
+ as the execution of the callbacks are more managable.
+
+2004-03-01 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * README: update patchlevel to 8.5a1
+ * generic/tcl.h:
+ * tools/tcl.wse.in, tools/tclSplash.bmp:
+ * unix/configure, unix/configure.in, unix/tcl.spec:
+ * win/README.binary, win/configure, win/configure.in:
+
+ * unix/tcl.m4: update HP-11 build libs setup
+
+2004-03-01 Don Porter <dgp@users.sourceforge.net>
+
+ * unix/tcl.m4 (SC_CONFIG_CFLAGS): Allow 64-bit enabling on
+ IRIX64-6.5* systems. [Bug 218561]
+ * unix/configure: autoconf-2.57
+
+ * generic/tclTrace.c (TclCheckInterpTraces): The TIP 62
+ * generic/tclTest.c (TestcmdtraceCmd): implementation introduced a
+ * tests/trace.test (trace-29.10): bug by testing the CallFrame
+ level instead of the iPtr->numLevels level when deciding what traces
+ created by Tcl_Create(Obj)Trace to call. Added test to expose the
+ error, and made fix. [FRQ 462580]
+
+2004-02-28 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * tests/fileSystem.test: fix to Tcl Bug 905163.
+ * tests/fileName.test: fix to Tcl Bug 904705.
+
+ * doc/{various}.n: removed 'the the' typos.
+
+2004-02-26 Daniel Steffen <das@users.sourceforge.net>
+
+ * macosx/Makefile: fixed copyright year in Tcl.framework Info.plist
+
+2004-02-25 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/basic.test: Made several tests more robust to the
+ * tests/cmdMZ.test: list-quoting of path names that might contain
+ * tests/exec.test: Tcl-special chars like { or [. Should help us
+ * tests/io.test: sort out [Bug 554068]
+ * tests/pid.test:
+ * tests/socket.test:
+ * tests/source.test:
+ * tests/unixInit.test:
+
+2004-02-25 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclLoad.c (Tcl_LoadObjCmd): Missing dereference caused
+ segfault with non-loadable extension. [Bug 904307]
+
+ * unix/tclUnixChan.c (TcpGetOptionProc): Stop memory leak with very
+ long hostnames. [Bug 888777]
+
+2004-02-25 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ * win/tclWinDde.c: Removed some gcc warnings - except for the
+ -Wconversion warning for GetGlobalAtomName. gcc is just wrong about
+ this.
+
+2004-02-24 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ IMPLEMENTATION OF TIP#100 FROM GEORGIOS PETASIS
+ * generic/tclLoad.c (Tcl_UnloadObjCmd): Implementation.
+ * tests/unload.test: Test suite.
+ * unix/dltest/pkgua.c: Helper for test suite.
+ * doc/unload.n: Documentation.
+ Also assorted changes (mostly small) to several other files.
+
+2004-02-23 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/regc_locale.c (cclass): Buffer was having its size reset
+ instead of being released => memleak. [Bug 902562]
+
+2004-02-21 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclLoad.c (Tcl_LoadObjCmd): Fixed memory leak due to an
+ improper error exit route.
+
+2004-02-20 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinSock.c (SocketThreadExitHandler): Don't call
+ TerminateThread when WaitForSingleObject returns a timeout.
+ Tcl_Finalize called from DllMain will pause all threads. Trust that
+ the thread will get the close notice at a later time if it does ever
+ wake up before being cleaned up by the system anyway.
+
+2004-02-17 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/tcltest.n:
+ * library/tcltest/tcltest.tcl: Changed -verbose default value to
+ {body error} so that detailed information on unexpected errors in
+ tests is provided by default, even after the fix for [Bug 725253]
+
+2004-02-17 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * tests/unixInit.test (unixInit-7.1):
+ * unix/tclUnixInit.c (TclpInitPlatform): ensure the std fds exist to
+ prevent crash condition [Bug 772288]
+
+2004-02-17 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclCompCmds.c (TclCompileSwitchCmd): Bozo mistake in memory
+ releasing order when in an error case. [Bug 898910]
+
+2004-02-16 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclTrace.c (TclTraceExecutionObjCmd)
+ (TclTraceCommandObjCmd): fix possible mem leak in trace info.
+
+2004-02-12 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/tclWinInit.c (AppendEnvironment): Use the tail component of the
+ passed in lib path instead of just blindly using lib+4. That worked
+ when lib was "lib/..." but fails for other values. Thanks go to
+ Patrick Samson for pointing this out.
+
+2004-02-10 David Gravereaux <davygrvy@pobox.com>
+
+ * win/nmakehlp.c: better macro grepping logic.
+
+2004-02-07 David Gravereaux <davygrvy@pobox.com>
+
+ * win/makefile.vc:
+ * win/rules.vc:
+ * win/tcl.rc:
+ * win/tclsh.rc: Added an 'unchecked' option to the OPTS macro so a
+ core built with symbols can be linked to the non-debug enabled C
+ run-time. As per discussion with Kevin Kenny. Called like this:
+
+ nmake -af makefile.vc OPTS=unchecked,symbols
+
+ This clarifies the meaning of the 'g' naming suffix to mean only that
+ the binary requires the debug enabled C run-time. Whether the binary
+ contains symbols or not is a different condition.
+
+2004-02-06 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/clock.n: Removed reference to non-existent [file ctime].
+
+2004-02-05 David Gravereaux <davygrvy@pobox.com>
+
+ * docs/tclvars.n: Added clarification of the tcl_platform(debug) var
+ that it only refers to the flavor of the C run-time, and not whether
+ the core contains symbols.
+
+2004-02-05 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclFileName.c (SkipToChar): Corrected CONST and type-casting
+ issues that caused compiler warnings.
+
+2004-02-04 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCmdAH.c (StoreStatData): Removed improper refcount
+ decrement of the varName parameter. This error was causing segfaults
+ following test cmdAH-28.7.
+
+ * library/tcltest/tcltest.tcl: Corrected references to non-existent
+ $name variable in [cleanupTests]. [Bug 833637]
+
+2004-02-03 Don Porter <dgp@users.sourceforge.net>
+
+ * library/tcltest/tcltest.tcl: Corrected parsing of single command
+ line argument (option with missing value) [Bug 833910]
+ * library/tcltest/pkgIndex.tcl: Bump to version 2.2.5.
+
+2004-02-02 David Gravereaux <davygrvy@pobox.com>
+
+ * generic/tclIO.c (Tcl_Ungets): Fixes improper filling of the channel
+ buffer. This is the buffer before the splice. [Bug 405995]
+
+2004-02-01 David Gravereaux <davygrvy@pobox.com>
+
+ * tests/winPipe.test: more pass-thru commandline verifications.
+ * win/tclWinPipe.c (BuildCommandLine): Special case quoting for '{'
+ not required by the c-runtimes's parse_cmdline().
+ * win/tclAppInit.c: Removed our custom setargv() in favor of the work
+ provided by the c-runtime. [Bug 672938]
+
+ * win/nmakehlp.c: defensive techniques to avoid static buffer
+ overflows and a couple envars upsetting invokations of cl.exe and
+ link.exe. [Bug 885537]
+
+ * tests/winPipe.test: Added proof that BuildCommandLine() is not doing
+ the "N backslashes followed a quote -> insert N * 2 + 1 backslashes
+ then a quote" rule needed for the crt's parse_cmdline().
+ * win/tclWinPipe.c: Fixed BuildCommandLine() to pass the new cases.
+
+2004-01-30 David Gravereaux <davygrvy@pobox.com>
+
+ * win/makefile.vc: Use the -GZ compiler switch when building for
+ symbols. This is supposed to emulate the release build better to avoid
+ hiding problems that only show themselves in a release build.
+
+2004-01-29 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclPathObj.c: fix to [Bug 883143] in file normalization
+
+2004-01-29 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * doc/file.n:
+ * generic/tclFCmd.c
+ * generic/tclTest.c
+ * library/init.tcl
+ * mac/tclMacFile.c
+ * tests/fileSystem.test: fix to [Bug 886352] where 'file copy -force'
+ had inconsistent behaviour wrt target files with insufficient
+ permissions, particular from vfs->native fs. Behaviour of '-force' is
+ now always consistent (and now consistent with behaviour of 'file
+ delete -force'). Added new tests and documentation and cleaned up the
+ 'simplefs' test filesystem.
+
+ * generic/tclIOUtil.c
+ * unix/tclUnixFCmd.c
+ * unix/tclUnixFile.c
+ * win/tclWinFile.c: made native filesystems more robust to C code
+ which asks for mount lists.
+
+ * generic/tclPathObj.c: fix to [Bug 886607] removing warning/error
+ with some compilers.
+
+2004-01-28 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclObj.c (SetBooleanFromAny): Rewrite to do more efficient
+ string->bool conversion.
+ Many other minor whitespace/style fixes to this file too.
+
+2004-01-27 David Gravereaux <davygrvy@pobox.com>
+
+ * win/nmakehlp.c: Use '.\nul' as the sourcefile name instead of 'nul'
+ so VC 5.2 doesn't try searching the path for it and failing with a
+ possible dialogbox popping up about having to add a CD to an empty
+ drive. Also added a SetErrorMode() call to disable any dialogs that
+ cl.exe or link.exe might create. [Bug 885537]
+
+2004-01-22 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * doc/file.n: clarified documentation of 'file system' [Bug 883825]
+ * tests/fCmd.test: improved test result in failure case.
+
+2004-01-22 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * tests/fileSystem.test: 3 new tests
+ * generic/tclPathObj.c: fix to [Bug 879555] in file normalization.
+ * doc/filename.n: small clarification to Windows behaviour with
+ filenames like '.....', 'a.....', '.....a'.
+
+ * generic/tclIOUtil.c: slight improvement to native cwd caching on
+ Windows.
+
+2004-01-21 David Gravereaux <davygrvy@pobox.com>
+
+ * doc/Panic.3: Mentions of 'panic' and 'panicVA' removed from the
+ documentation.
+
+2004-01-21 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * doc/FileSystem.3:
+ * generic/tcl.decls:
+ * generic/tclCmdAH.c
+ * generic/tclDecls.h
+ * generic/tclFCmd.c
+ * generic/tclFileName.c
+ * generic/tclFileSystem.h
+ * generic/tclIOUtil.c
+ * generic/tclInt.decls
+ * generic/tclInt.h
+ * generic/tclIntDecls.h
+ * generic/tclPathObj.c
+ * generic/tclStubInit.c
+ * generic/tclTest.c
+ * mac/tclMacFile.c
+ * tests/fileName.test
+ * tests/fileSystem.test
+ * tests/winFCmd.test
+ * unix/tclUnixFile.c
+ * win/tclWin32Dll.c
+ * win/tclWinFCmd.c
+ * win/tclWinFile.c
+ * win/tclWinInt.h
+
+ Three main issues accomplished: (1) cleaned up variable names in the
+ filesystem code so that 'pathPtr' is used throughout. (2) applied a
+ round of filesystem optimisation with better handling and caching of
+ relative and absolute paths, requiring fewer conversions. (3)
+ clarifications to the documentation, particularly regarding the
+ acceptable refCounts of objects. Some new tests added. Tcl benchmarks
+ show a significant improvement over 8.4.5, and on Windows typically a
+ small improvement over 8.3.5 (Unix still appears to require
+ optimisation). TCL_FILESYSTEM_VERSION_2 introduced, but for internal
+ use only. There should be no public incompatibilities from these
+ changes. Thanks to dgp for extensive testing.
+
+2004-01-19 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinPipe.c (Tcl_WaitPid): Fixed a thread-safety problem with
+ the process list. The delayed cut operation after the wait was going
+ stale by being outside the list lock. It now cuts within the lock and
+ does a locked splice for when it needs to instead. [Bug 859820]
+
+2004-01-18 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclCompile.c, generic/tclCompile.h: Two new opcodes,
+ INST_LIST_INDEX_IMM and INST_LIST_RANGE_IMM, that have operand(s) of
+ new type OPERAND_IDX4 which represents indexes into things like lists
+ (and perhaps other things eventually.)
+ * generic/tclExecute.c (TclExecuteByteCode): Implementation of the new
+ opcodes. INST_LIST_INDEX_IMM does a simple [lindex] with either front-
+ or end-based simple indexing. INST_LIST_RANGE_IMM does an [lrange]
+ with front- or end-based simple indexing for both the reference to the
+ first and last items in the range.
+ * generic/tclCompCmds.c (TclCompileLassignCmd): Generate bytecode for
+ the [lassign] command.
+
+2004-01-17 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinInit.c: added #pragma comment(lib, "advapi32.lib") when
+ compiling under VC++ so we don't need to specify it when linking.
+
+2004-01-17 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclCmdIL.c (Tcl_LassignObjCmd): Add more shimmering
+ protection for when the list is also one of the variables.
+
+ BASIC IMPLEMENTATION OF TIP#57
+ * generic/tclCmdIL.c (Tcl_LassignObjCmd): Implementation of the
+ [lassign] command that takes full advantage of Tcl's object API.
+ * doc/lassign.n: New file documenting the command.
+ * tests/cmdIL.test (cmdIL-6.*): Test suite for the command.
+
+2004-01-15 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinReg.c: Placed the requirement for advapi.lib into the
+ object file itself with #pragma comment (lib, ...) when built with
+ VC++. This will simplify linking for users of the static library.
+
+ * win/rules.vc: Added new 'fullwarn' to the CHECKS commandline macro;
+ sets $(FULLWARNINGS).
+
+ * win/makefile.vc: Removed 'advapi.lib' from $(baselibs). Added new
+ logic to crank-up the warning levels for both compile and link when
+ $(FULLWARNINGS) is set. Some clean-up with how the resource files are
+ built and how -DTCL_USE_STATIC_PACKAGES is sent when compiling the
+ shells.
+
+ * win/tclAppInit.c: Small change in how TCL_USE_STATIC_PACKAGES is
+ used.
+
+ * win/tcl.rc:
+ * win/tclsh.rc: Some clean-up with how the resource files are built.
+ Fixed 'OriginalFilename' problem that still thought a debug suffix was
+ still 'd', now is 'g'.
+
+2004-01-14 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclDictObj.c (TraceDictPath, DictExistsCmd): Adjusted
+ behaviour of [dict exists] so a failure to look up a dictionary along
+ the path of dicts doesn't trigger an error. This is how it was
+ documented to behave previously... [Bug 871387]
+
+ * generic/tclDictObj.c: Assorted dict fixes from Peter Spjuth relating
+ to [Bug 876170].
+ (SetDictFromAny): Make sure that lists retain their ordering even when
+ converted to dictionaries and back.
+ (TraceDictPath): Correct object reference count handling!
+ (DictReplaceCmd, DictRemoveCmd): Stop object leak.
+ (DictIncrCmd,DictLappendCmd,DictAppendCmd,DictSetCmd,DictUnsetCmd):
+ Simpler handling of reference counts when assigning to variables.
+ * tests/dict.test (dict-19.2): Memory leak stress test
+
+2004-01-13 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCmdMZ.c (Tcl_SwitchObjCmd): Silence compiler warnings.
+
+ Patch 876451: restores performance of [return]. Also allows forms such
+ as [return -code error $msg] to be bytecompiled.
+
+ * generic/tclInt.h: Factored Tcl_ReturnObjCmd() into two pieces:
+ * generic/tclCmdMZ.c: TclMergeReturnOptions(), which can parse the
+ options to [return], check their validity, and create the
+ corresponding return options dictionary, and TclProcessReturn(), which
+ takes that return options dictionary and performs the [return]
+ operation.
+
+ * generic/tclCompCmds.c: Rewrote TclCompileReturnCmd() to call
+ TclMergeReturnOptions() at compile time so the return options
+ dictionary is computed at compile time (when it is fully known). The
+ dictionary is pushed on the stack along with the result, and the code
+ and level values are included in the bytecode as operands. Also
+ supports optimized compilation of un-[catch]ed [return]s from procs
+ with default options into the INST_DONE instruction.
+
+ * generic/tclExecute.c: Rewrote INST_RETURN instruction to retrieve
+ the code and level operands, pop the return options from the stack,
+ and call TclProcessReturn() to perform the [return] operation.
+
+ * generic/tclCompile.h: New utilities include TclEmitInt4 macro
+ * generic/tclCompile.c: and TclWordKnownAtCompileTime().
+
+ End Patch 876451.
+
+ * generic/tclFileName.c (Tcl_GlobObjCmd): Latest changes to management
+ of the interp result by Tcl_GetIndexFromObj() exposed improper interp
+ result management in the [glob] command procedure. Corrected by
+ adopting the Tcl_SetObjResult(Tcl_NewStringObj) pattern. This stopped
+ a segfault in test filename-11.36. [Bug 877677]
+
+2004-01-13 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclIndexObj.c (Tcl_GetIndexFromObjStruct, Tcl_WrongNumArgs):
+ Create fresh objects instead of using the one currently in the
+ interpreter, which isn't guaranteed to be fresh and unshared. The cost
+ for the core will be minimal because of the object cache, and this
+ fixes [Bug 875395].
+
+2004-01-12 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompExpr.c (CompileLandOrLorExpr): cosmetic changes.
+
+2004-01-12 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompExpr.c (CompileLandOrLorExpr): new logic, fewer
+ instructions. As a side effect, the instructions INST_LOR and
+ INST_LAND are now never used.
+ * generic/tclExecute.c (INST_JUMP*): small optimisation; fix a bug in
+ debug code.
+
+2004-01-11 David Gravereaux <davygrvy@pobox.com>
+
+ * win/tclWinThrd.c (Tcl_ConditionNotify): condPtr must be dereferenced
+ to see if there are waiters else uninitialized datum is manipulated.
+ [Bug 849007 789338 745068]
+
+2004-01-09 David Gravereaux <davygrvy@pobox.com>
+
+ * generic/tcl.h: Renamed and deprecated #defines moved to within the
+ #ifndef TCL_NO_DEPRECATED block. This allows us to build Tcl to check
+ for deprecated functions in use, such as panic() and Tcl_Ckalloc(). By
+ request from DKF. Extensions that build with -DTCL_NO_DEPRECATED now
+ have these macros as restricted.
+ ***POTENTIAL INCOMPATIBILITY***
+
+ * win/makefile.vc:
+ * win/rules.vc: Added -DTCL_NO_DEPRECATED usage to makefile.vc.
+ Called like this: nmake -af makefile.vc CHECKS=nodep
+
+2004-01-09 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclIOUtil.c: fix to infinite loop in TclFinalizeFilesystem
+ [Bug 873311]
+
+ ******************************************************************
+ *** 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.2005 b/ChangeLog.2005
new file mode 100644
index 0000000..0d1d7cf
--- /dev/null
+++ b/ChangeLog.2005
@@ -0,0 +1,3822 @@
+2005-12-30 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclStubLib.c: Corrected a typo in "missing Stubs table
+ pointer."
+
+2005-12-27 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tcl.decls: Destubbed TclTomMathInitializeStubs - it is in
+ * generic/tcl.h: the stub library, not the main shared
+ * generic/tclBasic.c: library. Exported Tcl_InitBignumFromDouble.
+ * generic/tclExecute.c:
+ * generic/tclInt.h:
+ * generic/tclStrToD.c:
+
+ * generic/tclDecls.h:
+ * generic/tclStubLib.c:
+ * generic/tclStubInit.c: Regenerated.
+
+ * generic/clock.tcl: Reverted to using the time zone abbreviation and
+ not its name to "stop the bleeding" on [Bug 1386377]. This is *not* a
+ good long-term solution, but there may not be one.
+
+ * libtommath/bn_mp_sqrt.c: Improved the initial approximation to the
+ square root, roughly doubling the speed of the routine. (This is a
+ local change that needs to be communicated to Tom.)
+
+ * win/Makefile.in: Corrected a bug where tommath_class.h and
+ tommath_superclass.h were not installed, making it impossible for
+ client code to compile against the tommath stubs.
+
+ * library/tzdata: Updated to Olson's tzdata2005r. (Latest changes to
+ Daylight Saving Time in Canada, plus redefinition of the Posix-style
+ zones [e.g., EST5EDT] to be locale-independent.)
+
+ * libtommath: Updated to Tom St.Denis's release 0.37.
+
+2005-12-20 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * generic/tclThreadAlloc.c (Tcl_GetMemoryInfo): Format values as longs
+ and not ints, so they are less likely to wrap on 64-bit machines.
+
+2005-12-19 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCmdMZ.c: Modified [string is double] to use
+ * tests/string.test: TclParseNumber() to parse trailing whitespace.
+ Ensures consistency, and makes it easier to cleanup after invalid
+ internal reps left behind by parsing [Bugs 1360532 1382287].
+
+ * generic/tclParseExpr.c: Added TCL_PARSE_NO_WHITESPACE to
+ * generic/tclScan.c: TclParseNumber() calls since [scan] and [expr]
+ * tests/scan.test: parsing don't want spaces in parsed numbers.
+
+ * generic/tclInt.h: Added TCL_PARSE_NO_WHITESPACE flag to the
+ * generic/tclStrToD.c: TclParseNumber() interface.
+
+2005-12-19 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * doc/Tcl.n: Clarify what is going on in variable substitution
+ following thread on comp.lang.tcl.
+
+2005-12-18 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * generic/tclCompCmds.c (TclCompileDictCmd): Ensure that we only do an
+ 'endCatch' when there's a preceding 'beginCatch'. [Bug 1382528] Many
+ thanks to Anton Kovalenko for finding this and pointing out that it was
+ a catch stack handling problem!
+
+2005-12-14 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tclIOUtil.c: workaround gcc warning "comparison is always
+ * generic/tclTest.c: false due to limited range of data type".
+
+ * macosx/Tcl.xcode/project.pbxproj:
+ * macosx/Tcl.xcodeproj/project.pbxproj:
+ * unix/Makefile.in: add new tclTomMath* files.
+
+ * generic/tclBasic.c: replace panic with Tcl_Panic.
+
+2005-12-13 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tcl.decls: Added changes to export an additional stubs
+ * generic/tclBasic.c: table to represent the 'libtommath' routines
+ * generic/tclDecls.h: that Tcl uses and export them to callers.
+ * generic/tclInt.decls: Reran 'genstubs'
+ * generic/tclInt.h:
+ * generic/tclIntDecls.h:
+ * generic/tclIntPlatDecls.h:
+ * generic/tclStubInit.c:
+ * generic/tclStubLib.c:
+ * generic/tclTomMath.decls:
+ * generic/tclTomMath.h:
+ * generic/tclTomMathDecls.h:
+ * generic/tclTomMathInterface.c:
+ * generic/tommath.h:
+ * tools/fix_tommath_h.tcl:
+ * unix/Makefile.in:
+ * win/Makefile.in:
+ * win/makefile.vc:
+
+ * generic/tclClock.c: Made changes to silence a number of compiler
+ * generic/tclIO.c: warnings when building with mingw.
+ * generic/tclIORChan.c:
+ * generic/tclLink.c:
+ * generic/tclListObj.c:
+ * generic/tclObj.c:
+ * generic/tclParseExpr.c:
+ * generic/tclProc.c:
+ * generic/tclTimer.c:
+ * win/tclWinChan.c:
+ * win/tclWinConsole.c:
+ * win/tclWinDde.c:
+ * win/tclWinFCmd.c:
+ * win/tclWinFile.c:
+ * win/tclWinReg.c:
+ * win/tclWinSock.c:
+
+2005-12-13 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * generic/tclExecute.c (TEBC:DICT_FIRST,DICT_DONE): Only decrease the
+ references to the dictionary once the iteration completes. Do this by
+ storing the dict in the iterator context variable. [Bug 1379349] Thanks
+ to Ulrich Ring and Tobias Hippler for finding this.
+
+2005-12-12 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/tcl.m4, unix/configure: Fix sh quoting error reported in
+ bash-3.1+ [Bug 1377619] (schafer)
+
+2005-12-12 Kevin B. Kenny <kennykb@acm.org>
+
+ * doc/mathfunc.n: Changed two examples from the incorrect 'tcl::math::'
+ to 'tcl::mathfunc::' [Bug 1378818]
+
+2005-12-09 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/configure: Regen.
+ * win/tcl.m4 (SC_CONFIG_CFLAGS): Define MACHINE for gcc builds. The
+ lack of a definition of this variable in the manifest file was causing
+ a runtime error in wish built with gcc.
+
+2005-12-09 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * tests/lsearch.test (lsearch-10.8..10): If the -start is off the end,
+ * generic/tclCmdIL.c (Tcl_LsearchObjCmd): searching should find nothing
+ at all. [Bug 1374778]
+
+2005-12-08 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/Makefile.in, win/makefile.vc: Add Win x64 and CE build support
+ * win/tcl.m4, win/configure: CE still requires C code fixes.
+
+ * generic/tcl.h: use struct __stat64 (not _stat64) for MSC_VER >= 1400
+ (i.e. latest Platform SDK).
+
+2005-12-07 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * doc/socket.n: Cross-referenced the socket documentation better to the
+ fconfigure documentation on the topic of asynch sockets.
+ * doc/fconfigure.n: Added keyword to documentation of -blocking option
+ so that people looking for "asynch" can find it as well.
+
+2005-12-05 Daniel Steffen <das@users.sourceforge.net>
+
+ * unix/tclUnixPort.h (Darwin): fix incorrect __DARWIN_UNIX03 configure
+ overrides that were originally copied from Darwin CVS (rdar://3693001)
+
+2005-12-05 Kevin B. Kenny <kennykb@acm.org>
+
+ * tools/tclZIC.tcl: Updated to reflect changes in calling sequence when
+ GetJulianDateFromEraYearMonthDay moved to C.
+ * library/tzdata: Regenerated from Olson's tzdata2005p.tar.gz - the
+ 'systemv' changes appear not to affect Tcl's processing of the dates.
+
+2005-12-05 Daniel Steffen <das@users.sourceforge.net>
+
+ * unix/configure.in: move check for fts API to configure.in and run it
+ * unix/tcl.m4: on all platforms, since Linux glibc2 and *BSDs
+ also have this; using fts is more efficient than a recursive
+ opendir/readdir.
+ * unix/tclUnixFCmd.c (TraverseUnixTree): add support to fts code for
+ platforms with stat64.
+ * unix/configure:
+ * unix/tclConfig.h.in: regen.
+
+2005-12-05 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/configure: Use fts file API on Darwin if available.
+ * unix/tcl.m4: Addresses file delete issues in readdir noted
+ * unix/tclUnixFCmd.c: in [Bug 1034337]. (steffen)
+ Remove redundant stat call for each file in DoCopyFile. (steffen)
+
+2005-12-02 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclClock.c: Moved a tiny bit more of [clock format] from run
+ * library/clock.tcl: time to compile time, and fixed a l10n bug in the
+ process. [Bug 1371446]. Also, conditoned the call to SetupTimeZone to
+ speed the common case where TZData($timezone) already exists, and
+ achieved a puny speedup by making ::tcl::clock::getenv not throw
+ errors.
+ * unix/Makefile.in: Made some changes to support a 'make' command that
+ is present on some antiquated versions of Solaris.
+
+2005-12-01 Kevin B. Kenny <kennykb@acm.org>
+
+ * library/clock.tcl: Continued rationalizing the code, eliminating
+ numerous redundant [mc] calls. Added another time boost by precompiling
+ a [::format] command to do the bulk of the work of [clock format].
+
+2005-12-01 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * unix/Makefile.in: Add remaining dependency info. While automated
+ maintenance of this information would be good, having it at all is much
+ better than a poke in the eye with a sharp stick...
+
+2005-12-01 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tclClock.c: fix warning.
+
+ * unix/tcl.m4 (Darwin): fix error when MACOSX_DEPLOYMENT_TARGET unset
+ * unix/configure: regen.
+
+2005-11-30 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * unix/Makefile.in: Add dependency information relating to tclCompile.h
+ since when the list of opcodes changes it is usually useful to rebuild
+ everything that depends on it (but which is nonetheless a small
+ fraction of the total set of Tcl source files).
+
+ ***POTENTIAL INCOMPATIBILITY*** for bytecode savers/loaders. See below
+
+ * generic/tclCompCmds.c (TclCompileSwitchCmd): Arrange for very simple
+ [switch] invokations to be compiled into hash lookups into jump tables;
+ only a very specific kind of [switch] can be safely compiled this way,
+ but that happens to be the most common kind. This makes around 5-10%
+ difference to the speed of execution of clock.test.
+ * generic/tclExecute.c (TEBC:INST_JUMP_TABLE): New instruction to allow
+ for jumps to locations looked up in a hashtable. Requires a new AuxData
+ type, tclJumptableInfoType (supported by the functions DupJumptableInfo
+ and FreeJumptableInfo in tclCompCmds.c) so anything that saves bytecode
+ containing this *must* be updated!
+
+2005-11-30 Kevin Kenny <kennykb@acm.org>
+
+ * generic/tclClock.c: Fixed a bad refcount in previous commit that led
+ to a corrupted heap. Also silenced a warning that some compilers gave
+ about the excessively long constant for JULIAN_SEC_POSIX_EPOCH. Also
+ fixed a bug where [clock format] would fail in the :localtime zone for
+ times before the Posix Epoch. Thanks to Miguel Sofer for pointing out
+ all of these. Also rationalized the code a little bit by moving parts
+ of [clock scan] into C, eliminating some code that was duplicated in
+ the C and Tcl layers.
+
+2005-11-29 Kevin Kenny <kennykb@acm.org>
+
+ * generic/tclBasic.c: Moved a big part of [clock format] down
+ * generic/tclClock.c: to the C level in order to make it go faster.
+ * generic/tclInt.h: Preliminary measurements suggest that it
+ * generic/clock.tcl: more than doubles in speed with this change.
+
+2005-11-29 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * generic/tclCmdIL.c (Tcl_LsearchObjCmd): Allow [lsearch -regexp] to
+ process REs that contain backreferences. This expensive mode of
+ operation is only used if the RE would otherwise cause a compilation
+ failure. [Bug 1366683]
+
+2005-11-28 Kevin Kenny <kennykb@acm.org>
+
+ * tools/tclZIC.tcl (convertTimeOfDay): Corrected a typo that caused
+ wrong DST transitions in any time zone where the transition is
+ specified as local Standard Time (as opposed to wall-clock or UTC).
+ (Also updated the code to be bignum-safe.)
+ * tests/clock.test (clock-51.1): Added regression test for the above.
+ * library/tzdata: Updated to Olson's 'tzdata2005o' (changes for Cuba,
+ Nicaragua, Jordan, and Georgia) and regenerated. Thanks to Paul
+ Mackerras for reporting this problem.
+
+2005-11-27 Daniel Steffen <das@users.sourceforge.net>
+
+ * unix/tcl.m4 (Darwin): add 64bit support, check for Tiger copyfile(),
+ add CFLAGS to SHLIB_LD to support passing -isysroot in env(CFLAGS) to
+ configure (flag can't be present twice, so can't be in both CFLAGS and
+ LDFLAGS during configure), don't use -prebind when deploying on 10.4,
+ define TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING (rdar://3171542).
+ (SC_ENABLE_LANGINFO, SC_TIME_HANDLER): add/fix caching, fix obsolete
+ autoconf macros. Sync with tk/unix/tcl.m4.
+
+ * unix/configure.in: fix obsolete autoconf macros, sync gratuitous
+ formatting/ordering differences with tk/unix/configure.in.
+
+ * unix/Makefile.in: add CFLAGS to tclsh/tcltest link to make executable
+ linking the same as during configure (needed to avoid losing any linker
+ relevant flags in CFLAGS, in particular flags that cannot be in
+ LDFLAGS). Avoid concurrent linking of tclsh and compiling of
+ tclTestInit.o or xtTestInit.o during parallel make.
+ (checkstubs, checkdoc, checkexports): dependency and Darwin fixes
+ (dist): add new macosx files.
+
+ * unix/tclLoadDyld.c (TclpDlopen): use NSADDIMAGE_OPTION_WITH_SEARCHING
+ on second NSAddImage only. [Bug 1204237]
+ (TclGuessPackageName): should not be MODULE_SCOPE.
+ (TclpLoadMemory): ppc64 and endian (i386) fixes, add support for
+ loading universal (fat) bundles from memory.
+
+ * unix/tclUnixFCmd.c:
+ * macosx/tclMacOSXFCmd.c: ppc64 and endian (i386) fixes.
+ (TclMacOSXCopyFileAttributes): add support for new Tiger copyfile() API
+ to enable copying of xattrs & ACLs by [file copy].
+
+ * generic/tcl.h: add Darwin specifc configure overrides for TCL_WIDE
+ defines to support fat compiles of ppc and ppc64 at the same time,
+ (replaces Darwin CVS fix by emoy, rdar://3693001). add/correct location
+ of version numbers in macosx files.
+
+ * generic/tclInt.h: clarify fat compile comment.
+
+ * unix/tclUnixPort.h: add Darwin specifc configure overrides to support
+ fat compiles, where configure runs only once for multiple architectures
+ (replaces Darwin CVS fix by emoy, rdar://3693001).
+
+ * macosx/tclMacOSXBundle.c:
+ * macosx/tclMacOSXNotify.c:
+ * unix/tclUnixNotfy.c:
+ * unix/tclUnixPort.h: fix #include order to support compile time
+ override of HAVE_COREFOUNDATION in tclUnixPort.h when building for
+ ppc64
+
+ * macosx/Tcl.pbproj/default.pbxuser (new file):
+ * macosx/Tcl.pbproj/jingham.pbxuser:
+ * macosx/Tcl.pbproj/project.pbxproj:
+ * macosx/Tcl.xcode/default.pbxuser (new file):
+ * macosx/Tcl.xcode/project.pbxproj (new file):
+ * macosx/Tcl.xcodeproj/default.pbxuser (new file):
+ * macosx/Tcl.xcodeproj/project.pbxproj (new file): new/updated
+ projects for Xcode 2.2 on 10.4, Xcode 1.5 on 10.3 & ProjectBuilder on
+ 10.2, with native tcltest targets and support for universal (fat)
+ compiles.
+
+ * macosx/README: clarification/cleanup, document new Xcode projects and
+ universal (fat) builds via CFLAGS (i.e. all of ppc ppc64 i386 at once).
+
+ * unix/Makefile.in:
+ * unix/aclocal.m4:
+ * unix/configure.in:
+ * unix/dltest/Makefile.in:
+ * macosx/configure.ac (new file): add support for inclusion of
+ unix/configure.in by macosx/configure.ac, allows generation of a config
+ headers enabled configure script in macosx (required by Xcode
+ projects).
+
+ * macosx/GNUmakefile: rename from Makefile to avoid overwriting by
+ configure run in tcl/macosx, add support for reusing configure cache,
+ build target fixes, remove GENERIC_FLAGS override now handled by
+ tcl.m4.
+
+ * generic/tcl.decls: add Tcl_Main declaration as comment to avoid
+ 'checkstubs' target complaining about it missing from stubs.
+
+ * generic/regex.h:
+ * generic/tclDate.c:
+ * generic/tclEnv.c:
+ * generic/tclGetDate.y:
+ * generic/tclIOUtil.c:
+ * generic/tclObj.c:
+ * generic/tclStubInit.c:
+ * generic/tclStubLib.c:
+ * generic/tclPathObj.c:
+ * generic/tclThreadAlloc.c:
+ * generic/tclThreadStorage.c:
+ * generic/tclTrace.c:
+ * generic/tclVar.c:
+ * generic/tommath.h:
+ * tools/fix_tommath_h.tcl:
+ * unix/tclUnixFCmd.c: ensure externally visible symbols not contained
+ in stubs table are declared as MODULE_SCOPE (or as static if not used
+ outside of own source file). These changes allow 'make checkstubs' to
+ complete without error on Darwin with gcc 4.
+
+ * generic/rege_dfa.c (getvacant):
+ * generic/regexec.c (cfind):
+ * generic/tclCompExpr.c (CompileSubExpr):
+ * generic/tclNamesp.c (NamespaceEnsembleCmd):
+ * unix/tclUnixChan.c (TclUnixWaitForFile): initialise variables to
+ silence gcc 4 warnings.
+
+ * generic/tclExecute.c (TclExecuteByteCode): fix unused variable
+ warning when NO_WIDE_TYPE is defined.
+
+ * generic/regguts.h: only #define NDEBUG if not already #defined.
+
+ * unix/tclUnixNotfy.c:
+ * macosx/tclMacOSXNotify.c: sync whitespace & comments.
+
+ * unix/tclUnixPort.h:
+ * win/tclWinPort.h: remove declaration of obsolete&unused TclpMutex
+ API.
+
+ * unix/configure:
+ * unix/tclConfig.h.in: regen.
+
+2005-11-21 Andreas Kupries <andreask@activestate.com>
+
+ * unix/Makefile.in (install-libraries): Updated Makefile to new
+ * win/Makefile.in (install-libraries): version of the http package.
+ This fixes the ifneeded/provide mismatch reported when trying to
+ require http. Should we maybe try to automatically extract the version
+ number from the http code to prevent future breakage ?
+
+ This follows the update of the version number by dgp on Nov 15 (No
+ entry found in the ChangeLog).
+
+2005-11-20 Joe English <jenglish@users.sourceforge.net>
+
+ * generic/tclStubLib.c: Don't set tclStubsPtr to 0 when
+ Tcl_PkgRequireEx() fails [Fix for [Bug 1091431] "Tcl_InitStubs failure
+ crashes wish"]
+
+2005-11-18 Miguel Sofer <msofer@users.sf.net>
+
+ * tests/trace.test (trace-34.5): [Bug 1047286], added a second test
+ illustrating the role of "ns in callStack" in the ns's visibility
+ during deletion traces.
+
+2005-11-18 Kevin B. Kenny <kennykb@acm.org>
+
+ * doc/clock.n: Restored several missing lines near the %w format group
+ so that %w and %W are documented with their actual behaviour. [Bug
+ 1359183]
+
+2005-11-18 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclIO.c (TclFinalizeIOSubsystem): preserve statePtr until we
+ retrieve the next statePtr from it.
+
+2005-11-18 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclObj.c (GetBignumFromObj): replace NULL with
+ tclEmptyStringRep to stop memcpy from complaining in a debug build
+ (the corresponding branch is eliminated by the optimiser otherwise).
+
+2005-11-18 Andreas Kupries <andreask@activestate.com>
+
+ * generic/tclIO.c (TclFinalizeIOSubsystem): Applied Pat Thoyts' patch
+ for [Bug 1359094]. This moves the retrieval of the next channel state
+ to the end of the loop, as the called closeproc may close other
+ channels, i.e. modify the list we are iterating, invalidating any
+ pointer retrieved earlier.
+
+2005-11-18 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclListObj.c: Restored the SetListFromAny routine to the
+ * generic/tclObj.c: "list" Tcl_ObjType, and restored the
+ Tcl_RegisterObjType() call for "list". This addresses the needs of some
+ "bridge" extensions to examine whether the Tcl_ObjType of a Tcl_Obj is
+ that of the "list" Tcl_ObjType.
+
+2005-11-18 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * library/http/http.tcl (http::geturl): Improved syntactic validation
+ of URLs, and better error messages in some cases. [Bug 1358369]
+
+2005-11-17 Miguel Sofer <msofer@users.sf.net>
+
+ * tests/namespace.test: fix comment
+
+2005-11-14 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclStrToD.c: More data in the "can't happen" Tcl_Panic to
+ aid debugging.
+
+ * generic/tclBasic.c (CallCommandTraces): Save/restore the interp
+ result during traces to fix [Bug 1355342].
+
+2005-11-13 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclInt.h:
+ * generic/tclNamesp.c:
+ * tests/namespace.test: fix for [Bug 1354540] and [Bug 1355942]. The
+ new tests 7.3-6 and the modified 51.13 fail due to the unrelated [Bug
+ 1355342]
+
+ * tests/trace.test: added tests 20.13-16 for [Bug 1355342]
+
+2005-11-12 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclBasic.c (Tcl_DeleteCommandFromToken):
+ * generic/tclObj.c (Tcl_GetCommandFromObj): more partial fixes for
+ [Bug 1354540] - making sure that cached references to a command being
+ deleted cannot be made reusable by a delete trace.
+
+2005-11-12 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclNamesp.c (Tcl_FindCommand): Do not find commands in dead
+ namespaces on the path. Partial fix for [Bug 1354540].
+
+2005-11-11 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclInt.h: Revised TclParseNumber interface to enable
+ * generic/tclScan.c: revision to the [scan] command implementation
+ * generic/tclStrToD.c: to permit tests scan-4.44,55 to pass again.
+ [Bug 1348067].
+
+2005-11-11 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclBasic.c (Tcl_DeleteCommandFromToken):
+ * generic/tclObj.c (Tcl_GetCommandFromObj): bump the cmd epoch early
+ to insure that cached references to this command are invalidated.
+ Partial fix for [Bug 1352734] - at least insures that namespace-51.13
+ does not cause a panic. The test is still marked as knownbug, pending
+ resolution of what is actually the correct return value ([Bug
+ 1354540])
+
+2005-11-09 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclTimer.c: Changed [after] so that it behaves correctly
+ * tests/timer.test: with negative arguments [Bug 1350293] and
+ arguments that overflow a 32-bit word. [Bug 1350291]
+
+2005-11-08 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/compile.test: Updated tests with changed behavior
+ * tests/execute.test: due to addition of bignums.
+ * tests/expr-old.test:
+ * tests/expr.test:
+ * tests/parseExpr.test:
+ * tests/platform.test:
+ * tests/string.test:
+
+2005-11-08 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/tclUnixFCmd.c (MAX_READDIR_UNLINK_THRESHOLD): reduce to 130
+ based on errors seen on OS X 10.3 with lots of links in a dir.
+ [Bug 1034337 followup]
+
+2005-11-09 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * unix/Makefile.in (gdb-test): Added a new target to make it easier to
+ run the test suite inside a debugger.
+
+2005-11-08 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/compExpr-old.test: Updated tests with changed behavior due
+ to addition of bignums.
+
+ * tests/expr.test: Portable tests expr-46.13-18 [Bug 1341368]
+
+ * generic/tclPkg.c: Corrected inconsistencies in the value returned
+ * tests/pkg.test: by Tcl_PkgRequire(Ex) so that the returned
+ values will always agree with what is stored in the package database.
+ This way repeated calls to Tcl_PkgRequire(Ex) have the same results.
+ Thanks to Hemang Lavana. [Bug 1162286].
+
+2005-11-08 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * generic/tclTrace.c (TraceVarEx): Factor out heart of Tcl_TraceVar2
+ (TclTraceVariableObjCmd,TraceVarProc): Use the new internal API to
+ arrange for the clientData to be cleaned up at the same time as the
+ rest of the main trace record. This simplifies the code a bit at the
+ same time.
+
+2005-11-07 Miguel Sofer <msofer@users.sf.net>
+
+ * tests/trace.test (trace-13.2-4): added tests to detect leak, see [Bug
+ 1348775]. The recently added trace-8.9 test is now 13.4.
+
+2005-11-07 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * tests/dict.test (dict-19.2): arrange for the stress testing code to
+ only stress test the dict code and not the trace code as well. [Bug
+ 1342858]
+
+2005-11-05 Miguel Sofer <msofer@users.sf.net>
+
+ * tests/trace.test (trace-8.9): added test to detect leak, see [Bug
+ 1348775].
+
+2005-11-04 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ * win/tclWinPort.h: Applied [Patch 1267871] by Matt Newman for
+ * win/tclWinPipe.c: extended error code support on Windows.
+ * tests/exec.test: Tests for extended error codes.
+ * generic/tclPipe.c: Permit long codes (platform macros permitting).
+
+2005-11-04 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclBinary.c:
+ * generic/tclCmdAH.c:
+ * generic/tclCmdIL.c:
+ * generic/tclCmdMZ.c:
+ * generic/tclDictObj.c:
+ * generic/tclExecute.c:
+ * generic/tclIOCmd.c:
+ * generic/tclLink.c:
+ * generic/tclTest.c:
+ * generic/tclVar.c: fix for [Bug 1334947]. The functions TclPtrSetVar,
+ Tcl_ObjSetVar2 and Tcl_SetVar2Ex now always consume the newValuePtr
+ argument - i.e., they will free a 0-refCount object if they failed to
+ set the variable. Fixed all callers in the core.
+
+2005-11-04 Kevin Kenny <kennykb@acm.org>
+
+ * generic/tclGetDate.y: Added abbreviations for the Korean
+ * library/clock.tcl: timezone. [Patch 1298737]
+ * generic/tclDate.c: Regenerated.
+
+ * tools/findBadExternals.tcl: Added this script, which locates external
+ symbols that do not begin with 'Tcl' or 'tcl' and hence might be in
+ conflict with other link libraries. Thanks to George Peter Staplin for
+ the idea and the initial version of the script. [Bug 1263012]
+
+ * unix/Makefile.in: Trimmed a bunch of fat out of the tommath/
+ directory in 'make dist'. [RFE 1333318]
+
+ * unix/tcl.m4: Added code to enable [load] on LynxOS. Thanks to
+ heidibr@users.sf.net for the patch. [Bug 1163896]. Removed the last
+ vestiges of GNU dld from the Unix build [RFE 1071992].
+
+ * unix/tclLoadDld.c: Removed.
+ * unix/configure: Regenerated.
+
+2005-11-04 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclInt.h:
+ * generic/tclNamesp.c:
+ * generic/tclVar.c:
+ * tests/trace.test: fix for [Bugs 1338280/1337229]; changed to use the
+ same approach as the 8.4 patch in the ticket (i.e., removed the patch
+ committed on 2005-31-10).
+
+2005-11-03 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ * win/tclWin32Dll.c: Applied [Patch 1256872] to provide unicode
+ * win/tclWinConsole.c: support in the console on suitable systems.
+ * win/tclWinInt.h: Patch by Anton Kovalenko
+
+2005-11-02 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ Applied [Patch 1096916] to support building with MSVC 8.
+ * generic/regerror.c: Avoid use of reserved word.
+ * generic/tcl.h: Select the right Tcl_Stat structure
+ * generic/tclDate.c: Casts to handle 64 bit time_t case.
+ * tests/env.test: Include essential envvar on Win32
+ * win/nmakehlp.c: Handle new return codes.
+ * win/makefile.vc: Use the selected options.
+ * win/rules.vc: Check options are applicable
+ * win/tclWinPort.h: Disable deprecated function warnings
+ * win/tclWinSock.c: Provide default value to avoid warning.
+ * win/tclWinTime.c: Add casts to handle 64bit time_t type.
+
+2005-11-01 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclTrace.c (TclCheckExecutionTraces): Corrected mistaken
+ assumption that all command traces are set at the script level.
+ Report/fix from Jacques H. de Villiers. [Bug 1337941]
+
+ * tests/unixNotfy.test (1.1,2): Update error message whitespace to
+ match changes in code.
+
+ * tests/expr-old.test (expr-32.52): Use int(.) to restrict result of
+ left shift to the C long range.
+
+ * expr.test (expr-46.13): Added test that illustrates shortcoming of
+ [Patch 1340260].
+
+2005-10-31 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclNamesp.c: fix for [Bugs 1338280/1337229]. Thanks Don.
+ * tests/trace.test: fix duplicate test numbers
+
+2005-10-31 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * win/tclWinSerial.c (SerialSetOptionProc): Cleaned up option parsing
+ to produce more informative error messages and separate error and
+ non-error code paths better.
+ * tests/ioCmd.test (iocmd-8-19): Updated.
+
+2005-10-29 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclTrace.c (TraceVarProc): [Bug 1337229], partial fix. Ensure
+ that a second call with TCL_TRACE_DESTROYED does not lead to a second
+ call to Tcl_EventuallyFree(). It is still true that that second call
+ should not happen, so the bug is not completely fixed.
+ * tests/trace.test (test-18.3-4): added tests for [Bug 1337229] and
+ [Bug 1338280].
+
+2005-10-23 Vince Darley <vincentdarley@sourceforge.net>
+
+ * generic/tclFileName.c: fix to memory leak in glob [Bug 1335006] Obj
+ leak detection and patch by Eric Melbardis.
+
+ * tests/fCmd.test:
+ * win/tclWinFile.c: where appropriate windows API is available, try to
+ set 'nlink' and 'ino' stat fields (previously they were always 0). [Bug
+ 1325803]
+
+2005-10-22 Miguel Sofer <msofer@users.sf.net>
+
+ * tests/foreach.test (foreach-8.1): added test for [Bug 1189274]
+
+2005-10-22 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c (INST_INCR_*): fixed [Bug 1334570]. Obj leak
+ detection and patch by Eric Melbardis.
+
+2005-10-21 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclStrToD.c (RefineApproximation): Plugged a memory leak
+ where two intermediate results were not freed on one return path. [Bug
+ 1334461]. Thanks to Eric Melbardis for the patch.
+
+2005-10-21 Donal K. Fellows <dkf@users.sf.net>
+
+ * doc/binary.n: Clarify that virtually all code that uses the 'h'
+ format in [binary scan] should be using the 'H' format instead. It is
+ nearly always a bug to use the other!
+
+2005-10-20 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclListObj.c (TclLsetFlat):
+ * tests/lset.test (lset-10.3): fixed handling of unshared lists with
+ shared sublists, [Bug 1333036] reported by neuronstorm.
+
+2005-10-19 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclIORChan.c (PassReceivedError,PassReceivedErrorInterp):
+ Fix crash caused by passing -1 as the length to TclNewStringObj(). Only
+ Tcl_NewStringObj (the function call, not the macro) handles that sort
+ of thing correctly. This makes ioCmd.test pass again.
+
+2005-10-19 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclClock.c: Removed some dead code.
+ * generic/tclCmdIL.c:
+ * generic/tclCompCmds.c:
+ * generic/tclDictObj.c:
+ * generic/tclExecute.c:
+ * generic/tclLiteral.c:
+ * generic/tclParseExpr.c:
+ * generic/tclScan.c:
+ * generic/tclUtil.c:
+ * generic/tclVar.c:
+
+2005-10-19 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * generic/tclIORChan.c: General cleanup, removing checks that are
+ unnecessary due to the general contracts of other functions in the
+ core, converting to using ANSI declarations, etc. Note that nearly the
+ whole file has changed, but it is often just cosmetic.
+
+2005-10-19 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c (INST_DICT_APPEND, INST_DICT_LAPPEND): fixed
+ faulty peephole optimisation that can cause crashes, [Bug 1331475]
+ reported by Aric Bills.
+
+2005-10-18 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclExecute.c: Added optimization for I32L64 systems to avoid
+ using bignums to perform int multiplies. The improvement shows up most
+ dramatically in tclbench's matrix.bench.
+
+2005-10-15 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclExecute.c: Restored some optimizations of the
+ INST_INCR_SCALAR1_IMM opcode.
+
+2005-10-14 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+
+ * generic/tclIO.c (Tcl_ClearChannelHandlers): removed change dated
+ 2005-10-04 (see below). Look into [Bug 1323992] for detailed
+ discussion.
+
+ * generic/tcl.h: Fixed bad definition of CRTEXPORT which should have
+ been CRTIMPORT rather. This broke compilation of generic/tclMain.c and
+ was probably introduced by mistake while applying the fix for [Bug
+ 1256937] below.
+
+2005-10-14 Kevin Kenny <kennykb@acm.org>
+
+ * generic/tclExecute.c (TclIncrObj, TclExecuteByteCode): Tidied up a
+ couple of infelicitous do {...} while(0) constructs.
+
+2005-10-14 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ * generic/tcl.h: Fix for [Bug 1256937] - correctly decorate
+ * generic/tclMain.c: imported functions from msvcrt in static builds.
+
+2005-10-13 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * tests/format.test: "Forward"-port of test updates relating to [Bug
+ 1284178]. The bug itself was fixed by TIP#237.
+
+2005-10-13 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+
+ * generic/tclIO.c (Tcl_ClearChannelHandlers): temporary ifdef
+ TCL_THREADS changes done to de-activate pending event processing when
+ channel is being closed/cutted.
+
+2005-10-13 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclExecute.c: Removed obsolete use of NO_ERRNO_H.
+ * tools/man2tcl.c:
+ * unix/tcl.m4:
+ * unix/tclConfig.h.in:
+ * win/configure.in:
+
+ * unix/configure: autoconf-2.59
+ * win/configure:
+
+ * compat/tclErrno.h: Removed obsolete file.
+
+ * generic/tclStrToD.c (TclParseNumber): Missing goto caused crash when
+ parsing "Na". [Bug 1325833]
+
+2005-10-12 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclExecute.c (GetNumberFromObj): Restored some lost
+ optimizations for empty string values. We avoid cost of a call to
+ TclParseNumber just to tell us an empty string isn't a number.
+
+2005-10-12 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclPathObj.c (SetFsPathFromAny): TclGetString macro must not
+ be combined with post-increment arguments. [Bug 1325099]
+
+2005-10-12 Kevin Kenny <kennykb@acm.org>
+
+ * generic/tclExecute.c (Tcl_ExecuteByteCode, TclIncrObj): Several
+ common cases inlined in hopes of gaining a little performance in [incr]
+
+2005-10-10 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompCmds.c: New convenience macro CompileTokens().
+
+2005-10-10 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclExecute.c: Corrections to the NO_WIDE_TYPE build. Also
+ added missing "break" to a switch that broke wide XOR operations.
+
+2005-10-10 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclInterp.c (DeleteScriptLimitCallback)
+ (SetScriptLimitCallback): Improve the interlocking between the script
+ limit callback record and the hash table of current such records, to
+ prevent crashes in callbacks that create callbacks.
+ (Tcl_LimitSetTime): Reset the correct flag. Problem reported by
+ Nicolas Castagne <castagne@imag.fr> on comp.lang.tcl
+
+2005-10-10 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c: Fixing errors in last commit. (Two commits, the
+ second removes wrong comment).
+
+2005-10-09 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclBasic.c:
+ * generic/tclExecute.c:
+ * generic/tclStrToD.c:
+ * generic/tclStringObj.c: Initialise variables to avoid compiler
+ warnings ([Bug 1320818] among others).
+
+2005-10-08 Don Porter <dgp@users.sourceforge.net>
+
+ TIP#237 IMPLEMENTATION
+
+ [kennykb-numerics-branch] Resynchronized with the HEAD; at this
+ checkpoint [-rkennykb-numerics-branch-20051008], the HEAD and
+ kennykb-numerics-branch contain identical code.
+
+ [kennykb-numerics-branch] Merge updates from HEAD
+
+ * generic/tclExecute.c: More performance macros and special handling of
+ the wide integer type for performance on 32-bit systems.
+
+2005-10-07 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclExecute.c: Macro GetNumberFromObj() is version of
+ TclGetNumberFromObj() that saves a function call for common uses.
+
+ * generic/tclInt.h: Made #undef NO_WIDE_TYPE the default on 32-bit
+ systems. Being able to use 64-bit values without leaping to mp_int
+ should help with performance.
+
+ * generic/tclObj.c: Bug fixes in the #undef NO_WIDE_TYPE
+ * generic/tclExecute.c: configuration.
+
+ * generic/tclExecute.c: Improved performance of comparison opcodes and
+ bitwise operations and removed yet more dead code.
+
+2005-10-07 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/tclUnixFCmd.c (TraverseUnixTree): Adjust 2004-11-11 change to
+ * tests/fCmd.test (fCmd-20.2): account for NFS special files
+ with a readdir rewind threshold. [Bug 1034337]
+
+2005-10-06 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclExecute.c: Improved performance of INST_RSHIFT and
+ INST_LSHIFT.
+
+2005-10-05 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclExecute.c: Improved performance of INST_MULT, INST_DIV,
+ INST_ADD, and INST_SUB and replaced a "goto... label" with a "break
+ from loop" in TclIncrObj() and removed some dead code.
+
+2005-10-05 Andreas Kupries <andreask@activestate.com>
+
+ * generic/tclPipe.c (TclCreatePipeline): Fixed [Bug 1109294]. Applied
+ the patch provided by David Gravereaux.
+
+ * doc/CrtChannel.3: Fixed [Bug 1104682], by application of David
+ Welton's patch for it, and added a note about wideSeekProc.
+
+ * generic/tclIORChan.c (RcClose): Removed unreachable panic/return
+ statements. This fixes the remainder of [Bug 1286256].
+
+2005-10-05 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * tests/env.test (env-6.1):
+ * win/tclWinPort.h: define USE_PUTENV_FOR_UNSET 1
+ * generic/tclEnv.c (TclSetEnv, TclUnsetEnv): add USE_PUTENV_FOR_UNSET
+ to existing USE_PUTENV define to account for various systems that have
+ putenv(), but can't unset env vars with it. Note difference between
+ Windows and Linux for actually unsetting the env var (use of '=').
+ Correct the resizing of the environ array. We assume that we are in
+ full ownership, but that's not correct.[Bug 979640]
+
+2005-10-04 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+ * generic/tclExecute.c: Updated TclIncrObj() to more efficiently add
+ native long integers. Also updated IllegalExprOperandType and the
+ INST_UMINUS, INST_UPLUS, INST_BITNOT, and INST_TRY_CVT_TO_NUMERIC
+ sections for performance.
+
+ * generic/tclBasic.c: Updated more callers to make use of
+ TclGetNumberFromObj. Removed some dead code.
+
+2005-10-04 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/tclWinSerial.c (SerialSetOptionProc): free argv [Bug 1067708]
+
+ * tests/http.test: do not URI encode -._~ according
+ * library/http/http.tcl (init): to RFC3986. [Bug 1182373] (aho)
+
+ * unix/tclLoadShl.c (TclpDlopen): use DYNAMIC_PATH on second shl_load
+ only. [Bug 1204237]
+
+ * doc/scan.n: scan %[] requires "one or more chars" [Bug 1277503]
+
+ * tests/winFile.test (getuser): allow valid Windows usernames. [Bug
+ 1311285]
+
+ * generic/tclParse.c (Tcl_ParseCommand): add code that recognizes {} in
+ addition to {expand} for word expansion (make with
+ -DALLOW_EMPTY_EXPAND).
+
+2005-10-04 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+
+ * generic/tclIO.c (Tcl_ClearChannelHandlers): now deletes any
+ outstanding timer for the channel. Also, prevents events still in the
+ event queue from triggering on the current channel.
+
+ * generic/tclTimer.c (Tcl_DeleteTimerHandler): bail out early if passed
+ NULL argument.
+
+2005-10-03 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclBasic.c: Re-implemented ExprRoundFunc and
+ ExprEntierFunc to use TclGetNumberFromObj.
+
+ * generic/tclInt.h: Added new routine TclGetNumberFromObj to
+ * generic/tclObj.c: provide efficient access to the actual
+ internal rep of a numeric Tcl_Obj without conversions.
+
+2005-10-03 Kevin Kenny <kennykb@acm.org>
+
+ * tools/loadICU.tcl: Changed the file names of message catalogs to
+ lowercase.
+ * tools/makeTestCases.tcl:
+ * library/tzdata/*: Olson's tzdata2005n.tar.gz. Includes new DST
+ rules for USA and a number of changes to other locales.
+ * tests/clock.test: Regenerated for new US DST rules.
+
+2005-09-30 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclMain.c: Separate encoding conversion of command line
+ arguments from list formatting. [Bug 1306162].
+
+2005-09-30 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclStringObj.c: Bug fix: Missing cast to large enough
+ integral size before << operations led to broken [format %llx] results.
+ Thanks to Robert Henry for reporting the bug.
+
+2005-09-29 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * doc/mathfunc.n: implementation for TIP #255, expr min/max
+ * library/init.tcl:
+ * tests/info.test, tests/expr-old.test:
+
+2005-09-27 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tcl.h: Changed name of the new Tcl_Obj intrep field
+ * generic/tclObj.c: from "bignumValue" to "ptrAndLongRep" as
+ * generic/tclProc.c: described in TIP 237, and more suitable for
+ other more general uses.
+
+2005-09-27 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * tests/binary.test (binary-14.18): Added test for [Bug 1116542] though
+ the bug itself was already fixed by unrelated changes.
+
+2005-09-26 Kevin Kenny <kennykb@acm.org>
+
+ [kennykb-numerics-branch] Merge updates from HEAD.
+
+2005-09-26 Kevin Kenny <kennykb@acm.org>
+
+ * libtommath/: Updated to release 0.36.
+ * generic/tommath.h: Regenerated.
+ * generic/tclTomMathInterface.h: Added ten missing aliases for mp_*
+ functions to avoid namespace pollution in Tcl's exported symbols. [Bug
+ 1263012]
+
+2005-09-23 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * unix/Makefile.in: Added -DMP_PREC=4 switch to all compiles so
+ * win/Makefile.in: that minimum memory requirements of mp_int's
+ * win/makefile.vc: will not be quite so large. [Bug 1299153].
+
+ * generic/tclStrToD.c: Fixed memory leak. [Bug 1299803].
+ * generic/tclObj.c:
+
+2005-09-20 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclExecute.c: Revise TclIncrObj() to call
+ Tcl_GetBignumAndClearObj.
+
+ * generic/tcl.decls: Add Tcl_GetBignumAndClearObj.
+ * generic/tclObj.c:
+
+ * generic/tclDecls.h: make genstubs
+ * generic/tclStubInit.c:
+
+2005-09-16 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclInt.h: Added TclBNInitBigNumFromWideInt() so
+ * generic/tclTomMathInterface.c: that every caller isn't required to
+ duplicate the sign logic to use the unsigned interface.
+
+ * generic/tclBasic.c: Reduce the number of places where Tcl intrudes
+ * generic/tclExecute.c: into the internal format details of the mp_int
+ * generic/tclObj.c: struct.
+ * generic/tclStrToD.c:
+ * generic/tcLStringObj.c:
+
+ * generic/tclTomMath.h: Added mp_cmp_d to routines from libtommath
+ * unix/Makefile.in: used by Tcl.
+ * win/Makefile.in:
+ * win/makefile.vc:
+
+ * libtommath/bn_mp_add_d.c: Bug fix. For mp_add_d(&a, d, &c), when &a
+ has the value -d, then the value &c computed should be zero, but
+ mp_add_d was producing an inconsistent zero value with a sign field of
+ MP_NEG, something like a value of -0, which other routines in
+ libtommath can't handle.
+
+ * generic/tclExecute.c: Dropped all creation of "bigOne" values and
+ just use tommath routines that accept the value "1" directly.
+
+2005-09-15 Miguel Sofer <msofer@users.sf.net>
+
+ * doc/ParseCmd.3: copy/paste fix [Bug 1292427]
+
+2005-09-15 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch] Merge updates from HEAD.
+
+ * generic/tclStringObj.c (TclAppendFormattedObjs): Revision to
+ eliminate one round of string copying.
+
+ * generic/tclBasic.c: More callers of TclObjPrintf and
+ * generic/tclCkalloc.c: TclFormatToErrorInfo.
+ * generic/tclCmdMZ.c:
+ * generic/tclExecute.c:
+ * generic/tclIORChan.c:
+ * generic/tclMain.c:
+ * generic/tclProc.c:
+ * generic/tclTimer.c:
+ * generic/tclUtil.c:
+ * unix/tclUnixFCmd.c
+
+ * unix/configure: autoconf-2.59
+
+2005-09-15 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * unix/tcl.m4 (SC_TCL_EARLY_FLAGS): Added extra hack to allow Tcl to
+ transparently open large files on RHEL 3. [Bug 1287638]
+
+2005-09-14 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclStringObj.c: Bug fixes: ObjPrintfVA needed to
+ support "*" fields and needed to interpret precision limits on %s
+ conversions as a maximum number of bytes, not Tcl_UniChars, to take
+ from the (char *) argument.
+
+ * generic/tclBasic.c: Updated several callers to use
+ * generic/tclCkalloc.c: TclFormatToErrorInfo() and/or
+ * generic/tclCmdAH.c: TclObjPrintf().
+ * generic/tclCmdIL.c:
+ * generic/tclCmdMZ.c:
+ * generic/tclDictObj.c:
+ * generic/tclExecute.c:
+ * generic/tclIORChan.c:
+ * generic/tclIOUtil.c:
+ * generic/tclNamesp.c:
+ * generic/tclProc.c:
+
+ * library/init.tcl: Keep [unknown] in sync with errorInfo
+ formatting rules.
+
+2005-09-13 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c: First caller of TclFormatToErrorInfo.
+
+ * generic/tclInt.h: Using stdarg.h conventions, add more
+ * generic/tclStringObj.c: fixed arguments to TclFormatObj() and
+ TclObjPrintf(). Added new routine TclFormatToErrorInfo().
+
+ * generic/tcl.h: Explicitly standardized on the use of stdarg.h
+ * generic/tclBasic.c: conventions for functions with variable number
+ * generic/tclInt.h: of arguments. Support for varargs.h has been
+ * generic/tclPanic.c: implicitly gone for some time now. All
+ * generic/tclResult.c: TCL_VARARGS* macros purged from Tcl sources,
+ * generic/tclStringObj.c: leaving only some deprecated #define's
+ * tools/genStubs.tcl: in tcl.h for the sake of older extensions.
+
+ * generic/tclDecls.h: make genstubs
+
+ * doc/AddErrInfo.3: Replaced all documented requirement for use of
+ * doc/Eval.3: TCL_VARARGS_START() with requirement for use of
+ * doc/Panic.3: va_start().
+ * doc/SetResult.3:
+ * doc/StringObj.3:
+
+2005-09-12 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch] Merge updates from HEAD.
+
+ * generic/tclCmdAH.c: Added support for the "ll" width
+ * generic/tclStringObj.c: specifier to [format].
+
+ * generic/tclStringObj.c (TclAppendFormattedObjs): Bug fix: make
+ sure %ld formats force the collection of a wide value, when the value
+ could be a different long.
+
+2005-09-09 Andreas Kupries <andreask@activestate.com>
+
+ * generic/tclIORChan.c (RcDecodeEventMask): Added missing type
+ declaration for the parameter 'mask'. This fixes the [Bug 1286256]. The
+ other warning can be removed only by removing the panic/return code.
+
+2005-09-09 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch] Merge updates from HEAD.
+
+2005-09-09 Kevin Kenny <kennykb@acm.org>
+
+ * generic/tclStringObj.c: Added two missing casts to silence messages
+ from MSVC6.
+
+2005-09-09 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclInt.h: New internal routine TclObjPrintf()
+ * generic/tclStringObj.c: is similar to TclFormatObj() but
+ accepts arguments in non-Tcl_Obj format.
+
+ * generic/tclInt.h: New internal routines TclFormatObj()
+ * generic/tclStringObj.c: and TclAppendFormattedObjs() to offer
+ sprintf()-like means to append to Tcl_Obj. Work in progress toward
+ [RFE 572392].
+
+ * generic/tclCmdAH.c: Compiler directive NEW_FORMAT when #define'd
+ directs the [format] command to be implemented in terms of the new
+ TclAppendFormattedObjs() routine.
+
+2005-09-08 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ TIP#254 IMPLEMENTATION
+
+ * generic/tclLink.c (LinkTraceProc,ObjValue): Added many new of C var
+ * generic/tcl.h: to link to, making it
+ * doc/LinkVar.3: easier to seamlessly
+ * generic/tclTest.c (TestlinkCmd): couple C code and Tcl
+ * tests/link.test: scripts in an
+ application. [Patch 1242844]
+
+2005-09-07 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclUtf.c (Tcl_UniCharToUtf): Corrected handling of negative
+ * tests/utf.test (utf-1.5): Tcl_UniChar input value. Incorrect
+ handling was producing byte sequences outside of Tcl's legal internal
+ encoding. [Bug 1283976].
+
+2005-09-06 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclInt.h (List): Added flag to keep track of whether a list
+ * generic/tclListObj.c: with a string rep is provably canonical.
+ * generic/tclUtil.c (Tcl_ConcatObj): Do efficient concatenation and
+ * generic/tclBasic.c (Tcl_EvalObjEx): evaluation when the list is
+ canonical, and not just when the list is pure. This should make the
+ "pure list" hacking introduced in 8.3 much more robust.
+
+2005-09-05 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclObj.c (pendingObjDataKey): Added missing 'static' to stop
+ symbol from leaking outside the Tcl library. [Bug 1263012]
+
+2005-09-02 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclScan.c: Bug fix: The %o, %x, %i formats of [scan] must
+ not accept any 0b or 0o prefixes. [scan $s %o] must continue to work
+ even with KILL_OCTAL enabled.
+
+ * generic/tclInt.h: Added TCL_PARSE_SCAN_PREFIXES to the flags
+ * generic/tclStrToD.c: accepted by TclParseNumber.
+
+2005-09-01 Andreas Kupries <andreask@activestate.com>
+
+ * unix/tclUnixSock.c (InitializeHostName): Synchronized use of static
+ modifier in declaration and definition of function.
+
+ * unix/tclUnixChan.c (FileTruncateProc): Synchronized use of static
+ modifier in declaration and definition of function.
+
+ * generic/tclResult.c (ReleaseKeys): Synchronized use of static
+ modifier in declaration and definition of function.
+
+ * generic/tclListObj.c (NewListIntRep): Synchronized use of static
+ modifier in declaration and definition of function.
+
+ * generic/tclEncoding.c (InitializeEncodingSearchPath): Synchronized
+ use of static modifier in declaration and definition of function.
+
+ * generic/tclEncoding.c (FillEncodingFileMap): Synchronized use of
+ static modifier in declaration and definition of function.
+
+ * generic/tclIORChan.c (RcNewHandle): Synchronized use of static
+ modifier in declaration and definition of function.
+
+2005-09-01 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclObj.c: TclParseNumber calls meant to parse an integer
+ value now pass the TCL_PARSE_INTEGER_ONLY flag.
+
+ * generic/tclScan.c: Extended [scan] to accept the %lld, %llo, %llx,
+ and %lli formats. Numeric scanning is now done via TclParseNumber calls
+
+ * generic/tclInt.h: Extended TclParseNumber to accept new flag
+ * generic/tclStrToD.c: values TCL_PARSE_INTEGER_ONLY,
+ TCL_PARSE_OCTAL_ONLY, and TCL_PARSE_HEXIDECIMAL_ONLY, to give caller
+ more control over the parsing rules.
+
+2005-08-31 Vince Darley <vincentdarley@sourceforge.net>
+
+ * doc/FileSystem.3:
+ * unix/tclUnixFile.c:
+ * windows/tclWinFile.c: clarify that Tcl_FSMatchInDirectory may be
+ called with a NULL interpreter, and fix the code so this is allowed.
+ Tcl's core itself (tclEncoding.c:FillEncodingFileMap()) calls this
+ with a NULL interpreter.
+
+2005-08-30 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclObj.c: Extended bignum support to include bignums so
+ large they will not pack into a Tcl_Obj. When they outgrow Tcl's string
+ rep length limits, a panic will result.
+
+ * generic/tclTomMath.h: Added mp_sqrt to routines from
+ * unix/Makefile.in: libtommath used by Tcl.
+ * win/Makefile.in:
+ * win/makefile.vc:
+
+ * generic/tclBasic.c: Extended sqrt(.) so that range covers the
+ entire double range, accepting as many bignums in the domain as that
+ will allow.
+
+2005-08-29 Andreas Kupries <andreask@activestate.com>
+
+ * library/tm.tcl (::tcl::tm::roots): Accepted Don Porter's patch for
+ [Bug 1189657]. Syncs the implementation to the specification (TIP #189)
+
+2005-08-29 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch] Merge updates from HEAD.
+
+ * generic/tclBasic.c: Restored round(.) to the Tcl 8.4 rules.
+
+2005-08-29 Kevin Kenny <kennykb@acm.org>
+
+ * generic/tclBasic.c (ExprMathFunc): Restored "round away from zero"
+ * tests/expr.test (expr-46.*): behaviour to the "round" function.
+ Added test cases for the behavior, including the awkward case of a
+ number whose fractional part is 1/2-1/2ulp. [Bug 1275043]
+
+2005-08-26 Andreas Kupries <andreask@activestate.com>
+
+ * generic/tclIO.c: Moved Tcl_{Cut,Splice}Channel to
+ {Cut,Splice}Channel for internal use, and created new public functions
+ for Tcl_{Cut,Splice}Channel which walk the whole stack of
+ transformations and invoke the necessary thread actions. Added code to
+ Tcl_(Un)StackChannel to properly invoke the thread actions when pushing
+ and popping transformations on/from a channel.
+
+2005-08-26 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclNamesp.c (NamespaceEnsembleCmd): Reset the result after
+ creating an ensemble to clear any result object sharing (potentially
+ caused by delete traces) so that we can safely return the name of the
+ ensemble. Previously, this caused crashes in Snit's test suite.
+
+2005-08-25 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclListObj.c (UpdateStringOfList): Stop uncontrolled and
+ unsafe crashes from happening when working with very large string
+ representations. [Bug 1267380]
+
+ * generic/tclExecute.c (TEBC:INST_DICT_LAPPEND): Stop dropping a
+ duplicated object on the floor, which was a memory leak (and a wrong
+ result too). Thanks to Andreas Kupries for reporting this.
+
+2005-08-25 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch] Merge updates from HEAD
+
+ * generic/tclExecute.c: Bug fix. INST_RSHIFT: shift of negative values
+ produced incorrect results.
+
+ * generic/tclExecute.c: Bug fix. INST_*SHIFT opcodes stack management.
+ [expr 0<<6] should be 0, not 6.
+
+ * generic/tclBasic.c: Extended the domain of round(.) to all non-Inf,
+ non-NaN doubles, using bignums for the result as needed.
+
+2005-08-24 Andreas Kupries <andreask@activestate.com>
+
+ TIP#219 IMPLEMENTATION
+
+ * doc/SetChanErr.3: ** New File **. Documentation of the new channel
+ API functions.
+ * generic/tcl.decls: Stub declarations of the new channel API.
+ * generic/tclDecls.h: Regenerated
+ * generic/tclStubInit.c:
+
+ * tclIORChan.c: ** New File **. Implementation of the reflected
+ channel.
+ * generic/tclInt.h: Integration of reflected channel and new error
+ * generic/tclIO.c: propagation into the generic I/O core.
+ * generic/tclIOCmd.c:
+ * generic/tclIO.h:
+ * library/init.tcl:
+
+ * tests/io.test: Extended testsuite.
+ * tests/ioCmd.test:
+ * tests/chan.test:
+ * generic/tclTest.c:
+ * generic/tclThreadTest.c:
+
+ * unix/Makefile.in: Integration into the build machinery.
+ * win/Makefile.in:
+ * win/Makefile.vc:
+
+2005-08-24 Kevin Kenny <kennykb@acm.org>
+
+ * generic/tclStrToD.c (Tcl_DoubleDigits): Fixed the corner cases of
+ * tests/binary.test (binary-65.*) formatting floating point
+ numbers with the largest and smallest possible significands, and added
+ test cases for them.
+
+2005-08-24 Kevin Kenny <kennykb@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclExecute.c: Corrected some TRACE bugs that prevented
+ compilation with --enable-symbols=all.
+ * generic/tclStrToD.c: Revised commentary to prepare for a renaming of
+ the file, removed some dead code, and fixed a bug where
+ TclBignumToDouble failed on huge negative numbers.
+ * tests/binary.test (binary-65.*): Added missing 'ieeeFloatingPoint'
+ to large/small significand tests.
+ * tests/expr.test (expr-45.*) Added missing braces around expressions.
+
+2005-08-24 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclBasic.c: Revised implementation of the ceil(.) and
+ * generic/tclInt.h: floor(.) math functions in light of the
+ * generic/tclStrToD.c: revised comparison operators, so that it is
+ always true that ($x <= ceil($x)) and ($x >= floor($x)). The simple
+ approach of "convert to double and call ceil() or floor()" could not
+ guarantee that.
+
+ * generic/tclExecute.c: Bug fix: TclBignumToDouble return -Inf when
+ appropriate. Removed declarations of removed routines.
+
+ * generic/tclExecute.c: Revised the type promotion rules of the
+ comparison operators so that they form proper equivalence classes over
+ the set of numeric strings.
+
+2005-08-23 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/configure.in:
+ * win/configure: Regen.
+ * win/configure.in: Update minimum autoconf version to 2.59.
+
+2005-08-23 Kevin Kenny <kennykb@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd):
+ * generic/tclInt.h:
+ * generic/tclObj.c (Tcl_GetBooleanFromObj, SetDoubleFromAny,
+ Tcl_GetLongFromObj, Tcl_GetWideIntFromObj, Tcl_GetBignumFromObj):
+ * generic/tclParseExpr.c (GetLexeme):
+ * generic/tclScan.c (Tcl_ScanObjCmd):
+ * generic/tclStrToD.c (TclParseNumber):
+ * tests/binary.test (binary-62.1-65.7):
+ * tests/expr.test (expr-40.1-42.1):
+ * scan.test (scan-14.1,14.2):
+ Modified Tcl_ParseNumber to accept an argument to force interpretation
+ as decimal, and modified [scan] to use it. Corrected a bug where Not a
+ Number with hexadecimal information bits returned consistently
+ incorrect values. #ifdef-ed out some code that is needed only for IBM
+ hexadecimal floating point. Fixed bugs in code to handle the corner
+ cases of smallest and largest significands. Added test cases to improve
+ test coverage in generic/tclStrToD.c. Added test cases for 0b notation
+ (TIP #114). Removed TclStrToD, and the static functions that it calls,
+ which are now dead code (TclParseNumber now does all input
+ floating-point conversions.)
+
+2005-08-23 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclStrToD.c: Bug fix: set shift magnitude properly whether
+ we're expanding to mp_int type or not.
+
+ * generic/tclExecute.c: Bug fix: ACCEPT_NAN under INST_UMINUS.
+
+ * generic/tclStrToD.c: New macros TIP_114_FORMATS and KILL_OCTAL to
+ configure acceptance of 0o and 0b numbers and rejection of "leading
+ zero as octal".
+
+ * generic/tclBasic.c: Re-used the guts of int(.) and wide(.) math
+ functions to perform conversions in OldMathFuncProc.
+
+ * generic/tclBasic.c: Support for ACCEPT_NAN.
+ * generic/tclExecute.c:
+
+ * generic/tclInt.decls: Restored TclExprFloatError to internal stubs
+ * generic/tclBasic.c: table, and moved definition back to
+ * generic/tclExecute.c: tclExecute.c from tclBasic.c to handle #undef
+ ACCEPT_NAN.
+
+ * generic/tclIntDecls.h: make genstubs
+ * generic/tclStubInit.c:
+
+ * generic/tclInt.h: New internal macros TclIsNaN and TclIsInfinite
+ * generic/tclBasic.c: replace the IS_NAN and IS_INF macros scattered
+ * generic/tclExecute.c: here and there.
+ * generic/tclObj.c:
+ * generic/tclStrToD.c:
+ * generic/tclUtil.c:
+
+2005-08-22 Daniel Steffen <das@users.sourceforge.net>
+
+ * unix/tclConfig.h.in: autoheader-2.59.
+
+2005-08-22 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclInt.h: New ACCEPT_NAN macro to mark code that
+ * generic/tclCmdAH.c: supports or disables accepting of the NaN
+ * generic/tclExecute.c: value at various points.
+ * generic/tclLink.c:
+
+ * generic/tclStrToD.c: Bug fix. Parsing of +/- Infinity was reversed.
+
+ * generic/tclTestObj.c: Disabled unused [testconvertobj] command.
+
+ * generic/tclBasic: Added [expr {entier(.)}]. Rewrote int(.) and
+ wide(.) to use the same guts, accepting all non-Inf doubles as
+ arguments.
+
+ * generic/tclInt.h: New routine TclInitBignumFromDouble.
+ * generic/tclStrToD.c: Modified to return code and write error
+ message.
+
+ * generic/tclInt.h: TCL_WIDE_INT_IS_LONG implies NO_WIDE_TYPE.
+ * generic/tclObj.c: Removed now unnecessary tests of the
+ * generic/tclStrToD.c: TCL_WIDE_INT_IS_LONG definition.
+
+ * generic/tclInt.h: New internal routine TclSetBignumIntRep
+ * generic/tclObj.c: consolidates packing of bignum value into a
+ * generic/tclStrToD.c: Tcl_Obj within one source code file.
+
+ * tests/expr.test: Corrected the wideIs64bit constraint.
+ * tests/format.test:
+ * tests/scan.test:
+
+2005-08-21 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclInt.h: Moved TclParseInteger to tclUtil.c and
+ * generic/tclParseExpr.c: made it static.
+ * generic/tclUtil.c:
+
+ * generic/tclInt.decls: Moved TclExprFloatError to tclBasic.c and made
+ * generic/tclBasic.c: it static.
+ * generic/tclExecute.c:
+
+ * generitc/tclIntDecls.h: make genstubs
+ * generic/tclStubInit.c:
+
+ * generic/tclExecute.c: errno, IS_NAN, IS_INF, LLD no longer called in
+ this file; dropped/disabled support for them.
+
+ * generic/tclCompExpr.c: errno no longer used in these files;
+ * generic/tclParseExpr.c: dropped support "hack" for it.
+
+ * generic/tclStrToD.c: Disabled out of date support "hack" for errno.
+
+ * generic/tclBasic.c: Eliminated VerifyExprObjType. Initialize errno
+ to zero in OldMathFuncProc.
+
+2005-08-19 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclBasic.c: Updated OldMathFuncProc and ExprAbsFunc to do
+ less invasion into numeric Tcl_Obj internals. Made ExprDoubleFunc,
+ ExprIntFunc, ExprWideFunc, and ExprRoundFunc bignum-aware. Revised
+ ExprSrandFunc error message.
+
+ * generic/tclProc.c: Wrapped a few tclWideIntType uses in
+ * generic/tclCmdMZ.c: #ifndef NO_WIDE_TYPE.
+
+ * generic/tclInt.h: #define'd NO_WIDE_TYPE.
+
+ * generic/tclVar.c: Replaced TclPtrIncrVar and TclPtrIncrWideVar
+ * generic/tclInt.h: with TclPtrIncrObjVar and replaced TclIncrVar2
+ * generic/tclInt.decls: and TclIncrWideVar2 with TclIncrObjVar2. New
+ routines call on TclIncrObj to do the work.
+
+ * generic/tclIntDecls.h: make genstubs
+ * generic/tclStubInit.c:
+
+ * generic/tclCmdIL.c: Rework Tcl_IncrObjCmd and the INST_*INCR*
+ * generic/tclExecute.c: opcodes to use the new routines.
+
+2005-08-18 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclExecute.c: Fixed string rep invalidation bug in
+ * tests/dict.test (dict-11.17): INST_DICT_INCR_IMM rewrite.
+
+ * generic/tclDictObj.c: DictIncrCmd rewrite to use TclIncrObj.
+
+ * generic/tclInt.h: TclIncrObj static -> internal
+ * generic/tclExecute.c:
+
+2005-08-17 George Peter Staplin <GeorgePS@XMission.com>
+
+ * generic/tclBasic.c: eliminate a namespace clash caused by
+ BuiltinFuncTable not being static.
+
+ * generic/tclObj.c: fix a namespace clash caused by a missing
+ static for pendingObjData.
+
+2005-08-17 Kevin Kenny <kennykb@acm.org>
+
+ * generic/tclEvent.c (Tcl_Finalize): Removed a copy-and-paste accident
+ that caused a (mostly harmless) double finalize of the load and
+ filesystem subsystems.
+ * tests/clock.test: Eliminated the bad test clock-43.1, and split
+ clock-50.1 into two tests, with a more permissive check on the error
+ message for an out-of-range value.
+
+2005-08-17 Kevin Kenny <kennykb@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclBasic.c (Tcl_Expr{Long,Double}{,Obj}): Updated to
+ * generic/tclTest.c: deal with
+ * tests/expr-old.test: bignums (well,
+ * tests/expr.test: mostly).
+ Added a missing "errno=0;" in ExprUnaryFunc so that spurious error
+ returns aren't detected.
+ Added test cases for Tcl_Expr* and Tcl_Expr*Obj because there was very
+ poor test coverage in those areas.
+ * generic/tclParseExpr.c: Reworked parsing of numbers to call
+ TclParseNumber rather than trying to do things locally.
+ * generic/tclStrToD.c: Corrected a comment. Changed so that *endPtrPtr
+ does not include any trailing whitespace.
+
+2005-08-17 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclExecute.c: New routine TclIncrObj to centralize the
+ increment operation needed in many places. Updated INST_DICT_INCR_IMM
+ to make use of it.
+
+2005-08-16 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclExecute.c: Made bit shifting opcodes and INST_MOD
+ bignum-aware.
+
+ * tests/scan.test: Making << bignum-aware means that repeated
+ * tests/string.test: left shifting cannot turn a positive into a
+ negative. Revised [int_range] and [largest_int] utility commands in the
+ test suite that relied on that happening. Without revision they became
+ infinite loops.
+
+ * generic/tclExecute.c: Made binary bitwise opcodes bignum-aware.
+
+ * generic/tclTomMath.h: Added mp_or and mp_xor to routines from
+ * unix/Makefile.in: libtommath used by Tcl.
+ * win/Makefile.in:
+ * win/makefile.vc:
+
+2005-08-15 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch] Updates from HEAD.
+ * generic/tclExecute.c: More revisions to IllegalExprOperandType.
+ Merged INST_BITNOT with INST_UMINUS and make it bignum-aware according
+ to the rule: ~a = -a - 1. Disabled unused code and noted more TODOs.
+
+ * generic/tclInt.decls: Disabled TclLooksLikeInt() and all callers.
+ * generic/tclUtil.c:
+ * generic/tclCompCmds.c:
+
+ * generic/tclBasic.c: Rewrite of VerifyExprObjType().
+
+ * generic/tclIntDecls.h: make genstubs
+ * generic/tclStubInit.c:
+
+ * generic/tclExecute.c: Updated execution of comparison bytecodes to
+ be bignum-aware, routing string compares through INST_STR_CMP.
+
+2005-08-14 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclExecute.c: Updated execution of arithmetic bytecodes to
+ be bignum-aware, and to allow calculations on NaN to produce a NaN
+ result. INST_UMINUS updated to call mp_neg.
+
+ * generic/tclTomMath.h: Added mp_and, mp_expt_d, and mp_neg to
+ * unix/Makefile.in: routines from libtommath used by Tcl.
+ * win/Makefile.in:
+ * win/makefile.vc:
+
+2005-08-13 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclObj.c: Extended Bignum auto-narrowing to auto-narrow
+ to tclWideIntType when appropriate; this helps keep things working as
+ the bytecode execution code is migrated to supporting bignums.
+
+ * generic/tclExecute.c: Major overhaul of IllegalExprOperandType.
+ Changed several TclNewFooObj() calls to more logically appropriate
+ ones. Added several TODO comments marking opportunies for future work.
+ Made more use of the eePtr->constants. Made INST_UMINUS bignum aware.
+
+2005-08-12 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclExecute.c: Simplify doCondJump. Use eePtr->constants as
+ result of INST_DICT_NEXT, INST_LAND, and INST_LOR. Separate INST_LNOT
+ from INST_UMINUS and simplify.
+
+2005-08-12 Kevin Kenny <kennykb@acm.org>
+
+ * generic/tclClock.c (MktimeObjCmd):
+ * library/clock.tcl (GetSystemTimeZone, LoadZoneinfoFile)
+ (ReadZoneinfoFile):
+ * tests/clock.test (clock-50.1):
+ Added functionality to read /etc/localtime if it exists, so that Tcl's
+ time can track system time on Linux even if TZ is not set. Changed
+ ::tcl::clock::Mktime to check for failure, and added a test case that
+ mimics failure but is really success.
+
+2005-08-11 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclExecute.c: Rewrite of INST_LAND/INST_LOR to take advantage
+ of loss of "pure double" issues. Merged INST_UPLUS with
+ INST_TRY_CVT_TO_NUMERIC and updated to use improved rules for impure
+ "double"s as well.
+
+ * generic/tclStrToD.c: Restored conditional generation of
+ tclWideIntType values by TclParseNumber so that Tcl's not completely
+ broken while bignum calculation support is incomplete. The NO_WIDE_TYPE
+ macro can be used to disable this.
+
+ * generic/tclBasic.c (ExprAbsFunc): First pass making [expr abs(.)]
+ bignum-aware.
+
+2005-08-11 Kevin Kenny <kennykb@acm.org>
+
+ * generic/tclEvent.c: Eliminated the USE_THREAD_STORAGE option
+ * generic/tclInt.h: (which is on in every build generated by
+ * generic/tclThread.c: by the standard configurator).
+ * generic/tclThreadStorage.c: Eliminated the code for thread specific
+ * unix/configure: data without USE_THREAD_STORAGE and
+ * unix/tcl.m4: radically refactored the code for
+ * unix/tclConfig.h.in: USE_THREAD_STORAGE so that it has fewer
+ * unix/tclUnixThrd.c: dependencies on the order of
+ * win/configure: finalization. (Also, made 'make
+ * win/Makefile.in: distclean' on Windows clean just a little
+ * win/rules.vc: bit cleaner.)
+ * win/tcl.m4:
+ * win/tclWinThrd.c:
+
+2005-08-10 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclTomMath.h: Added mp_shrink, mp_to_unsigned_bin,
+ * unix/Makefile.in: mp_to_unsigned_bin_n, and mp_unsigned_bin_size
+ * win/Makefile.in: to routines from libtommath used by Tcl.
+ * win/makefile.vc:
+
+ * generic/tommath.h: make gentommath_h
+
+ * generic/tclObj.c: Substantial rewrite to make all number parsing
+ flow through TclParseNumber(). Also established the NO_WIDE_TYPE and
+ BIGNUM_AUTO_NARROW #ifdef's to help track the assumptions of different
+ portions of the code.
+
+ * generic/tclInt.h: Added NO_WIDE_TYPE #ifdefs
+
+2005-08-10 Kevin Kenny <kennykb@acm.org>
+
+ * generic/tclEvent.c (Tcl_Finalize): Pushed Tcl_FinalizeLoad and
+ Tcl_ResetFilesystem down after Tcl_FinalizeThreadAlloc because we can't
+ unload DLL's until after their TSD keys are finalized. (Note that we'll
+ still see aborts if an unloaded DLL has TSD - that still needs to be
+ fixed.
+
+ * tests/compExpr-old.test (compExpr-3.8): Made tests conditional on
+ * tests/expr.test (expr-3.8): 'unix' because they get
+ stack overflows on Win32 threaded builds,
+
+2005-08-09 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclPathObj.c: fix to [file rootname] bug in optimized code
+ path reported on comp.lang.tcl.
+
+2005-08-08 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclObj.c: Replaced some goto's with loops and started
+ use of BIGNUM_AUTO_NARROW and NO_WIDE_TYPE.
+
+2005-08-06 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclThreadStorage.c: Stop exposing the guts of the thread
+ storage system through the internal stubs table. Client code should
+ always use the standard API.
+
+2005-08-05 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch]
+ * generic/tclObj.c: Rewrote Tcl_GetDoubleFromObj().
+
+2005-08-05 Donal K. Fellows <dkf@users.sf.net>
+
+ * unix/tclUnixInit.c (localeTable): Solaris uses a non-standard name
+ for the cp1251 charset. Thanks to Victor Wagner for reporting this.
+ [Bug 1252475]
+
+2005-08-05 Kevin Kenny <kennykb@users.sourceforge.net>
+
+ * win/makefile.vc: Removed unused file ldAout.tcl.
+ * win/makefile.bc: [Bug 1244361]
+
+ * tests/binary.test: Cleaned up testing for scanning of NaN. [Bug
+ 1246264]
+
+ * generic/tclBasic.c (ExprAbsFunc): Added code to handle the corner
+ * tests/expr.test (expr-38.1): case of applying 'abs' to the
+ smallest 32-bit integer. [Bug 1241572]
+
+2005-08-04 Andreas Kupries <andreask@activestate.com>
+
+ * generic/tclIO.c (CloseChannel): Fixed comment nit, added apparently
+ missing word to complete a sentence.
+
+ * generic/tclObj.c (Tcl_DbDecrRefCount): Fixed whitespace nit in panic
+ message.
+
+2005-08-04 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch] Updated from HEAD
+
+ * generic/tclObj.c: Rewrote Tcl_GetBooleanFromObj() and supporting
+ routines to make use of TclParseNumber. This reduces the potential
+ number of times a string value must be scanned.
+
+ * generic/tclObj.c: Simplified routines that manage the typeTable.
+ Deleted the UpdateStringOfBoolean() routine, that can never be called.
+
+2005-08-03 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCompExpr.c: Untangled some dependencies in the
+ * generic/tclEvent.c: order of finalization routines.
+ * generic/tclInt.h: [Bug 1251399]
+ * generic/tclObj.c:
+
+2005-08-02 Don Porter <dgp@users.sourceforge.net>
+
+ [kennykb-numerics-branch] Updated from HEAD
+
+2005-07-30 Daniel Steffen <das@users.sourceforge.net>
+
+ * unix/tclLoadDyld.c (TclpDlopen, TclpLoadMemory): workarounds for
+ bugs/changes in behaviour in Mac OS X 10.4 Tiger.
+
+2005-07-29 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCmdIL.c (InfoGlobalsCmd): Even in high-speed mode, still
+ have to take care with non-existant variables. [Bug 1247135]
+
+2005-07-28 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/README: Update link to msys_mingw8.zip.
+
+2005-07-28 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/compExpr-old.test: Still more conversion of "nonPortable"
+ * tests/error.test: tests into tests with constraints that
+ * tests/expr-old.test: describe the limits of their
+ * tests/expr.test: portability. Also more consolidation
+ * tests/fileName.test: of constraint synonyms.
+ * tests/format.test: wideis64bit, 64bitInts => wideIs64bit
+ * tests/get.test: wideIntegerUnparsed => wideIs32bit
+ * tests/load.test: wideIntExpressions => wideBiggerThanInt
+ * tests/obj.test:
+ * tests/parseExpr.test: Dropped "roundOffBug" constraint that
+ * tests/string.test: protected from buggy sprintf.
+
+2005-07-28 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclPipe.c (TclCreatePipeline): Arrange for POSIX systems to
+ * unix/tclUnixPipe.c (TclpOpenFile): use the O_APPEND flag for
+ * tests/exec.test (exec-19.1): files opened in a pipeline
+ like ">>this". Note that Windows cannot support such access; there is
+ no equivalent flag on the handle that can be set at the kernel-call
+ level. The test is unix-specific in every way. [Bug 1245953]
+
+2005-07-27 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclUtil.c: Converted the $::tcl_precision value to be kept
+ per-thread to prevent different threads from stomping on each others'
+ formatting prescriptions.
+
+ ***POTENTIAL INCOMPATIBILITY*** Multi-threaded programs that set the
+ value of ::tcl_precision will now have to set it in each thread.
+
+ * tests/expr.test: Consolidated equivalent constraints into
+ * tests/fileName.test: single definitions and (more precise) names:
+ * tests/get.test: longis32bit, 32bit, !intsAre64bit => longIs32bit
+ * tests/listObj.test: empty => emptyTest; winOnly => win
+ * tests/obj.test: intsAre64bit => longIs64bit
+ Also updated some "nonPortable" tests to use constraints that mark
+ precisely what about them isn't portable, so the tests can run where
+ they work.
+
+ * library/init.tcl ([unknown]): Corrected return code handling in the
+ portions of [unknown] that expand incomplete commands during
+ interactive operations. [Bug 1214462].
+
+2005-07-26 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/configure: Regen.
+ * unix/configure.in: Check for a $prefix/share directory and add it the
+ the package if found. This will check for Tcl packages in
+ /usr/local/share when Tcl is configured with the default dist install.
+ [Patch 1231015]
+
+2005-07-26 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c (Tcl_CallWhenDeleted): Converted to use
+ per-thread counter, rather than a process global one that required
+ mutex protection. [RFE 1077194]
+
+ * generic/tclNamesp.c (TclTeardownNamespace): Re-ordering so that
+ * tests/trace.test (trace-34.4): command delete traces fire
+ while the command still exists. [Bug 1047286]
+
+2005-07-24 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * unix/configure: Regen.
+ * unix/tcl.m4 (SC_PROG_TCLSH, SC_BUILD_TCLSH):
+ * win/configure: Regen.
+ * win/tcl.m4 (SC_PROG_TCLSH, SC_BUILD_TCLSH): Split confused search
+ for tclsh on PATH and build and install locations into two macros.
+ SC_PROG_TCLSH searches just the PATH. SC_BUILD_TCLSH determines the
+ name of the tclsh executable in the Tcl build directory. [Bug 1160114]
+ [Patch 1244153]
+
+2005-07-23 Don Porter <dgp@users.sourceforge.net>
+
+ * library/auto.tcl: Updates to the Tcl script library to make use
+ * library/history.tcl: of Tcl 8.4 features. Forward port of
+ * library/init.tcl: appropriate portions of [Patch 1237755].
+ * library/package.tcl:
+ * library/safe.tcl:
+ * library/word.tcl:
+
+2005-07-23 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * tests/string.test: Add string is tests for functionality that was not
+ tested.
+ * win/README: Update msys + mingw URL. Remove old Cygwin + mingw info.
+
+2005-07-23 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c (INST_DICT_*): stop 2 compiler warnings for
+ uninitialised variables.
+
+2005-07-23 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclExecute.c (TEBC:INST_DICT_INCR_IMM): Fix the incrementor
+ to work correctly with wide values.
+
+2005-07-21 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCompCmds.c (TclCompileDictCmd): First run at a compiler
+ * generic/tclExecute.c (TclExecuteByteCode): for dictionaries. Also
+ added an instruction to support 'finally'-like clauses, exposed more of
+ the dict guts to the rest of the core, and defined a few tests to
+ exercise more obscure parts of the compiler's operation that were bugs
+ during development.
+
+2005-07-21 Kevin B. Kenny <kennykb@acm.org>
+
+ * library/ldAout.tcl (***REMOVED***): Removed support for ancient
+ * unix/configure: BSD's, IRIX 4, RISCos and
+ * unix/Makefile.in: Ultrix. Removed two files whose
+ * unix/tcl.m4: code is used only on those
+ * unix/tclLoadAout.c (***REMOVED***): antique platforms.
+
+ ***POTENTIAL INCOMPATIBILITY*** if anyone actually uses those
+ platforms; it is to be noted though, that an error in the installer has
+ actually not caused a necessary file to be installed on those platforms
+ in several releases, and nobody's complained.
+
+2005-07-16 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclStrToD.c (RefineResult): Plugged a stupid memory leak in
+ RefineResult (called from Tcl_StrToD). [Tk Bug 1227781]
+
+2005-07-15 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclClock.c (TclClockLocaltimeObjCmd,ThreadSafeLocalTime):
+ * library/clock.tcl (GuessWindowsTimeZone, ClearCaches):
+ * tests/clock.test (clock-49.1, clock-49.2):
+ Handle correctly the case where localtime() returns NULL to report a
+ conversion error. Also handle the case where the Windows registry
+ contains timezone values that can be mapped to a tzdata file name but
+ the corresponding file does not exist or is corrupted, by falling back
+ on a Posix timezone string instead; this last case will avoid calls to
+ localtime() in starpacks on Windows. [Bug 1237907]
+
+2005-07-14 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * generic/tclCompile.c: Update to follow style guidelines.
+ (TclPrintInstruction): Reorganize to do better printing out of bytecode
+ with far fewer "special hacks" for particular opcodes.
+ * generic/tclCompile.h: Requires two new opcode types.
+
+2005-07-13 Don Porter <dgp@users.sourceforge.net>
+
+ * unix/tclUnixSock.c: Use a ProcessGlobalValue to store the value
+ * win/tclWinSock.c: returned by Tcl_GetHostName() ([info
+ hostname]). Also re-order initialization of the value on Windows to
+ favor GetComputerName() over gethostname() as a source of the
+ information.
+
+2005-07-12 Kevin Kenny <kennykb@acm.org>
+
+ [kennykb-numerics-branch] Updated from HEAD
+
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd):
+ * generic/tclInt.h:
+ * generic/tclObj.c (Tcl_GetDoubleFromObj, SetDoubleFromAny)
+ (Tcl_GetIntFromObj, SetIntOrWideFromAny):
+ * generic/tclStrToD.c (TclParseNumber, etc.):
+ * tclTomMathInterface.c (TclBNInitBignumFromWideUInt):
+ * tests/obj.test (obj-1.1, obj-2.2, obj-3.1, obj-3.2):
+
+ Initial attempt at an implementation of TIP #249, comprising a unified
+ parser and modifications to the Tcl_Get*FromObj routines to use it.
+ Further integration of the parser is necessary and planned.
+
+2005-07-12 Donal K. Fellows <dkf@users.sf.net>
+
+ * doc/lsearch.n: Clarify documentation of -exact option; wording was
+ open to misinterpretation by non-English speakers.
+
+2005-07-11 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclExecute.c: General style cleanup.
+
+2005-07-08 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * generic/tclExecute.c (TclExecuteByteCode): Reimplement long and wide
+ type integer division and modulus operations so that the smallest and
+ largest integer values are handled properly. The divide operation is
+ more efficient since it no longer does a modulus or negation and only
+ checks for a remainder when the quotient will be a negative number.
+ The modulus operation is now a bit more complex because of a number of
+ special cases dealing with the smallest and largest integers.
+ * tests/expr.test: Add test cases for division and modulus operations
+ on the smallest and largest integer values for 32 and 64 bit types.
+ [Patch 1230205]
+
+2005-07-06 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclLink.c: Simplified LinkTraceProc [Bug 1208108].
+
+2005-07-05 Don Porter <dgp@users.sourceforge.net>
+
+ * unix/Makefile.in: Purged use of TCLTESTARGS [RFE 1161550].
+
+ * generic/tclUtil.c: Converted TclFormatInt() into a macro.
+ * generic/tclInt.decls: [RFE 1194015]
+ * generic/tclInt.h:
+
+ * generic/tclIntDecls.h: make genstubs
+ * generic/tclStubInit.c:
+
+ * generic/tclNamesp.c: Allow for [namespace import] of a command
+ * tests/namespace.test: over a previous [namespace import] of itself
+ without throwing an error. [RFE 1230597]
+
+2005-07-04 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclDictObj.c (DictForCmd, DictFilterCmd): Interlocking of
+ dictionary internal representations is now done in the core of the dict
+ iterator. Purge the last attempts at doing it at a higher level as they
+ didn't work and were no longer needed.
+
+2005-07-01 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+
+ * unix/tclUnixNotfy.c: protect against spurious wake-ups while waiting
+ on the condition variable when tearing down the notifier thread [Bug
+ 1222872].
+
+2005-06-28 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * generic/tclExecute.c (TclExecuteByteCode): When parsing an integer
+ operand for a unary minus expression operator, check for a wide integer
+ that is actually LONG_MIN. If found, convert back to a long int type.
+ * tests/expr.test: Add constraint for 32bit long int type and 64bit
+ wide int type. Add tests that parse the smallest/largest long int and
+ wide int values.
+
+2005-06-24 Kevin Kenny <kennykb@acm.org>
+
+ * generic/tclEvent.c (Tcl_Finalize):
+ * generic/tclInt.h:
+ * generic/tclPreserve.c (TclFinalizePreserve): Changed the finalization
+ logic so that Tcl_Preserve finalizes after exit handlers run; a lot of
+ code called from Tk's exit handlers presumes that Tcl_Preserve will
+ still work even from an exit handler.
+
+2005-06-24 Don Porter <dgp@users.sourceforge.net>
+
+ * library/auto.tcl: Make file safe to re-[source] without
+ destroying registered auto_mkindex_parser hooks.
+
+2005-06-23 Kevin Kenny <kennykb@acm.org>
+
+ * win/tclWinChan.c: More rewriting of __asm__ blocks that implement
+ * win/tclWinFCmd.c: SEH in GCC, because mingw's gcc 3.4.2 is not as
+ forgiving of violations committed by the old code and caused panics.
+ [Bug 1225957]
+
+2005-06-23 Daniel Steffen <das@users.sourceforge.net>
+
+ * tools/tcltk-man2html.tcl: fixed useversion glob pattern to accept
+ multi-digit patchlevels.
+
+2005-06-22 Don Porter <dgp@users.sourceforge.net>
+
+ * win/tclWinFile.c: Potential buffer overflow. [Bug 1225571] Thanks to
+ Pat Thoyts for discovery and fix.
+
+2005-06-22 Kevin Kenny <kennykb@acm.org>
+
+ * generic/tclInt.h: Changed the finalization
+ * generic/tclEvent.c (Tcl_Finalize): logic to defer the
+ * generic/tclIO.c (TclFinalizeIOSubsystem): shutdown of the pipe
+ * unix/tclUnixPipe.c (TclFinalizePipes): management until after all
+ * win/tclWinPipe.c (TclFinalizePipes): channels have been closed,
+ in order to avoid a situation where the Windows PipeCloseProc2 would
+ re-establish the exit handler after exit handlers had already run,
+ corrupting the heap. [Bug 1225727] Also corrected a potential read of
+ uninitialized memory in PipeClose2Proc [Bug 1225044]
+
+2005-06-21 Andreas Kupries <andreask@activestate.com>
+
+ * generic/tclInt.h: Followup to change made on 2005-06-18 by Daniel
+ Steffen. There are compilers (*) who error out on the redefinition of
+ WORDS_BIGENDIAN. We have to undef the previous definition (on the
+ command line) first to make this acceptable. (*): AIX native.
+
+2005-06-21 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclFileName.c: Changed [file split] and [file join] to treat
+ Windows drive letters similarly to ~ syntax and make sure that they
+ appear with "./" in front when they are in intermediate components of
+ the path. [Bug 1194458]
+ * tests/fileName.test: Added test for the above bug.
+
+2005-06-21 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c: Added missing walk of the list of active
+ * generic/tclTrace.c: traces to cleanup references to traces being
+ * generic/tclInt.h: deleted. [Bug 1201035] Made the walk of the
+ * tests/trace.test (trace-34.*): active trace list aware of the
+ direction of trace scanning, so the proper correction can be made.
+ [Bug 1224585]
+
+2005-06-21 Donal K. Fellows <dkf@users.sf.net>
+
+ * unix/tcl.m4 (SC_ENABLE_SYMBOLS): Only enable the 'compile' special
+ debugging feature when requested in configure.in; removes irrelevant
+ junk from the configure files of extensions that use Tcl's tcl.m4.
+
+2005-06-20 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCompile.h (INST_PUSH_RETURN_OPTIONS): New opcode to allow
+ * generic/tclCompCmds.c (TclCompileCatchCmd): compilation of
+ * generic/tclCompile.c: TIP#90 catch [Bug
+ * generic/tclExecute.c (TclExecuteByteCode): 1219112]
+
+ * generic/tclCompCmds.c (TclCompileSwitchCmd): Ensure we spill to the
+ command form in all cases where it generates an error.
+
+2005-06-20 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * generic/tclCmdMZ.c (Tcl_SwitchObjCmd): Generate an error if a mode
+ argument like -exact is passed more than once to the switch command.
+ The previous implementation silently accepted invalid switch
+ invocations like [switch -exact -glob $str ...].
+ * tests/for.test: Check some error cases when invoking continue and
+ break inside a for loop next script.
+ * tests/switch.test: Add checks for shortened version of a mode
+ argument like -exact. Add test for more than one mode argument. Add
+ test for odd case of passing a variable as a body script.
+
+2005-06-18 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tclInt.h: ensure WORDS_BIGENDIAN is defined correctly with
+ fat compiles on Darwin (i.e. ppc and i386 at the same time), the
+ configure AC_C_BIGENDIAN check is not sufficient in this case because a
+ single run of the compiler builds for two architectures with different
+ endianness.
+
+ * unix/tcl.m4 (Darwin): add -headerpad_max_install_names to LDFLAGS to
+ ensure we can always relocate binaries with install_name_tool.
+
+ * unix/configure: autoconf-2.59
+
+2005-06-18 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclCmdAH.c (Tcl_FormatObjCmd): Fix for [Bug 1154163]; only
+ * tests/format.test: insert 'l' modifier when it is needed.
+
+2005-06-17 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclTimer.c (AfterDelay): Split out the code to manage
+ synchronous-delay [after] commands.
+ * tests/interp.test (interp-34.10): Time limits and synch-delay [after]
+ did not mix well... [Bug 1221395]
+
+2005-06-14 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclBasic.c (Tcl_DeleteCommandFromToken): Only delete a
+ * tests/namespace.test (namespace-49.2): command from the hashtable on
+ reentrant processing if it has not been already deleted; at least three
+ deletes of the same command are possible. [Bug 1220058]
+ * generic/tclTrace.c (TraceCommandProc): Remove bogus error message
+ creation when traces trigger in situations where the command has
+ already been deleted.
+
+2005-06-13 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclFCmd.c: correct fix to file mkdir 2005-06-09 [Bug 1219176]
+
+2005-06-12 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCompCmds.c: Factor out some common idioms into named forms
+ for greater clarity.
+
+2005-06-10 Donal K. Fellows <dkf@users.sf.net>
+
+ * doc/chan.n: Fold in the descriptive parts of the documentation for
+ all the commands that [chan] builds on top of.
+
+2005-06-09 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclFCmd.c: fix to race condition in file mkdir [Bug 1217375]
+ * doc/glob.n: improve glob documentation [Bug 1190891]
+
+2005-06-09 Donal K. Fellows <dkf@users.sf.net>
+
+ * doc/expr.n, doc/mathfunc.n: Fix minor typos [Bug 1211078] and add
+ mention of distinctly-relevant [namespace path] subcommand.
+
+2005-06-07 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclInt.h: Reduced the Tcl_ObjTypes "index",
+ * generic/tclIndexObj.c: "ensembleCmd", "localVarName", and
+ * generic/tclNamesp.c: "levelReference" to file static scope.
+ * generic/tclProc.c:
+ * generic/tclVar.c:
+
+ * generic/tclObj.c: Restored registration of the "procbody"
+ Tcl_ObjType, as required by the tclcompiler application.
+
+ * generic/tclDecls.h: make genstubs
+ * generic/tclStubInit.c:
+
+2005-06-07 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclIO.c (Tcl_ChannelTruncateProc): Stop proliferation of
+ * generic/tcl.h: channel type versions
+ * doc/CrtChannel.3: following advice from AKu
+
+ Bump patchlevel to a4 to distinguish from a3 release.
+
+ * generic/tclInt.h (INTERP_TRACE_IN_PROGRESS): Add flag so the error
+ * generic/tclIndexObj.c (Tcl_WrongNumArgs): messages from ensembles
+ * generic/tclIOCmd.c (Tcl_ReadObjCmd): can be correct.
+
+ TIP#208 IMPLEMENTATION
+
+ * library/init.tcl: Create the chan ensemble.
+ * tests/chan.test: Rudimentary test suite.
+ * doc/chan.n: General documentation.
+
+ TRUNCATION API (part of TIP#208)
+ * generic/tcl.h, generic/tcl.decls: Declaration of the API.
+ * doc/CrtChannel.3, doc/OpenFileChnl.3: Documentation of the API.
+ * generic/tclBasic.c (Tcl_CreateInterp): Create the mapping into Tcl.
+ * generic/tclIOCmd.c (TclChanTruncateObjCmd): Implementation of
+ Tcl-level truncation API.
+ * generic/tclIO.c (Tcl_TruncateChannel): Generic C-level truncation API
+ implementation.
+ * unix/tclUnixChan.c (FileTruncateProc): Basic implementation of
+ truncating driver.
+
+ * win/tclWinChan.c (FileTruncateProc): Added implementation of file
+ truncation for Windows.
+ * tests/chan.test (chan-15.2): Added real test of truncation.
+
+2005-06-06 Kevin B. Kenny <kennykb@acm.org>
+
+ * win/tclWin32Dll.c: Corrected another buglet in the assembly code for
+ stack probing on Win32/gcc. [Bug 1213678]
+ * generic/tclObj,c: Added missing 'static' on definition of
+ UpdateStringOfBignum, and removed a 'switch' on a 'long long' operand
+ (which HP-UX native 'cc' seems unable to handle). [Bug 1215775]
+
+2005-06-04 Jeff Hobbs <jeffh@ActiveState.com>
+
+ *** 8.5a3 TAGGED FOR RELEASE ***
+
+ * unix/Makefile.in (dist): add libtommath
+
+2005-06-03 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * library/parray.tcl (parray): Only generate the sorted list of element
+ names once. Thanks to Andreas Leitgeb for spotting this.
+
+2005-06-03 Daniel Steffen <das@users.sourceforge.net>
+
+ * macosx/Makefile: fixed 'embedded' target.
+
+2005-06-02 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/Makefile.in (html): add BUILD_HTML_FLAGS optional var
+ * tools/tcltk-man2html.tcl: add a --useversion to prevent confusion
+ when multiple Tcl source dirs exist.
+
+2005-06-01 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c: For compatibility with earlier Tcl releases,
+ * generic/tclResult.c: when a command procedure simply does a
+ * generic/tclTest.c: "return TCL_RETURN;" we must interpret that
+ * tests/result.test: the same as
+ "return Tcl_SetReturnOptions(interp, Tcl_NewObj());" [Bug 1209759].
+
+2005-06-01 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclCompCmds.c (TclCompileSwitchCmd): Allow compilation of
+ -nocase -glob [switch]es (only one we know how to compile).
+
+ TIP#241 IMPLEMENTATION from Joe Mistachkin
+
+ * generic/tclCmdIL.c (Tcl_LsearchObjCmd, Tcl_LsortObjCmd):
+ * generic/tclCmdMZ.c (Tcl_SwitchObjCmd): Implementation of -nocase
+ option for [lsearch], [lsort] and [switch] commands.
+ * win/tclWinPort.h: Win uses nonstandard function names...
+ * tests/cmdIL.test, tests/lsearch.test, tests/switch.test: Tests
+ * doc/lsearch.n, doc/lsort.n, doc/switch.n: Docs
+
+ * generic/tclCompCmds.c (TclCompileLindexCmd): Compile the most common
+ case of [lindex] more efficiently.
+
+ * unix/tclUnixNotfy.c (Tcl_FinalizeNotifier): Pass the correct number
+ of arguments to Tcl_JoinThread.
+
+2005-05-31 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * unix/configure.in, unix/tcl.m4: Standardize generation of help
+ messages to always use AC_HELP_STRING and always (except for --with-tcl
+ and --with-tk, where the default is complex) say what the default is.
+
+2005-05-31 Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+
+ * unix/tclUnixNotfy.c: the notifier thread is now created as joinable
+ thread and it is properly joined in Tcl_FinalizeNotifier. This is an
+ attempt to fix the [Bug 1082283].
+
+2005-05-30 Zoran Vasiljevic <vasiljevic@users.sf.net>
+
+ * win/tclWinThrd.c: Fixed [Bug 1204064]
+
+2005-05-30 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ TIP #229 IMPLEMENTATION
+
+ * generic/tclNamesp.c (Tcl_FindCommand, TclResetShadowedCmdRefs)
+ (NamespacePathCmd, SetNsPath, UnlinkNsPath, TclInvalidateNsPath):
+ Implementation of the [namespace path] command and the command name
+ resolution engine.
+ * doc/info.n, doc/namespace.n: Doc updates.
+ * tests/namespace.test (namespace-51.*): Test updates.
+ * generic/tclResolve.c (BumpCmdRefEpochs, Tcl_SetNamespaceResolvers):
+ * generic/tclBasic.c (Tcl_CreateCommand, Tcl_CreateObjCommand): Ensure
+ that people don't see stale paths.
+ * generic/tclInt.h (Namespace, NamespacePathEntry): Structure defs.
+ * generic/tclCmdIL.c (InfoCommandsCmd): Updates to [info commands].
+
+2005-05-26 Daniel Steffen <das@users.sourceforge.net>
+
+ * macosx/Makefile: moved & corrected EMBEDDED_BUILD check.
+
+ * unix/configure.in: corrected framework finalization to softlink stub
+ library to Versions/8.x subdir instead of Versions/Current.
+ * unix/configure: autoconf-2.59
+
+2005-05-25 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclCmdMZ.c (Tcl_TimeObjCmd): add necessary cast
+
+2005-05-25 Don Porter <dgp@users.sourceforge.net>
+
+ TIP#182 IMPLEMENTATION [Patch 1165062]
+
+ * doc/mathfunc.n: New built-in math function bool().
+ * generic/tclBasic.c:
+ * tests/expr.test:
+ * tests/info.test:
+
+2005-05-24 Don Porter <dgp@users.sourceforge.net>
+
+ * library/init.tcl: Updated [unknown] to be sure the [return]
+ * tests/init.test: options from an auto-loaded command are seen
+ correctly by the caller.
+
+2005-05-24 Daniel Steffen <das@users.sourceforge.net>
+
+ * tests/env.test: added DYLD_FRAMEWORK_PATH to the list of env vars
+ that need to be handled specially.
+
+ * macosx/Makefile:
+ * macosx/README:
+ * macosx/Tcl-Info.plist.in (new file):
+ * unix/Makefile.in:
+ * unix/configure.in:
+ * unix/tcl.m4:
+ * unix/tclUnixInit.c: moved all Darwin framework build support from
+ macosx/Makefile into the standard unix configure/make buildsystem, the
+ macosx/Makefile is no longer required to build Tcl.framework (but its
+ functionality is still available for backwards compatibility).
+ * unix/configure: autoconf-2.59
+
+ * generic/tclIOUtil.c (TclLoadFile):
+ * generic/tclInt.h:
+ * unix/tcl.m4:
+ * unix/tclLoadDyld.c: added support for [load]ing .bundle binaries in
+ addition to .dylib's: .bundle's can be [unload]ed (unlike .dylib's),
+ and can be [load]ed from memory, e.g. directly from VFS without needing
+ to be written out to a temporary location first. [Bug 1202209]
+ * unix/configure: autoconf-2.59
+ * unix/tclConfig.h.in: autoheader-2.59
+
+ * generic/tclCmdMZ.c (Tcl_TimeObjCmd): change [time] called with a
+ count > 1 to return a string with a float value instead of a rounded
+ off integer. [Bug 1202178]
+
+ * doc/expr.n:
+ * doc/string.n: fixed roff syntax complaints from 'make html'.
+
+2005-05-20 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclParseExpr.c: Corrected parser to recognize all
+ boolean literals accepted by Tcl_GetBoolean, including prefixes like
+ "y" and "f", and to allow "eq" and "ne" as function names in the proper
+ context. [Bug 1201589].
+
+2005-05-19 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclBasic.c (TclEvalObjvInternal): Rewrite for greater
+ clarity; although 'goto' is Bad, the contortions you have to go through
+ to avoid it can be worse...
+
+2005-05-19 Daniel Steffen <das@users.sourceforge.net>
+
+ * macosx/tclMacOSXNotify.c (Tcl_InitNotifier): fixed crashing CFRelease
+ of runLoopSource in Tcl_InitNotifier (reported by Zoran):
+ CFRunLoopAddSource doesn't CFRetain, so can only CFRelease the
+ runLoopSource in Tcl_FinalizeNotifier.
+
+2005-05-18 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c (Tcl_ExprBoolean): Rewrite as wrapper around
+ Tcl_ExprBooleanObj.
+
+ * generic/tclCmdMZ.c ([string is boolean/true/false]): Rewrite dropping
+ string-based Tcl_GetBoolean call, so that internal reps are kept for
+ subsequent quick boolean operations.
+
+ * generic/tclExecute.c: Dropped most special handling of the "boolean"
+ Tcl_ObjType, since that type should now be rarely encountered.
+
+ * doc/BoolObj.3: Rewrite of documentation dropping many details
+ about the internals of Tcl_Objs. Shorter documentation focuses on the
+ function and use of the routines.
+
+ * generic/tclInt.h: Revision to the "boolean" Tcl_ObjType, so that
+ * generic/tclObj.c: only string values like "yes" and "false" are
+ * tests/obj.test: kept as the "boolean" Tcl_ObjType. The string
+ values "0" and "1" are kept as "int" Tcl_ObjType, which also produce
+ quick calls to Tcl_GetBooleanFromObj(). Since this internal change
+ means a Tcl_ConvertToType to a "boolean" Tcl_ObjType might not produce
+ a Tcl_Obj of type "boolean", the registration of the "boolean" type is
+ also removed.
+ ***POTENTIAL INCOMPATIBILITY***
+ For callers of Tcl_GetObjType on the type name "boolean".
+
+2005-05-17 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclObj.c (TclInitObjSubsystem): Removed the
+ * tests/listObj.test: registration of the Tcl_ObjType's "list",
+ * tests/obj.test: "procbody", "index", "ensembleCommand",
+ "localVarName", and "levelReference". The only reason to register a
+ Tcl_ObjType is to have it returned by Tcl_GetObjType, and the only
+ reason for that is to retrieve a (Tcl_ObjType *) to pass to
+ Tcl_ConvertToType(). None of the types above can support a
+ Tcl_ConvertToType() call; they panic. Better not to offer something
+ than to lead users into a panic.
+ ***POTENTIAL INCOMPATIBILITY***
+ For callers of Tcl_GetObjType on the type names listed above.
+
+2005-05-15 Kevin Kenny <kennykb@users.sourceforge.net>
+
+ * win/tclWin32Dll.c: conditioned definition of EXCEPTION_REGISTRATION
+ structures on HAVE_NO_SEH, to fix a bug in buildability on MSVC.
+
+2005-05-14 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tclInt.decls:
+ * generic/tclTest.c:
+ * generic/tclUtil.c:
+ * win/tclWin32Dll.c: fixed link error due to direct access by tclTest.c
+ to the MODULE_SCOPE tclPlatform global: renamed existing
+ TclWinGetPlatform() accessor to TclGetPlatform() and moved it to
+ generic code so that it can be used by on all platforms where
+ MODULE_SCOPE is enforced.
+
+ * macosx/tclMacOSXBundle.c:
+ * unix/tclUnixInit.c:
+ * unix/tcl.m4 (Darwin): made use of CoreFoundation API configurable and
+ added test of CoreFoundation availablility to allow building on ppc64,
+ replaced HAVE_CFBUNDLE by HAVE_COREFOUNDATION; test for availability of
+ Tiger or later OSSpinLockLock API.
+
+ * unix/tclUnixNotfy.c:
+ * unix/Makefile.in:
+ * macosx/tclMacOSXNotify.c (new file): when CoreFoundation is
+ available, use new CFRunLoop based notifier: allows easy integration
+ with other event loops on Mac OS X, in particular the TkAqua Carbon
+ event loop is now integrated via a standard tcl event source (instead
+ of TkAqua upon loading having to finalize the exsting notifier and
+ replace it with its custom version). [Patch 1202052]
+
+ * tests/unixNotfy.test: don't run unthreaded tests on Darwin since
+ notifier may be using threads even in unthreaded core.
+
+ * unix/tclUnixPort.h:
+ * unix/tcl.m4 (Darwin): test for thread-unsafe realpath during
+ configure, as Darwin 7 and later realpath is threadsafe.
+
+ * macosx/Makefile: enable configure caching.
+
+ * unix/configure.in: wrap tclConfig.h header in #ifndef _TCLCONFIG so
+ that it can be included more than once without warnings from gcc4.0 (as
+ happens e.g. when including both tclInt.h and tclPort.h)
+
+ * macosx/tclMacOSXBundle.c:
+ * unix/tclUnixChan.c:
+ * unix/tclLoadDyld.c:
+ * unix/tclUnixInit.c: fixed gcc 4.0 warnings.
+
+ * unix/configure: autoconf-2.59
+ * unix/tclConfig.h.in: autoheader-2.59
+
+ * generic/tclIntDecls.h:
+ * generic/tclIntPlatDecls.h:
+ * generic/tclStubInit.c: make genstubs
+
+2005-05-13 Kevin Kenny <kennykb@acm.org>
+
+ * win/tclWin32Dll.c: Further rework of the SEH logic. All
+ EXCEPTION_REGISTRATION records are now in the activation record rather
+ than pushed on the stack.
+
+2005-05-13 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c: Dropped the TCL_NO_MATH configuration. It's
+ * generic/tclBinary.c: believed this has not been working in a long
+ * generic/tclExecute.c: time. Tcl needs math.h. [RFE 1200680]
+ * unix/Makefile.in:
+
+2005-05-12 Kevin Kenny <kennykb@acm.org>
+
+ * doc/mathfunc.n: Changed NAME line to match the name of the page.
+
+2005-05-11 Kevin Kenny <kennykb@acm.org>
+
+ [kennykb-numerics-branch] Resynchronized with the HEAD; at this
+ checkpoint [-rkennykb-numerics-branch-20050511], the HEAD and
+ kennykb-numerics-branch contain identical code.
+
+2005-05-11 Kevin Kenny <kennykb@acm.org>
+
+ * generic/tclStrToD.c (TclStrToD, RefineResult, ParseNaN): Changed the
+ code to cast 'char' to UCHAR explicitly when using ctype macros, to
+ silence complaints from the Solaris compiler.
+
+2005-05-10 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/tclUnixFCmd.c: add lint attr to enum to satisfy strictly
+ compliant compilers that don't like trailing ,s.
+
+ * tests/string.test: string-10.[21-30]
+ * generic/tclCmdMZ.c (Tcl_StringObjCmd): add extra checks to prevent
+ possible UMR in unichar cmp function for string map.
+
+2005-05-10 Kevin Kenny <kennykb@acm.org>
+
+ * generic/tclBinary.c (FormatNumber): Fixed a bug where NaN's resulted
+ in reads of uninitialized memory when using 'd', 'q', or 'Q' format.
+ * generic/tclStrToD.c (ParseNaN, TclFormatNaN): Added code to handle
+ the peculiarities of HP's PA_RISC, which uses a different 'quiet' bit
+ in NaN from everyone else.
+ * libtommath/tommath_superclass.h: Corrected C++-style comment.
+
+2005-05-10 Kevin Kenny <kennykb@acm.org>
+
+ Merged all changes on kennykb-numerics-branch back into the HEAD.
+ TIP's 132 and 232 are now Final.
+
+2005-05-10 Kevin Kenny <kennykb@acm.org>
+
+ [kennykb-numerics-branch] Merged changes from HEAD.
+
+2005-05-10 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c (ExponLong, ExponWide):
+ * tests/expr.test (expr-23.34/35): fixed special case 'i**0' for i>0
+ [Bug 1198892]
+
+2005-05-09 Kevin B. Kenny <kennykb@acm.org>
+
+ [kennykb-numerics-branch]
+ * win/tclWin32Dll.c (TclpCheckStackSpace, TclWinCPUID): Reworked
+ structured event handling to function even with -fomit-frame-pointers.
+
+2005-05-08 Kevin B. Kenny <kennykb@acm.org>
+
+ [kennykb-numerics-branch]
+ * generic/tclStrToD.c: Made code more portable by finding a workaround
+ for MSVC's 'volatile' issue that does not require conditional
+ compilation.
+ * win/tclWin32Dll.c (TclWinCPUID): Removed structured event handling
+ from the GCC code since (a) bad code is generated by the instruction
+ scheduling with -O2, and (b) it's not needed on any reasonably modern
+ CPU.
+
+2005-05-07 Kevin B. Kenny <kennykb@acm.org>
+
+ [kennykb-numerics-branch]
+ * generic/tclEvent.c: Moved initialization of tclStrToD.c's
+ * generic/tclInt.h: static constants into a procedure called
+ * generic/tclStrToD.c: from TclInitSubsystems to avoid double checked
+ locking protocol. Cleaned up an issue where MSVC ignored the
+ 'volatile' specifier, causing incorrect comparison of an underflowed
+ number against zero.
+
+2005-05-06 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/tcl.m4, unix/configure: correct Solaris 10 (5.10) check and add
+ support for x86_64 Solaris cc builds.
+
+2005-05-05 Kevin B. Kenny <kennykb@acm.org>
+
+ [kennykb-numerics-branch] Merged with HEAD.
+
+2005-05-05 Kevin B. Kenny <kennykb@acm.org>
+
+ * win/tclWinThrd.c: Corrected a compilation error on the
+ --enable-threads configuration.
+
+2005-05-05 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclInt.decls: Converted TclMatchIsTrivial to a macro.
+ * generic/tclInt.h:
+ * generic/tclUtil.c:
+ * generic/tclIntDecls.h: `make genstubs`
+ * generic/tclStubInit.c:
+ * generic/tclBasic.c: Added callers of TclMatchIsTrivial where a
+ * generic/tclCmdIL.c: search can be done more efficiently when it is
+ * generic/tclCompCmds.c:recognized that a pattern match is really an
+ * generic/tclDictObj.c: exact match. [Patch 1076088]
+ * generic/tclIO.c:
+ * generic/tclNamesp.c:
+ * generic/tclVar.c:
+
+ * generic/tclCompCmds.c: Factored common efficiency trick into a
+ macro named CompileWord.
+
+ * generic/tclCompCmds.c: Replaced all instance of
+ * generic/tclCompile.c: TCL_OUT_LINE_COMPILE with TCL_ERROR.
+ * generic/tclInt.h: Now that we've eradicated the mistaken
+ * tests/appendComp.test: notion of a "compile-time error", we
+ can use the TCL_ERROR return code to signal any failure to produce
+ bytecode.
+
+2005-05-03 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/DString.3: Eliminated use of identifier "string" in Tcl's
+ * doc/Environment.3: public C API to avoid conflict/confusion with
+ * doc/Eval.3: the std::string of C++.
+ * doc/ExprLong.3, doc/ExprLongObj.3, doc/GetInt.3, doc/GetOpnFl.3:
+ * doc/ParseCmd.3, doc/RegExp.3, doc/SetResult.3, doc/StrMatch.3:
+ * doc/Utf.3, generic/tcl.decls, generic/tclBasic.c, generic/tclEnv.c:
+ * generic/tclGet.c, generic/tclParse.c, generic/tclParseExpr.c:
+ * generic/tclRegexp.c, generic/tclResult.c, generic/tclUtf.c:
+ * generic/tclUtil.c, unix/tclUnixChan.c:
+
+ * generic/tclDecls.h: `make genstubs`
+
+2005-05-02 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tcl.decls:
+ * generic/tclBasic.c: Simplified implementation of Tcl_ExprString.
+ * tests/expr-old.test:
+
+ * generic/tclDecls.h: `make genstubs`
+
+2005-04-30 Daniel Steffen <das@users.sourceforge.net>
+
+ * unix/tclUnixNotfy.c: applied dkf's tkMacOSXNotify.c cleanup changes.
+
+2005-04-29 Don Porter <dgp@users.sourceforge.net>
+
+ TIP#176 IMPLEMENTATION [Patch 1165695]
+
+ * generic/tclUtil.c: Extended TclGetIntForIndex to recognize index
+ formats including end+integer and integer+/-integer.
+
+ * generic/tclCmdMZ.c: Extended the -start switch of [regexp] and
+ [regsub] to accept all index formats known by TclGetIntForIndex.
+
+ * doc/lindex.n: Updated docs to note new index formats.
+ * doc/linsert.n, doc/lrange.n, doc/lreplace.n, doc/lsearch.n:
+ * doc/lset.n, doc/lsort.n, doc/regexp.n, doc/regsub.n, doc/string.n:
+
+ * tests/cmdIL.test: Updated tests.
+ * tests/compile.test, tests/lindex.test, tests/linsert.test:
+ * tests/lrange.test, tests/lreplace.test, tests/lsearch.test:
+ * tests/lset.test, tests/regexp.test, tests/regexpComp.test:
+ * tests/string.test, tests/stringComp.test, tests/util.test:
+
+2005-04-28 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/unixInit.test (7.1): Alternative fix for the 2004-11-11 commit.
+
+2005-04-27 Don Porter <dgp@users.sourceforge.net>
+
+ * library/init.tcl: Corrected flaw in interactive command
+ * tests/main.test: auto-completion. [Bug 1191409].
+
+ TIP#183 IMPLEMENTATION [Patch 577093]
+
+ * generic/tclIOUtil.c (TclGetOpenModeEx): New routine.
+ * generic/tclInt.h:
+
+ * generic/tclIO.c (Tcl_OpenObjCmd): Support for "b" and
+ * doc/open.n: "BINARY" in "access" argument to [open].
+ * tests/ioCmd.test:
+
+2005-04-26 Kevin B. Kenny <kennykb@users.sourceforge.net>
+
+ * generic/tclBinary.c (FormatNumber): Dredge the NaN out of the
+ internal representation if Tcl_GetDoubleFromObj returns TCL_ERROR on a
+ NaN.
+
+ * generic/tclObj.c (Tcl_GetDoubleFromObj): Restored silent
+ overflow/underflow behaviour that the merge of 2004-04-25 messed up.
+ Thanks to Don Porter for calling attention to this bug. Also removed an
+ uninitialised memory reference in this function that valgrind caught.
+ Also changed to return TCL_ERROR on a pure NaN.
+
+ * generic/tclStrToD.c (RefineResult): Added a test for the initial
+ approximation being HUGE_VAL; this test avoids EDOM being returned from
+ ldexp on some platforms on input values exceeding the floating point
+ range.
+
+ * tests/expr.test (expr-29.*, expr-30.*): Added further tests of
+ overflow/underflow on input conversions.
+
+2005-04-25 Kevin B. Kenny <kennykb@users.sourceforge.net>
+
+ [kennykb-numerics-branch] Merged with HEAD.
+
+ * doc/CrtMathFunc.n: Revised documentation for TIP 232
+
+2005-04-25 Daniel Steffen <das@users.sourceforge.net>
+
+ * compat/string.h: fixed memchr() protoype for __APPLE__ so that we
+ build on Mac OS X 10.1 again.
+
+ * generic/tclNotify.c (TclFinalizeNotifier): fixed notifier not being
+ finalized in unthreaded core (was testing for notifier initialization
+ in current thread by checking thread id != 0 but thread id is always 0
+ in untreaded core).
+
+ * win/tclWinNotify.c (Tcl_WaitForEvent):
+ * unix/tclUnixNotfy.c (Tcl_WaitForEvent): don't call ScaleTimeProc for
+ zero wait times (as specified in TIP 233).
+
+ * unix/Makefile.in: added @PLAT_SRCS@ to SRCS and split out NOTIFY_SRCS
+ from UNIX_SRCS for parity with UNIX_OBJS & NOTIFY_OBJS.
+
+ * unix/tcl.m4 (Darwin): added configure checks for recently added
+ linker flags -single_module and -search_paths_first to allow building
+ with older tools (and on Mac OS X 10.1), use -single_module in SHLIB_LD
+ and not just T{CL,K}_SHLIB_LD_EXTRAS, added unexporting from Tk of
+ symbols from libtclstub to avoid duplicate symbol warnings, added
+ PLAT_SRCS definition for Mac OS X, defined MODULE_SCOPE to
+ __private_extern__.
+ (SC_MISSING_POSIX_HEADERS): added caching of dirent.h check.
+
+ * unix/configure: autoconf-2.59
+
+2005-04-25 Kevin B. Kenny <kennykb@users.sourceforge.net>
+
+ * library/tzdata/America/Boise:
+ * library/tzdata/America/Chicago:
+ * library/tzdata/America/Denver
+ * library/tzdata/America/Indianapolis:
+ * library/tzdata/America/Los_Angeles:
+ * library/tzdata/America/Louisville:
+ * library/tzdata/America/Managua:
+ * library/tzdata/America/New_York:
+ * library/tzdata/America/Phoenix:
+ * library/tzdata/America/Port-au-Prince:
+ * library/tzdata/America/Indiana/Knox:
+ * library/tzdata/America/Indiana/Marengo:
+ * library/tzdata/America/Indiana/Vevay:
+ * library/tzdata/America/Kentucky/Monticello:
+ * library/tzdata/America/North_Dakota/Center:
+ * library/tzdata/Asia/Tehran:
+ Olson's tzdata2005i. Corrects exact time at which Standard Time was
+ adopted in the US (generally, noon, Standard Time, rather than noon,
+ Local Mean Time). Adopts new civil rules for Nicaragua and Iran.
+
+2005-04-25 Don Porter <dgp@users.sourceforge.net>
+
+ * library/init.tcl: Use "ni" and "in" operators.
+
+2005-04-25 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c: fix for [Bug 1189274].
+
+2005-04-24 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclLiteral.c: Silence compiler warnings.
+ * generic/tclObj.c: [Bug 1188863].
+
+2005-04-22 Don Porter <dgp@users.sourceforge.net>
+
+ The 2005-04-21 changes to Tcl_GetBooleanFromObj were done to bring it
+ into agreement with its docs. Further investigation reveals it was the
+ docs that were incorrect.
+
+ * doc/BoolObj.3: Corrections to the documentation of
+ Tcl_GetBooleanFromObj to bring it into agreement with what this public
+ interface has always done, including noting the difference in function
+ between Tcl_GetBooleanFromObj and Tcl_GetBoolean.
+
+ * generic/tclGet.c: Revised Tcl_GetBoolean to no longer be a
+ wrapper around Tcl_GetBooleanFromObj (different function!).
+
+ * generic/tclObj.c: Removed TclGetTruthValueFromObj routine that
+ was added yesterday. Revisions so that only Tcl_GetBoolean-approved
+ values get the "boolean" Tcl_ObjType. This retains the fix for [Bug
+ 1187123].
+ * tests/string.test: Test string-23.0 for Bug 1187123.
+
+ * generic/tclInt.h: Revert most recent change.
+ * generic/tclBasic.c:
+ * generic/tclCompCmds.c:
+ * generic/tclDictObj.c:
+ * generic/tclExecute.c:
+ * tests/obj.test:
+
+2005-04-21 Don Porter <dgp@users.sourceforge.net>
+
+ * doc/GetInt.3: Convert argument "string" to "str" to agree with code.
+ Also clarified a few details on int and double formats.
+ * generic/tclGet.c: Radical code simplification. Converted
+ Tcl_GetFoo() routines into wrappers around Tcl_GetFooFromObj(). Reduces
+ code duplication, and the resulting potential for inconsistency.
+
+ * generic/tclObj.c: Several changes:
+
+ - Re-ordered error detection code so all values with trailing garbage
+ receive a "not an integer" message instead of an "integer too large"
+ message.
+ - Removed inactive code meant to deal with strtoul* routines that fail
+ to parse leading signs. All of them do, and if any are detected that
+ do not, the correct fix is replacement with compat/strtoul*.c, not a
+ lot of special care by the callers.
+ - Tcl_GetDoubleFromObj now avoids shimmering away a "wideInt" intrep.
+ - Fixed Tcl_GetBooleanFromObj to agree with its documentation and with
+ Tcl_GetBoolean, accepting only "0" and "1" and not other numeric
+ strings. [Bug 1187123]
+ - Added new private routine TclGetTruthValueFromObj to perform the more
+ permissive conversion of numeric values to boolean that is needed by
+ the [expr] machinery.
+
+ * generic/tclInt.h (TclGetTruthValueFromObj): New routine.
+ * generic/tclExecute.c: Updated callers to call new routine.
+ * generic/tclBasic.c: Updated callers to call new routine.
+ * generic/tclCompCmds.c: Updated callers to call new routine.
+ * generic/tclDictObj.c: Updated callers to call new routine.
+ * tests/obj.test: Corrected bad tests that actually expected
+ values like "47" and "0xac" to be accepted as booleans.
+
+ * generic/tclLiteral.c: Disabled the code that forces some literals
+ into the "int" Tcl_ObjType during registration. We can re-enable it if
+ this change causes trouble, but it seems more sensible to let Tcl's
+ "on-demand" shimmering rule, and not try to pre-guess things.
+
+2005-04-20 Kevin B. Kenny <kennykb@acm.org>
+
+ [kennykb-numerics-branch]
+ * doc/expr.n:
+ * doc/mathfunc.n (new file): Revised documentation for TIP 232
+
+2005-04-20 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclGet.c (Tcl_GetInt): Corrected error that did not
+ * generic/tclObj.c (Tcl_GetIntFromObj): permit 0x80000000 to be
+ recognized as an integer on TCL_WIDE_INT_IS_LONG systems [Bug 1090869].
+
+2005-04-20 Kevin B. Kenny <kennykb@acm.org>
+
+ * generic/tclFileName.c: Silenced a compiler warning about '/*' within
+ a comment.
+
+2005-04-19 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c: Added unsupported command
+ * generic/tclCmdAH.c: [::tcl::unsupported::EncodingDirs] to permit
+ * generic/tclInt.h: query/set of the encoding search path at
+ * generic/tclInterp.c: the script level. Updated init.tcl to make
+ * library/init.tcl: use of the new command. Also updated several
+ coding practices in init.tcl ("eq" for [string equal], etc.)
+
+2005-04-19 Kevin B. Kenny <kennykb@acm.org>
+
+ * library/clock.tcl (Initialize): Put initialization code into a proc
+ to avoid inadvertently clobbering global variables. [Bug 1185933]
+ * tests/clock.test (clock-48.1): Added regression test for the above
+ bug.
+ Thanks to Ulrich Ring for reporting this bug.
+
+2005-04-16 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/Var.c (Tcl_ArrayObjCmd - ARRAY_NAMES): fix Tcl_Obj leak. [Bug
+ 1084111]
+
+2005-04-16 Zoran Vasiljevic <vasiljevic@users.sf.net>
+
+ * generic/tclIOUtil.c: force clenaup of the interp result in
+ TclLoadFile(). Some implementations of TclpFindSymbol() will seed the
+ interp result with error message when unable to find the requested
+ symbol (this is not considered to be an error).
+
+ Set of changes correcting huge memory waste (not a leak) when a thread
+ exits. This has been introduced in 8.4.7 within an attempt to correctly
+ cleanup after ourselves when Tcl library is being unloaded with the
+ Tcl_Finalize() call.
+
+ This fixes the [Bug 1178445]
+
+ * generic/tclInt.h: added prototypes for TclpFreeAllocCache() and
+ TclFreeAllocCache()
+
+ * generic/tclThreadAlloc.c: modified TclFinalizeThreadAlloc() to
+ explicitly call TclpFreeAllocCache with the NULL-ptr as argument
+ signalling cleanup of private tsd key used only by the threading
+ allocator.
+
+ * unix/tclUnixThrd.c: fixed TclpFreeAllocCache() to recognize when
+ being called with NULL argument. This is a signal for it to clean up
+ the tsd key associated with the threading allocator.
+
+ * win/tclWinThrd.c: renamed TclWinFreeAllocCache to TclpFreeAllocCache
+ and fixed to recognize when being called with NULL argument. This is a
+ signal for it to clean up the tsd key associated with the threading
+ allocator.
+
+2005-04-13 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/unixInit.test: Disabled obsolete tests and removed code
+ * tests/encoding.test: that supported them.
+ * generic/tclInterp.c:
+
+ * library/init.tcl: Use auto-loading to bring in Tcl Module support
+ * library/tclIndex: as needed. This reduces startup time by
+ * library/tm.tcl: delaying this initialization to a later time.
+
+2005-04-15 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c: missing semicolons caused failure to compile
+ with TCL_COMPILE_DEBUG.
+
+2005-04-13 David Gravereaux <davygrvy@pobox.com>
+
+ * generic/tclIO.c (Tcl_SetChannelBufferSize): Lowest size limit
+ * tests/io.test: changed from ten bytes to one byte. Need for
+ * tests/iogt.test: this change was proven by Ross Cartlidge
+ <rossc@cisco.com> where [read stdin 1] was grabbing 10 bytes followed
+ by starting a child process that was intended to continue reading from
+ stdin. Even with -buffersize set to one, nine chars were getting lost
+ by the buffersize over reading for the native read() caused by [read].
+
+2005-04-13 Don Porter <dgp@users.sourceforge.net>
+
+ * unix/tclUnixInit.c (TclpGetEncodingNameFromEnvironment): Reversed
+ order of verifying candidate [encoding system] value, checking against
+ a table in memory first before calling Tcl_GetEncoding and potentially
+ scanning through the filesystem. Also ordered the table so that a
+ binary search could be used within it. Improves startup time a bit more
+ on some systems.
+
+2005-04-13 Kevin B. Kenny <kennykb@acm.org>
+
+ * library/clock.n: Added a missing '--' on several [switch] commands to
+ improve performance of [clock format] and related operations. [FRQ
+ 1182459]
+
+2005-04-13 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * doc/fcopy.n: Improved documentation on copying binary files, added an
+ example and mentioned the use of [file copy].
+ * doc/fconfigure.n: Improved documentation of -encoding binary option.
+ This is all following comments from Steve Manning <steve@manning.net>
+ on comp.lang.tcl that the current documentation was not clear.
+
+2005-04-13 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompile.c:Commented out the functions
+ TclPrintInstruction(), TclPrintObject() and TclPrintSource() when not
+ debugging the compiler, as they are never called in that case.
+
+2005-04-12 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclInterp.c: Corrected bad syntax of Tcl_Panic() call.
+
+ * generic/tclUtil.c (TclGetProcessGlobalValue): More robust handling
+ of bad TclInitProcessGlobalValueProc behavior; an immediate panic
+ rather than a mysterious crash later.
+
+ * generic/tclEncoding.c: Several changes to the way the
+ encodingFileMap cache is maintained. Previously, it was attempted to
+ keep the file map filled and up to date with changes in the encoding
+ search path. This contributed to slow startup times since it required
+ an expensive "glob" operation to fill the cache. Now the validity of
+ items in the cache are checked at the time they are used, so the cache
+ is permitted to fall out of sync with the encoding search path. Only
+ [encoding names] and Tcl_GetEncodingNames() now pay the full expense.
+ [Bug 1177363]
+
+2005-04-12 Kevin B. Kenny <kennykb@acm.org>
+
+ * compat/strstr.c: Added default definition of NULL to accommodate
+ building on systems with badly broken headers. [Bug 1175161]
+
+2005-04-11 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * tools/tclZIC.tcl: Rewrote to take advantage of more features of Tcl
+ 8.5 (on which it was dependent anyway). Also added a [package require]
+ line to formalize the relationship.
+
+2005-04-11 Kevin Kenny <kennykb@users.sf.net>
+
+ [kennykb-numerics-branch] Merged with HEAD. Updated to libtommath 0.35.
+
+ * generic/tclBasic.c: Attempted to repeat changes that applied to
+ tclExecute.c in Miguel Sofer's commit of 2005-04-01, together with
+ (possibly) a few more uses of his new object creation macros. Also
+ plugged a memory leak in TclObjInvoke. [Bug 1180368]
+
+2005-04-10 Kevin Kenny <kennykb@acm.org>
+
+ * library/tzdata/America/Montevideo:
+ * library/tzdata/Asia/Almaty:
+ * library/tzdata/Asia/Aqtau:
+ * library/tzdata/Asia/Aqtobe:
+ * library/tzdata/Asia/Baku:
+ * library/tzdata/Asia/Jerusalem:
+ * library/tzdata/Asia/Oral:
+ * library/tzdata/Asia/Qyzylorda:
+ * library/tzdata/Indian/Chagos:
+ * library/tzdata/Indian/Cocos: Olson's tzdata2005h
+
+2005-04-10 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclBasic.c (TclObjInvoke): Plug memory leak. [Bug 1180368]
+
+2005-04-09 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c: fix possible leak of expansion Tcl_Objs
+
+2005-04-09 Daniel Steffen <das@users.sourceforge.net>
+
+ * macosx/README: updated requirements for OS & developer tool versions
+ and other small fixes/cleanup.
+
+ * generic/tclListObj.c (Tcl_ListObjIndex): added missing NULL return
+ when getting index from an empty list.
+
+ * unix/tcl.m4 (Darwin): added -single_module linker flag to
+ TCL_SHLIB_LD_EXTRAS and TK_SHLIB_LD_EXTRAS.
+ * unix/configure: autoconf-2.59
+
+2005-04-08 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclInt.h (TclGetEncodingFromObj): New function to
+ * generic/tclEncoding.c (TclGetEncodingFromObj): retrieve a
+ Tcl_Encoding value, as well as cache it in the internal rep of a new
+ "encoding" Tcl_ObjType.
+ * generic/tclCmdAH.c (Tcl_EncodingObjCmd): Updated to call new
+ function so that Tcl_Encoding's used by [encoding convert*] routines
+ are not freed too quickly. [Bug 1077262]
+
+2005-04-08 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclCompCmds.c (TclCompileSwitchCmd): Rewritten to be able to
+ handle the other form of [switch] and generate slightly simpler (but
+ longer) code.
+
+2005-04-06 Donal K. Fellows <dkf@users.sf.net>
+
+ * doc/upvar.n, doc/unset.n, doc/tell.n, doc/tclvars.n, doc/subst.n:
+ * doc/seek.n, doc/scan.n, doc/regsub.n, doc/registry.n, doc/regexp.n:
+ * doc/read.n, doc/puts.n, doc/pkgMkIndex.n, doc/open.n, doc/lreplace.n:
+ * doc/lrange.n, doc/load.n, doc/llength.n, doc/linsert.n, doc/lindex.n:
+ * doc/lappend.n, doc/info.n, doc/gets.n, doc/format.n, doc/flush.n:
+ * doc/fileevent.n, doc/file.n, doc/fblocked.n, doc/close.n:
+ * doc/array.n, doc/Utf.3, doc/TraceVar.3, doc/StrMatch.3, doc/RegExp.3:
+ * doc/PrintDbl.3, doc/OpenTcp.3, doc/OpenFileChnl.3, doc/Object.3:
+ * doc/Notifier.3, doc/LinkVar.3, doc/IntObj.3, doc/Interp.3:
+ * doc/GetOpnFl.3, doc/GetIndex.3, doc/Eval.3, doc/CrtMathFnc.3:
+ * doc/CrtFileHdlr.3, doc/CrtCommand.3, doc/CrtChannel.3:
+ * doc/Backslash.3: Purge old .VS/.VE macro instances.
+
+ * tools/man2html2.tcl (IPmacro): Rewrote to understand what .IP really
+ is (.IP and .TP are really just two ways of doing the same thing).
+ Change below made this relevant.
+ * doc/re_syntax.n: Change some uses of .TP to .IP to work around bugs
+ in various *roff implementations. Also reworded the atom descriptions
+ slightly.
+
+2005-04-05 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclExecute.c (ExprSrandFunc): Replaced incursions into the
+ * generic/tclUtil.c (TclGetIntForIndex): intreps of numeric types with
+ simpler calls of Tcl_GetIntFromObj and Tcl_GetLongFromObj, now that
+ those routines are better behaved wrt shimmering. [Patch 1177219]
+
+2005-04-05 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclInt.h:
+ * generic/tclObj.c: Change in TclDecrRefCount and TclFreeObj, to speed
+ up the freeing of simple Tcl_Obj [Patch 1174551]
+
+2005-04-04 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c: small opts in obj handling
+
+2005-04-02 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclVar.c: converted a few function calls to macros.
+
+2005-04-01 Miguel Sofer <msofer@users.sf.net>
+
+ * doc/ListObj.3:
+ * generic/tclBasic.c:
+ * generic/tclCmdIL.c:
+ * generic/tclConfig.c:
+ * generic/tclExecute.c:
+ * generic/tclInt.decls:
+ * generic/tclInt.h:
+ * generic/tclIntDecls.h:
+ * generic/tclListObj.c:
+ * generic/tclStubInit.c:
+ * generic/tclVar.c: Changed the internal representation of lists to
+ (a) reduce the malloc/free calls at list creation (from 2 to 1), (b)
+ reduce the cost of handling empty lists (we now never create a list
+ internal rep for them), (c) allow refcounting of the list internal rep.
+ The latter permits insuring that the pointers returned by
+ Tcl_ListObjGetElements remain valid even if the object shimmers away
+ from its original list type. This is [Patch 1158008]
+
+ * generic/tclExecute.c:
+ * generic/tclInt.h:
+ * generic/tclObj.c:
+ * generic/tclStringObj.c:
+ (1) defined new internal macros for creating and setting frequently
+ used obj types (int,long, wideInt, double, string). Changed TEBC to use
+ eg 'TclNewIntObj(objPtr, i)' to avoid the function call in 'objPtr =
+ Tcl_NewIntObj(i)'
+ (2) ExecEnv now stores two Tcl_Obj* pointing to the constants "0" and
+ "1", for use by TEBC.
+ (3) slight reduction in cost of INST_START_CMD
+
+2005-03-31 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c (INST_JUMP_TRUE/FALSE): replaced "test and
+ branch" with "compute index into table"
+
+2005-03-30 Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
+
+ * doc/FileSystem.3: Defined loadHandle argument. [Bug 1172401]
+
+2005-03-29 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/tcl.m4, win/configure: do not require cygpath in macros to allow
+ msys alone as an alternative.
+
+2005-03-24 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCompile.h: Move the TclInterpReady() declaration from
+ * generic/tclInt.h: tclCompile.h to tclInt.h. Should have been done
+ as part of the 1115904 bug fix on 2005-03-18.
+
+ * generic/tclThreadTest.c: Stop providing the phony package
+ "Thread 1.0" when the [::testthread] command is defined. It's never
+ used by anything, and conflicts with loading the real "Thread" package.
+
+2005-03-18 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclCompCmds.c (TclCompileIncrCmd): Corrected checks for
+ immediate operand usage to permit leading space and sign characters.
+ Restores more efficient bytecode for [incr x -1] that got lost in the
+ CONST string reforms of Tcl 8.4. [Bug 1165671]
+
+ * generic/tclBasic.c (Tcl_EvalEx): Restored recursion limit
+ * generic/tclParse.c (TclSubstTokens): testing in nested command
+ * tests/basic.test (basic-46.4): substitutions within direct
+ * tests/parse.test (parse-19.*): script evaluation (Tcl_EvalEx)
+ that got lost in the parser reforms of Tcl 8.1. Added tests for correct
+ behavior. [Bug 1115904]
+
+2005-03-15 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclFileName.c:
+ * win/tclWinFile.c:
+ * tests/winFCMd.test: fix to 'file pathtype' and 'file norm' failures
+ on reserved filenames like 'COM1:', etc.
+
+2005-03-15 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ * unix/tcl.m4: Updated the OpenBSD configuration and regenerated
+ * unix/configure: the configure script.
+
+2005-03-15 Kevin B. Kenny <kennykb@acm.org>
+
+ [kennykb-numerics-branch] Merged with HEAD.
+
+ * generic/tclBasic.c (many):
+ * generic/tclCompExpr.c (CompileMathFuncCall):
+ * generic/tclCompile.h:
+ * generic/tclExecute.c (many):
+ * generic/tclParseExpr.c (ParsePrimaryExpr):
+ * tests/compExpr-old.test:
+ * tests/compExpr.test:
+ * tests/compile.test:
+ * tests/expr-old.test:
+ * tests/expr.test:
+ * tests/for.test:
+ * tests/parseExpr.test: Initial implementation of TIP #232.
+
+ * generic/tclObj.c (Tcl_DbNewBignumObj): Fixed typo that broke
+ --enable-symbols=mem build
+ * tests/binary.test (binary-40.3, binary-40.6): Corrected tests to
+ allow NaN(7ffffffffffff).
+
+2005-03-14 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c: fixed INST_PUSH1's debugging code (wrong obj
+ ref passed to TRACE_WITH_OBJ).
+
+2005-03-14 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompile.c: fixed INST_RETURN's stack effect in
+ tclInstructionTable (-1 instead of -2)
+
+2005-03-10 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclCompCmds.c: removed debugging line
+
+2005-03-10 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclTrace.c (TclCheckInterpTraces): Corrected mistaken cast
+ of ClientData to (TraceCommandInfo *) when not warranted. Thanks to
+ Yuri Victorovich for the report. [Bug 1153871]
+ * generic/tcl.h: Moved flag values TCL_TRACE_ENTER_EXEC and
+ * generic/tclInt.h: TCL_TRACE_LEAVE_EXEC from public interface into
+ private. Should be used only by internal workings of execution traces.
+
+2005-03-09 Kevin B. Kenny <kennykb@acm.org>
+
+ [kennykb-numerics-branch] Merged from HEAD.
+
+ * doc/PrintDbl.3:
+ * doc/tclVars.n: Documented new semantics for tcl_precision.
+ * generic/tclExecute.c (Tcl_ExecuteByteCode): Removed the check for
+ division-by-zero on IEEE-754 machines.
+ * generic/tclUtil.c (Tcl_PrintDouble): Corrected bug where numbers in
+ the range [1e-4 .. 1.) were printed incorrectly.
+ * tests/compExpr-old.test (compExpr-old-11.13): Revised test case for
+ division by zero.
+ * tests/expr-old.test (expr-34.11, expr-34.12): Revised test cases for
+ overflow in pow() to deal with infinities.
+ * tests/expr.test (expr-11.13, expr-29.1, expr-29.2): Revised test case
+ for division by zero and for underflow on input conversions.
+ * tests/parseExpr.test (parseExpr-16.11): Revised test case for
+ overflow on input conversion.
+ * tests/string.test (string-6.38 deleted): Removed test case for
+ underflow on input conversion, which is no longer an error.
+ * tests/util.test (util-10.*): Added test case for the bug in tclUtil.c
+
+2005-03-08 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/makefile.vc: clarify necessary defined vars that can come from
+ MSVC or the Platform SDK.
+
+2005-03-07 Donal K. Fellows <dkf@users.sf.net>
+
+ * doc/string.n: Minor typo. [Bug 1158247]
+
+2005-03-07 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclExecute.c: new peephole optimisation for INST_PUSH1; fixed
+ the peephole opt in INST_POP so that it is not used when
+ TCL_COMPILE_DEBUG is defined.
+
+2005-03-04 Kevin B. Kenny <kennykb@acm.org>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclCmdMZ.c: Changed [scan] to treat out-of-range floating
+ point values as infinities and zeroes.
+ * generic/tclExecute.c: Changed [expr] to be permissive about
+ infinities, allowing them to propagate.
+ * generic/tclGet.c: Changed Tcl_GetDouble to be permissive about
+ over/underflow.
+ * generic/tclObj.c: Changed SetDoubleFromAny to be permissive about
+ over/underflow.
+ * generic/tclParseExpr.c: Made [expr] permissive about input numbers
+ out of range.
+
+2005-03-03 Kevin B. Kenny <kennykb@acm.org>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclInt.h:
+ * generic/tclStrToD.c (Tcl_DoubleDigits, TclFormatNaN):
+ * generic/tclUtil.c (Tcl_PrintDouble): Changed the signature of
+ TclDoubleDigits so that it accepts a pointer to the signum of the
+ argument, and returns the signum via that pointer. Added very hacky
+ code to handle IEEE signed zeroes in Tcl_DoubleDigits. (It can't be
+ done other than as a hack until C9x; C89 simply doesn't deal with the
+ concept of -0.0). Added output conversion of tagged NaN values.
+ * generic/tclBinary.c (FormatNumber): Changed to allow [binary format]
+ to handle NaN.
+ * tests/binary.test (binary-60.1): Added a quick-n-dirty test to make
+ sure that NaN's can be scanned and formatted.
+ * generic/tclParseExpr.c (GetLexeme, ParseMaxDoubleLength): Modified so
+ that tagged NaN (e.g., NaN(DEADBEEF)) can be recognized.
+
+2005-03-02 Kevin B. Kenny <kennykb@acm.org>
+
+ [kennykb-numerics-branch] Merged with HEAD as of 2005-02-23.
+
+ * generic/tclExecute.c: Broadened test for NaN to work on Windows.
+ * generic/tclInt.h:
+ * generic/tclStrToD.c (Tcl_DoubleDigits):
+ * generic/tclUtil.c (Tcl_PrintDouble, TclPrecTraceProc): Added
+ Tcl_DoubleDigits to format 'double' numbers with the minimum number of
+ significant digits to yield correct rounding. Modified tcl_precision
+ to accept 0 as a precision (meaning "minimum digits"), and made 0 the
+ default. [TIP #132]
+ * generic/tclObj.c: Made NaN's throw an error in Tcl_GetDoubleFromObj.
+ * unix/Makefile.in:
+ * win/Makefile.in:
+ * win/makefile.vc: Added libtommath/bn_mp_init_set.c to the build.
+ * libtommath/tommath.h (mp_iseven): Fixed a bug that caused zero to
+ test 'odd'.
+ * generic/tommath.h: Regenerated.
+ * tests/binary.test:
+ * tests/expr-old.test:
+ * tests/expr.test:
+ * tests/scan.test: Corrected a number of tests that depended on
+ tcl_precision, and removed the {eformat} condition from tests that no
+ longer require it.
+ * tests/util.test: Corrected a number of tests that depended on
+ tcl_precision, and removed the {eformat} condition from tests that no
+ longer require it. Added a series of tests for correct rounding in
+ Tcl_PrintDouble. [TIP #132].
+
+2005-03-01 David N. Welton <davidw@dedasys.com>
+
+ * doc/CrtSlave.3: Changed to Tcl_Object to Tcl_Obj in the man page.
+
+2005-02-24 Don Porter <dgp@users.sourceforge.net>
+
+ * library/tcltest/tcltest.tcl: Better use of [glob -types] to avoid
+ * tests/tcltest.test: failed attempts to [source] a directory, and
+ similar matters. Thanks to "mpettigr". [Bug 1119798]
+
+ * library/tcltest/pkgIndex.tcl: Bump to tcltest 2.2.8
+ * unix/Makefile.in:
+ * win/Makefile.in:
+
+2005-02-23 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/CrtChannel.3 (THREADACTIONPROC): Formatting fix. [Bug 1149605]
+
+2005-02-17 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * win/tclWinFCmd.c (TraverseWinTree): use wcslen on wchar, not
+ Tcl_UniCharLen.
+
+2005-02-16 Miguel Sofer <msofer@users.sf.net>
+
+ * doc/variable.n: fix for [Bug 1124160], variables are detected by
+ [info vars] but not by [info locals].
+
+2005-02-11 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/Makefile.in: remove SHLIB_LD_FLAGS (only for AIX, inlined into
+ * unix/tcl.m4: SHLIB_LD). Combine AIX-* and AIX-5 branches in
+ * unix/configure: SC_CONFIG_CFLAGS. Correct gcc builds for AIX-4+
+ and HP-UX-11. autoconf-2.59 gen'd.
+
+2005-02-11 Miguel Sofer <msofer@users.sf.net>
+
+ * tests/basic.test (basic-26.3): new test
+
+2005-02-10 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclBasic.c (Tcl_EvalObjEx):
+ * tests/basic.test (basic-26.2): preserve the arguments passed to TEOV
+ in the pure-list branch, in case the list shimmers away. Fix for [Bug
+ 1119369], reported by Peter MacDonald.
+
+2005-02-10 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclFileName.c: fix for test failures introduced on 2005-01-17
+ [Bug 1119092]
+
+2005-02-10 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/binary.n: Made the documentation of sign bit masking and [binary
+ scan] consistent. [Bug 1117017]
+
+2005-02-08 David N. Welton <davidw@dedasys.com>
+
+ * doc/CrtChannel.3: Typo: return->returns.
+
+2005-02-06 Kevin B. Kenny <kennykb@acm.org>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclStrToD.c (TclStrToD, SafeLdExp): Added code to manage the
+ FPU precision on gcc+x86. Enabled fast conversion of floats with small
+ exponents now that precision is correct.
+ * tests/expr.test: Corrected test for the smallest representible value
+ to the right IEEE values.
+
+2005-02-06 David N. Welton <davidw@dedasys.com>
+
+ * doc/Thread.3: One-word grammar fix.
+
+2005-02-05 David N. Welton <davidw@dedasys.com>
+
+ * doc/Thread.3: Fixed sentence describing flags for Tcl_CreateThread.
+
+ * doc/FileSystem.3: Cleaned up typo in Tcl_FSNewNativePath
+ documentation.
+
+ * generic/tclPathObj.c: Cleaned up typo in comment.
+
+2005-02-03 Kevin B. Kenny <kennykb@acm.org>
+
+ [kennykb-numerics-branch]
+
+ * generic/tclStrToD.c (TclStrToD, RefineResult, SafeLdExp): Added code
+ to ensure that 'ldexp' is never called with a value that will underflow
+ * tests/expr.test: Added tests for the smallest representible value,
+ and rounding between it and zero. (The tests reflect current
+ behaviour; plan is to change the specification of Tcl so that input
+ conversion of doubles underflows silently.)
+
+2005-02-02 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * generic/tclProc.c (TclInitCompiledLocals): Add check for type of the
+ framePtr->procPtr->bodyPtr passed to TclInitCompiledLocals and panic if
+ it is not the correct type. If the body of the proc is not of the
+ compiled byte code type then the code will crash. This was discovered
+ while tracking down a crash in Itcl, that crash is fixed by Itcl patch
+ 1115085.
+
+2005-02-01 Kevin B. Kenny <kennykb@acm.org>
+
+ [kennykb-numerics-branch] Merged with HEAD as of today.
+
+ * generic/tclInt.decls: Changed numbers of new stubs to resolve a
+ conflict.
+ * generic/tclInt.h: Added new TclStrToD routine that replaces the
+ native 'strtod' throughout Tcl.
+ * generic/tclCmdMZ (Tcl_StringObjCmd):
+ * generic/tclGet.c (Tcl_GetDouble):
+ * generic/tclObj.c (SetBooleanFromAny, SetDoubleFromAny):
+ * generic/tclParseExpr.c (GetLexeme):
+ * generic/tclScan.c (Tcl_ScanObjCmd): Replaced all uses of the native
+ 'strtod' with a TclStrToD routine that performs correct rounding and
+ handles denormals.
+ * generic/tclStrToD.c: (new file)
+ New scanning function for extracting 'double' from a string that rounds
+ correctly, and handles denormals and infinities.
+ * unix/Makefile.in:
+ * win/Makefile.in:
+ * win/makefile.vc:
+ Added tclStrToD.c and the tommath routines that support it.
+
+ These changes represent a partial implementation of TIP #132. Output
+ conversion of floating point numbers, and proper handling of infinities
+ within expressions, still need to be addressed.
+
+2005-02-01 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclExecute.c (TclCompEvalObj): Removed stray statement left
+ behind in prior code reorganization.
+
+2005-01-31 Don Porter <dgp@users.sourceforge.net>
+
+ * unix/configure: autoconf-2.57
+
+2005-01-30 Joe English <jenglish@users.sourceforge.net>
+
+ * unix/configure.in: Restored two double-evals that were removed in the
+ DBGX purge; these are still needed on some platforms to account for
+ TCL_TRIM_DOTS. [Bug 1112654]
+
+ * unix/configure: NOT REGENERATED: only have autoconf 2.59 here, need
+ to find someone with autoconf 2.57.
+
+2005-01-28 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * unix/configure, unix/tcl.m4: add solaris 64-bit gcc build support.
+ [Bug 1021871]
+
+2005-01-28 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * tests/expr-old.test (expr-old-37.2): Added test for [Bug 1109484]
+
+2005-01-27 Jeff Hobbs <jeffh@ActiveState.com>
+
+ * generic/tclBasic.c (Tcl_ExprBoolean, Tcl_ExprDouble)
+ (Tcl_ExprLong): Fix to recognize Tcl_WideInt type. [Bug 1109484]
+
+2005-01-26 Andreas Kupries <andreask@activestate.com>
+
+ TIP#218 IMPLEMENTATION
+
+ * generic/tclDecls.h: Regenerated from tcl.decls.
+ * generic/tclStubInit.c:
+
+ * doc/CrtChannel.3: Documentation of extended API,
+ * generic/tcl.decls: extended testsuite, and
+ * generic/tcl.h: implementation. Removal of old
+ * generic/tclIO.c: driver-specific TclpCut/Splice
+ * generic/tclInt.h: functions. Replaced with generic
+ * tests/io.test: thread-action calls through the
+ * unix/tclUnixChan.c: new hooks. Update of all builtin
+ * unix/tclUnixPipe.c: channel drivers to version 4.
+ * unix/tclUnixSock.c: Windows drivers extended to
+ * win/tclWinChan.c: manage thread state in a thread
+ * win/tclWinConsole.c: action handler.
+ * win/tclWinPipe.c:
+ * win/tclWinSerial.c:
+ * win/tclWinSock.c:
+
+2005-01-25 Don Porter <dgp@users.sourceforge.net>
+
+ * library/auto.tcl: Updated [auto_reset] to clear auto-loaded
+ commands in namespaces other than :: and to clear auto-loaded commands
+ that do not happen to be procs. [Bug 1101670]
+ ***POTENTIAL INCOMPATIBILITY***
+
+2005-01-25 Daniel Steffen <das@users.sourceforge.net>
+
+ * unix/tcl.m4 (Darwin): fixed bug with static build linking to dynamic
+ library in /usr/lib etc instead of linking to static library earlier in
+ search path. [Bug 956908] Removed obsolete references to Rhapsody.
+ * unix/configure: autoconf-2.57
+
+2005-01-21 Andreas Kupries <andreask@activestate.com>
+
+ * generic/tclStubInit.c: Regenerated the stubs support code from the
+ * generic/tclDecls.h: modified tcl.decls (TIP #233, see below).
+
+ * doc/GetTime.3: Implemented TIP #233, i.e. the
+ * generic/tcl.decls: 'Virtualization of Tcl's Sense of Time'.
+ * generic/tcl.h: Declared, implemented, and documented the
+ * generic/tclInt.h: specified new API functions. Moved the
+ * unix/tclUnixEvent.c: native (OS) access to time information
+ * unix/tclUnixNotfy.c: into standard handler functions. Inserted
+ * unix/tclUnixTime.c: hooks calling on the handlers where native
+ * win/tclWinNotify.c: access was done before, and where scaling
+ * win/tclWinTime.c: between domains (real/virtual) is required.
+
+2005-01-21 Andreas Kupries <andreask@activestate.com>
+
+ * generic/tclThread.c: Typo police. Fixed some nits
+ * generic/tclCmdAH.c: in header comments of functions.
+ * generic/tclBasic.c: (Missing --).
+ * generic/tclFileName.c:
+
+2005-01-21 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/FileSystem.3: Add missing ARGUMENTS section definitions for
+ arguments to Tcl_FSLink. [Bug 1106272]
+
+2005-01-21 Kevin B. Kenny <kennykb@acm.org>
+
+ [kennykb-numerics-branch]
+
+ * unix/Makefile.in: Updated Makefile to build libtommath on Unix as
+ well as Windows. [Bug 1106865]
+
+ * generic/tclTestObj.c (TestbignumobjCmd): Silenced a compiler warning
+ about a mismatched 'const'.
+
+2005-01-20 Kevin B. Kenny <kennykb@acm.org>
+
+ [kennykb-numerics-branch] Development checkpoint.
+
+ * compat/strtoll.c: Reverted to HEAD.
+ * compat/strtoull.c:
+ * doc/Ensemble.3:
+ * generic/tclBasic.c:
+ * generic/tclCmdIL.c:
+ * generic/tclNamesp.c:
+ * generic/tclPathObj.c:
+ * generic/tclPort.h:
+ * unix/configure:
+ * unix/configure.in:
+ * unix/tcl.m4:
+ * win/configure:
+ * win/configure.in:
+ * win/rules.vc:
+ * win/tcl.m4:
+
+ * generic/tcl.h: Added declarations for bignum types, and for a
+ 'bignumValue' in the Tcl_Obj structure.
+ * generic/tclInt.h: Added declarations of interface procedures for
+ memory allocation in libtommath.
+
+ * generic/tcl.decls: Added new interface to bignum objects.
+ * generic/tclInt.decls: Added internal stubs for bignum routines used
+ by the test code in tclTestObj.c.
+
+ * generic/tclDecls/h: Regen.
+ * generic/tclIntDecls.h:
+ * generic/tclStubInit.h:
+
+ * tools/fix_tommath_h.tcl: (New file) Script to edit
+ libtommath/tommath.h and produce generic/tommath.h so that storage
+ classes, allocation routines, and data types conform to Tcl's
+ conventions.
+ * generic/tommath.h: (New file) Generated by the above.
+
+ * generic/tclTomMath.h: (New file) Additional declarations to be
+ included in tommath.h when building Tcl.
+
+ * generic/tclTomMathInterface.c: (New file) Small 'glue' routines
+ adapting tommath's API to Tcl.
+
+ * libtommath/bn_fast_s_mp_mul_digs.c:
+ * libtommath/bn_mp_mul_d.c:
+ * libtommath/bn_mp_read_radix.c:
+ * libtommath/tommath.h: Applied suggested changes from Tom St Denis
+ that correct an off-by-one error in single-digit multiplication
+ (leading to a pointer smash if uncorrected) and change the string
+ argument to 'mp_read_radix' from 'char*' to 'const char*'.
+
+ * libtommath/bn_mp_radix_size.c: Local patch to ensure that sufficient
+ memory is requested even if the number has a single digit.
+
+ * libtommath/bn_mp_read_radix.c: Local patch to return MP_VAL if the
+ input string contains an invalid character.
+
+ * generic/tclObj.c: Added accessor functions for bignums.
+ * generic/tclTestObj.c: Added a 'testbignumobj' command to exercise the
+ accessor functions for bignums.
+
+ * win/Makefile.in: Added rules for making libtommath.
+
+2005-01-19 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ TIP#235 IMPLEMENTATION
+
+ * doc/Ensemble.3: Documentation for the new public API.
+ * generic/tclNamesp.c (Tcl_CreateEnsemble,...): Rename of
+ * generic/tcl.decls: existing API into TIPped form.
+
+2005-01-19 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/tclWinChan.c (FileCloseProc): Invoke TclpCutFileChannel() to
+ remove a FileInfo from the thread local list before deallocating it.
+ This should have been done via an earlier call to Tcl_CutChannel, but I
+ was running into a crash in the next call to Tcl_CutChannel during the
+ I/O finalization stage.
+
+2005-01-18 Kevin Kenny <kennykb@acm.org>
+
+ * library/tzdata/GMT+0:
+ * library/tzdata/GMT-0:
+ * library/tzdata/GMT0:
+ * library/tzdata/Greenwich:
+ * library/tzdata/Navajo:
+ * library/tzdata/Universal:
+ * library/tzdata/Zulu:
+ * library/tzdata/America/Asuncion:
+ * library/tzdata/America/Rosario:
+ * library/tzdata/Asia/Jerusalem:
+ * library/tzdata/Brazil/Acre:
+ Routine update per Olson's tzdata2005c. Removed links to links
+ (Greenwich in several aliases; Navajo; Acre). Updated Paraguayan DST
+ rules and "best guess" at this year's Israeli rules.
+
+2005-01-17 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclFileName.c: fix for glob failure on Windows shares [Bug
+ 1100542].
+
+ * doc/pkgMkIndex.n: added documentation that 'pkg_mkIndex -lazy' is not
+ a good idea. [Bug 1101678]
+
+2005-01-14 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * tests/compile.test (compile-17.1): Document known issue with binding
+ time of compiled command interpretations in [expr].
+
+ * generic/tclIOUtil.c (TclFSFileAttrIndex): New helper function so that
+ we don't need to hard-code attribute indexes. [Bug 1100671]
+
+2005-01-13 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/string.n: Removed the term 'set' from the documentation of the
+ [string trim] commands, as it caused confusion.
+
+2005-01-12 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * unix/tcl.m4 (SC_PATH_{TCL,TK}CONFIG): Added code to detect the case
+ when the --with-tcl/--with-tk arguments point to the config scripts
+ themselves and not their directory. If this is the case, they now
+ complain but keep working. [FRQ 951247]
+ * unix/configure: autoconf-2.57
+
+2005-01-10 Joe English <jenglish@users.sourceforge.net>
+
+ * unix/Makefile.in, unix/configure.in, unix/tcl.m4,
+ * unix/tclConfig.sh.in, unix/dltest/Makefile.in:
+ Remove ${DBGX}, ${TCL_DBGX} from Tcl build system [Patch 1081595].
+ * unix/configure: regenerated
+
+2005-01-10 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * unix/tclUnixFCmd.c (TclUnixCopyFile): Convert u_int to unsigned to
+ make clashes with types in standard C headers less of a problem. [Bug
+ 1098829]
+
+2005-01-09 Joe English <jenglish@users.sourceforge.net>
+
+ * unix/tclUnixThrd.c, unix/tclUnixPort.h: Remove readdir_r() and
+ related #ifdeffery (see [Bug 1095909]).
+ * unix/tcl.m4, unix/tclConfig.h.in: Don't check for HAVE_READDIR_R.
+ * unix/configure: Regenerated.
+
+2005-01-06 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * library/http/http.tcl (http::mapReply): Significant performance
+ enhancement by using [string map] instead of [regsub]/[subst], and
+ update version requirement to Tcl8.4. [Bug 1020491]
+
+2005-01-05 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * doc/lsearch.n, doc/re_syntax.n: Convert to other form of emacs mode
+ control comment to prevent problems with old versions of man. [Bug
+ 1085127]
+
+2005-01-05 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ * tests/winDde.test: Fixed broken test result.
+
+2005-01-05 Donal K. Fellows <donal.k.fellows@man.ac.uk>
+
+ * generic/tclInt.h, generic/tclPort.h: Move the #include of tclConfig.h
+ *first* before any reference to tcl.h so that the build configuration
+ is loaded before the first reference to any system headers. Issue
+ reported by Art Haas on tcl-core.
+
+2005-01-04 Don Porter <dgp@users.sourceforge.net>
+
+ * tests/fCmd.test (fCmd-18.10): Added notNetworkFilesystem constraint.
+ [Bug 456665]
+
+ ******************************************************************
+ *** 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/README b/README
index 181b0a1..b3bbc2e 100644
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
README: Tcl
- This is the Tcl 8.4.19 source distribution.
+ This is the Tcl 8.5.11 source distribution.
http://tcl.sourceforge.net/
You can get any source release of Tcl from the file distributions
link at the above URL.
@@ -22,7 +22,7 @@ Contents
Tcl provides a powerful platform for creating integration applications that
tie together diverse applications, protocols, devices, and frameworks.
When paired with the Tk toolkit, Tcl provides the fastest and most powerful
-way to create GUI applications that run on PCs, Unix, and the Macintosh.
+way to create GUI applications that run on PCs, Unix, and Mac OS X.
Tcl can also be used for a variety of web-related tasks and for creating
powerful command languages for applications.
@@ -45,7 +45,7 @@ and selling it either in whole or in part. See the file
Extensive documentation is available at our website.
The home page for this release, including new features, is
- http://www.tcl.tk/software/tcltk/8.4.html
+ http://www.tcl.tk/software/tcltk/8.5.html
Detailed release notes can be found at the file distributions page
by clicking on the relevant version.
@@ -57,9 +57,9 @@ Information about Tcl itself can be found at
There have been many Tcl books on the market. Many are mentioned in the Wiki:
http://wiki.tcl.tk/_/ref?N=25206
-To view the complete set of reference manual entries for Tcl 8.4 online,
+To view the complete set of reference manual entries for Tcl 8.5 online,
visit the URL:
- http://www.tcl.tk/man/tcl8.4/
+ http://www.tcl.tk/man/tcl8.5/
2a. Unix Documentation
----------------------
@@ -118,8 +118,8 @@ information about Tcl, Tk, and related applications. The newsgroup is a
great place to ask general information questions. For bug reports, please
see the "Support and bug fixes" section below.
-6. The Tcler's Wiki
--------------------
+6. Tcl'ers Wiki
+---------------
A Wiki-based open community site covering all aspects of Tcl/Tk is at:
@@ -167,7 +167,7 @@ The Tcl community is too large for us to provide much individual support
for users. If you need help we suggest that you post questions to
comp.lang.tcl. We read the newsgroup and will attempt to answer esoteric
questions for which no one else is likely to know the answer. In addition,
-see the following page on the Wiki for links to other organizations that offer
+see the following Web site for links to other organizations that offer
Tcl/Tk training:
http://wiki.tcl.tk/training
diff --git a/changes b/changes
index f973758..0442b3a 100644
--- a/changes
+++ b/changes
@@ -4216,7 +4216,7 @@ input lines. (redman)
This is used on Windows to avoid the various problems that people
have been seeing where the system hangs when tclsh is running
outside of the event loop. As part of this, renamed
-TcapAlertNotifier back to Tcl_AlertNotifier since it is public.
+TclpAlertNotifier back to Tcl_AlertNotifier since it is public.
(stanton)
3/23/99 (feature change) Test suite now uses "tcltest" namespace to
@@ -5856,7 +5856,7 @@ in the 8.4.3 release.
2003-07-16 (bug fix)[756791] corrected assumption that Tcl_Free == free
-2003-07-16 (feature enhancement) -DTCL_UTF_MAX=6 compile option forces
+2003-07-16 (feature enhancement) -DTCL_UTF_MAX=6 compile option forces
internal UCS-4 representation of Unicode (default is recommended UCS-2).
2003-07-16 (bug fix)[767578] 64-bit corrections in thread notifier.
@@ -5962,36 +5962,149 @@ various odd regexp "can't happen" bugs.
--- Released 8.4.6, March 1, 2004 --- See ChangeLog for details ---
+Changes to 8.5a1 include all changes to the 8.4 line through 8.4.6,
+plus the following, which focuses on the high-level feature changes
+in this changeset (new minor version) rather than bug fixes:
+
+ * refactored IO code to split FS path code into generic/tclPathObj.c
+ and generic/tclFileSystem.h
+
+ * refactored trace code into generic/tclTrace.c
+
+ * configure scripts now require autoconf 2.57 for regeneration
+
+ * updated runtime library scripts to use newer Tcl code features
+ (like replacing regsub with string map)
+
+ * improve robustness of tcltest test suite across environments
+
+ * changed the bytecode evaluation-stack addressing mode, from array-style
+ to pointer-style; the catch stack and evaluation stack are now
+ contiguous in memory
+
+ * switch command is now byte-compiled
+
+ * enhanced checking in 'file' command for Windows NT file permissions
+
+ * [TIP #57] new 'lassign' command (adopted from TclX)
+
+ * [TIP #75] switch -regexp now provides submatch info
+
+ * [TIP #90] extended 'catch' and 'return' to enable creation of procs
+ that are a true replacement for 'return'
+
+ * [TIP #100] new 'unload' command (can unload DLLs loaded via 'load',
+ requires the extension writer to support it)
+
+ * [TIP #111] new 'dict' command. Several commands have been updated
+ to handle the list form of dicts implicitly at the C level where
+ only lists were previously accepted
+
+ * [TIP #112] 'namespace ensemble' command addition allows for ensembles
+ that build on the namespace abstraction
+
+ * [TIP #118] file attributes -readonly option for unices that support
+ chflags(), support Mac Classic attribute options on OS X, add
+ -rsrclength for OS X, enhance file copy on OS X to copy finder
+ attributes and resource forks transparently
+
+ * [TIP #120] enable dde in safe interpreters
+ * [TIP #130] enable unique dde server names on Windows
+ * [TIP #135] change dde servername -exact option to -force
+=> dde 1.3
+
+ * [TIP #121] new Tcl_SetExitProc C API to control application shutdown
+
+ * [TIP #123] expr ** exponentiation operator
+
+ * [TIP #124] 'clock clicks -milliseconds' now returns a wide integer and a
+ new 'clock clicks -microseconds' returns a wide integer, representing
+ the number of microseconds, both since the Posix epoch
+
+ * [TIP #127] added 'lsearch -index' option
+
+ * [TIP #136] added 'lrepeat' command
+
+ * [TIP #137/151] Add -encoding option to 'source' command and main tclsh
+ executable.
+ *** POTENTIAL INCOMPATIBILITY ***
+ For Tcl embedders that build on Tcl_Main() and make use of Tcl_Main's
+ former ability to pass a leading "-encoding" option to interactive shell
+ operations, this will now be consumed by Tcl.
+
+ * [TIP #138] New TCL_HASH_KEY_SYSTEM_HASH option for Tcl hash tables
+
+ * [TIP #139] documented portions of Tcl's namespace C APIs
+
+ * [TIP #148] correct [list]-quoting of the '#' character
+ *** POTENTIAL INCOMPATIBILITY ***
+ For scripts that assume a particular (buggy) string rep for lists.
+
+ * [TIP #156] add "root locale" to msgcat
+=> msgcat 1.4
+
+ * [TIP #157] leading {expand} syntax on words to cause argument expansion.
+ This is a safer/cleaner alternative to the use of 'eval'.
+
+--- Released 8.5a1, March 3, 2004 --- See ChangeLog for details ---
+
+2004-03-04 (new feature) registry package is [unload]able (thoyts)
+=> registry 1.1.4
+
2004-03-08 (bug fix)[910525] [glob -path] in root directory (darley)
-2004-03-15 (bug fix)[916795] syntax error -> compiler segfault (sofer,porter)
+2004-03-12 (new feature)[TIP 163] [dict merge] (english, fellows)
+
+2004-03-18 (platform support) support for Mac Classic removed (steffen)
+
+2004-03-28 (bug fix)[925121] corrected segfault in bc compiler (sofer)
-2004-03-29 (bug fix)[920667] install into any Unicode path on Win (hobbs)
+2004-03-30 (bug fix)[495830,729692] bytecode execution checks
+each command/interp validity before executing. (sofer)
2004-03-31 (bug fix)[811457] support translation to "" (porter)
2004-03-31 (bug fix)[811461] ignore locales with no "language" part (porter)
-=> msgcat 1.3.2
+=> msgcat 1.4.1
+
+2004-04-01 (bug fix) make [glob -type d -dir . *] work across VFS boundary
+
+2004-04-06 (clean up) refactored Tcl header file #include order. Might
+create need for changes in extensions that #include private headers.
+Changed source code files should work with older Tcl as well. See ChangeLog.
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2004-04-07 (bug fix)[920667] install into any Unicode path on Win (hobbs)
2004-04-07 (platform support) properly substitute more values in Windows
tclConfig.sh (hobbs)
2004-04-23 (bug fix)[930851] reset channel EOF when eofchar changes (kupries)
+2004-04-28 (bug fix)[600812][TIP 184] [upvar 0 scalar array(foo)] raises error
+
2004-05-03 (bug fix)[947070] stack overflow prevention on Win (kenny)
2004-05-03 (bug fix)[868853] fix leak in [fconfigure $serial -xchar] (cassoff)
-2004-04-05 (bug fix)[928353,929892,928808,947440,948177] test fixes: OSX
-(abner)
-
-2004-05-04 (bug fix) crash: [cd] w/ volumerelative $HOME (hobbs)
+2004-05 (bug fix)[928353,929892,928808,947440,948177] test fixes: OSX (abner)
2004-05-05 (bug fix)[794839] socket connect error -> r/w fileevents
(gravereaux)
-2004-05-14 (bug fix)[940278,922848] [clock] notices $::env(TZ) changes,
+2004-05-07 (bug fix)[949905] corrected utf-8 encoding of \u0000 on I/O (max)
+
+2004-05-13 (new feature)[TIP 129] [binary scan tnmrRqQ] (markus, fellows)
+
+2004-05-13 (new feature)[TIP 142] [interp limit] (fellows)
+
+2004-05-14 (bug fix)[940278,922848] [clock] notices $::env(TZ) changes,
gmt works on all platforms. (kenny, welton, glessner)
+2004-05-16 (feature rewrite) bytecode execution of {expand} changed
+ *** POTENTIAL INCOMPATIBILITY with prior 8.5a releases ***
+
+2004-05-18 (platform support) makefile.vc now generates tclConfig.sh (thoyts)
+
2004-05-18 (bug fix)[500285,500389,852944] [clock %G %V] ISO8601 week numbers
(kenny)
@@ -6005,24 +6118,34 @@ gmt works on all platforms. (kenny, welton, glessner)
2004-05-26 (bug fix)[960926] file count doubled when -singleproc 1 (porter)
=> tcltest 2.2.6
-2004-05-27 (bug fix)[949905] corrected utf-8 encoding of \u0000 on I/O (max)
+2004-05-26 (bug fix)[874058] improved build configuration on 64-bit systems.
+Corrects Tcl_StatBuf definition issues. (hobbs)
+
+2004-05-30 (platform support) Win: allow signed short exit codes (gravereaux)
2004-06-05 (bug fix)[976722] hi-res clock fixes: Win
(godfrey, suchenwirth, kenny)
-
2004-06-10 (bug fix)[932314] bad return values from Tcl_FSChdir() (vasiljevic)
-2004-06-14 (bug fix) correct dde hangs w/non-responsive apps (thoyts)
-=> dde 1.2.3
+2004-06-18 (platform support) regonize more unix locales (huang)
+
+2004-06-18 (bug fix) prevent stack overflow from long free() chains (fellows)
2004-06-21 (platform support) exceptions w/ gcc -O3 on Win (dejong)
+2004-06-23 (feature rewrite)[976496] thread local storage done with hash
+tables to avoid system limits (mistachkin)
+
2004-06-29 (bug fix)[981733] SafeBase global pollution (fellows)
+2004-06-30 (new feature)[TIP 188] [string is wideinteger] (kenny)
+
2004-07-02 (new feature)[TIP 202] pipe redirection 2>@1 (hobbs)
2004-07-03 (bug fix)[908375] round() wide integer support (lavana, sofer)
+2004-07-07 (bug fix)[458361] shimmer of single-word scripts suppressed (sofer)
+
2004-07-15 (bug fix)[770053] crash in thread finalize of notifier (vasiljevic)
2004-07-15 (bug fix)[990453] plug mutex leaks on reinit
@@ -6033,16 +6156,13 @@ gmt works on all platforms. (kenny, welton, glessner)
2004-07-19 (bug fix)[987967] improved self-init of mutexes on Win (vasiljevic)
-2004-07-19 (bug fix)[874058] improved build configuration on 64-bit systems.
-Corrects Tcl_StatBuf definition issues. (hobbs)
-
2004-07-20 (bug fix) pure Darwin/CFLite support (steffen)
2004-07-20 (bug fix)[736426] plug leaky allocator reinit (mistachkin, kenny)
---- Released 8.4.7, July 26, 2004 --- See ChangeLog for details ---
+2004-07-30 (bug fix)[999084] no deadlock in re-entrant Tcl_Finalize (porter)
-2004-07-28 (bug fix)[999084] no deadlock in re-entrant Tcl_Finalize (porter)
+2004-08-02 (new feature)[TIP 207] [interp invokehidden -namespace] (porter)
2004-08-10 (bug fix) thread IDs on 64-bit systems (ratcliff,vasiljevic)
@@ -6051,98 +6171,215 @@ Corrects Tcl_StatBuf definition issues. (hobbs)
2004-08-16 (bug fix)[1008314] Tcl_SetVar TCL_LIST_ELEMENT (sofer,porter)
+2004-08-18 (new feature)[TIP 173,209] complete [clock] rewrite (kenny)
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2004-08-18 (new feature)[TIP 189] package loading for Tcl Modules (kupries)
+
2004-08-19 (bug fix)[1011860] [scan %ld] fix on LP64 (fellows,porter)
+2004-08-23 (bug fix)[695441] extend [tcl_findLibrary] search path to include
+ $::auto_path and [pkgconfig get scriptdir,runtime] (porter)
+
+2004-08-27 (platform support) TCL_MODULE_PATH values for Mac OSX (steffen)
+
+2004-08-27 (bug fix)[1017022] recognize imported ensembles (fellows)
+
2004-08-30 (bug fix) [string map $x $x] crash (fellows)
2004-09-01 (bug fix)[1020445] WIN64 support (hobbs)
+2004-09-03 (bug fix)[1020538] crash in [file copy] (violi,fellows)
+
2004-09-07 (bug fix)[1016167] [after] overwrites its imports (kenny)
2004-09-08 (bug fix) fixed [clock format 0 -format %k] (kenny)
2004-09-09 (bug fix)[560297] fixed broken [namespace forget] logic (porter)
-2004-09-09 (bug fix)[1017299] fixed [namespace import] cycle prevention (porter)
+2004-09-09 (bug fix)[1017299] fixed [namespace import] cycle prevention
+(porter)
2004-09-10 (performance) $x[set x {}] is now fast [K $x [set x {}]] (sofer)
-2004-09-10 (bug fix)[868489] better control over int <-> wideInt (fellows,kenny)
+2004-09-10 (bug fix)[868489] better control over int <-> wideInt
+(fellows,kenny)
2004-09-10 (bug fix)[1025359] POSIX errorCode from wide seeks (kupries,fellows)
+2004-09-10 (bug fix)[707104,1026493] fix [rename] of [interp alias] (porter)
+
2004-09-18 (bug fix)[868467] fix [expr 5>>32] => 0, not 5 (hintermayer,fellows)
-2004-09-23 (bug fix)[1016726] fix `make clean` in static config (leitgeb,dejong)
+2004-09-21 (bug fix) consistent errorinfo from [namespace eval x error foo bar]
+ and [namespace eval c {error foo bar}] (porter)
-2004-09-29 (bug fix)[1036649] syntax error in [subst] => buffer overflow (sofer)
+2004-09-22 (feature change) syntax errors not reported at compile time;
+ deferred to runtime. Support [return -errorline]. (porter)
+
+2004-09-23 (bug fix)[1016726] fix `make clean` in static config
+(leitgeb,dejong)
+
+2004-09-22 (feature change) report all compile errors at runtime (porter)
+
+2004-09-29 (bug fix)[1036649] syntax error in [subst] => buffer overflow
+(sofer)
2004-09-30 (bug fix)[1038021] save/restore error state: var traces (porter)
-2004-10-08 (bug fix)[954263] case insensitive [file exec] for Win (hobbs,darley)
+2004-10-01 (performance) stackframe level values in internal reps (fellows)
+
+2004-10-01 (feature change)[1037235] auto-create [dict] key paths (fellows)
+
+2004-10-04 (bug fix)[884830] eq and ne parse in expr (fellows)
+
+2004-10-05 (reform) errorInfo, errorCode management (porter)
+ *** POTENTIAL INCOMPATIBILITY for traces on those vars ***
+
+2004-10-06 (feature change)[1041072] re-bless and enhance Tcl_AppendResult
+(dkf)
+
+2004-10-06 (reform) more robust interp result appends (porter)
+=> dde 1.3.1
+=> registry 1.1.5
+
+2004-10-06 (reform) re-write of [glob] guts (fellows)
+
+2004-10-07 (reform)[925620] improved platform split of VFS code (darley)
+
+2004-10-08 (new feature)[TIP 201] "in" and "ni" expr operators (fellows)
+
+2004-10-08 (new feature)[TIP 212] [dict update]; [dict with] (fellows)
+
+2004-10-08 (bug fix)[954263] case insensitive [file exec] for Win
+(hobbs,darley)
2004-10-14 (performance) [info commands/globals/procs/vars $pattern] faster
- when $pattern is trivial (fellows)
+ when $pattern is trivial (fellows)
+
+2004-10-14 (new feature)[TIP 217] [lsort -indices] (salsman,fellows)
+
+2004-10-24 (reform) replaced bit flag values with macros for Var handling
+ *** POTENTIAL INCOMPATIBILITY for accesses to Var internals ***
+
+2004-10-26 (new feature)[1054370] install msgcat, http, tcltest as TM's
+(porter)
+
+2004-10-26 (bug fix)[767676] negative PIDs with pipes (giese,gravereaux)
+
+2004-10-27 (bug fix)[731778] stop critical section leaks
+(mistachkin,gravereaux)
+
+2004-10-27 (bug fix)[926088] -load option to find tested packages (gravereaux)
2004-10-28 (bug fix)[1030548] restore the --enable-symbols --enable-threads
- build on Win (mistachkin,kenny,kupries)
+build on Win (mistachkin,kenny,kupries)
2004-10-29 (bug fix)[1055673] fix command line syntax error message (porter)
=> tcltest 2.2.7
+2004-10-30 (bug fix)[926106] fix [file mtime] DST anomaly (kenny)
+
2004-10-31 (bug fix)[1057461] fix [info globals ::varName] (fellows)
2004-11-02 (bug fix)[761471] fix [expr {NaN == NaN}] (sofer)
2004-11-02 (bug fix)[1017151] misleading errorInfo after tests (seeger,porter)
+2004-11-03 (bug fix)[527164] preserve errorinfo from var traces (porter)
+
+2004-11-08 (bug fix){947693] Made -blocking option of channel during [close]
+consistent on Windows with Unix (gravereaux)
+ *** POTENTIAL INCOMPATIBILITY ***
+
2004-11-11 (bug fix)[1034337] recursive file delete, MacOSX (steffen)
+2004-11-12 (new feature)[TIP 221] [interp bgerror] (porter)
+
+2004-11-12 (new feature)[TIP 226] Tcl_(Save|Restore|Discard)InterpState
+(porter)
+
+2004-11-12 (new feature)[TIP 227] Tcl_(Get|Set)ReturnOptions (porter)
+
2004-11-12 (bug fix)[1004065] stop crash when TCL_UTF_MAX==6 (hobbs,porter)
2004-11-15 (bug fix)[10653678] [trace variable],[trace remove] interop (porter)
-2004-11-16 (bug fix)[695441] [tcl_findLibrary] search $::auto_path too (porter)
-
2004-11-16 (bug fix)[1067709] crash in [fconfigure -ttycontrol] (hobbs)
2004-11-18 (new feature) configure options --enable-man-suffix (max)
-Documentation improvements [759545,1058446,1062647,1065732,etc.]
-Test suite expansion [1036649,1001997,etc.]
+2004-11-22 (bug fix)[1030465] Improve HAVE_TYPE_OFF64_T check (dejong)
---- Released 8.4.8, November 18, 2004 --- See ChangeLog for details ---
+2004-11-22 (bug fix)[1043129] Fixed the treatment of backslashes in file
+join on Windows (darley)
-2004-11-22 (bug fix)[1030465] Improve HAVE_TYPE_OFF64_T check (dejong)
+2004-11-22 (bug fix)[976438] Move init.tcl search path construction to
+tclInit (porter)
-2004-11-23 (bug fix)[1072654] Fixed segfault in info vars trivial
+2004-11-24 (bug fix)[1072654] Fixed segfault in info vars trivial
matching branch (new in 8.4.8) (porter)
-2004-11-23 (bug fix)[1043129] Fixed the treatment of backslashes in file
-join on Windows (darley)
-
2004-11-24 (bug fix)[1001325, 1071701] Fixed readdir_r detection and usage
(dejong, kenny, porter)
2004-11-24 (bug fix)[1071807] Fixed all uses of 'select' to use standard
macros rather than older bit-whacking style (kenny)
+2004-11-26 (bug fix)[1073524] Simplify the code to check for correctness of
+strstr, strtoul and strtod on unix (fellows)
+
2004-11-26 (bug fix)[1072136] Remove file normalize on tcl_findLibrary
search path uniqification added in 8.4.8 (porter)
+2004-11-30 (bug fix)[976520] Rework startup/initialization of the Tcl
+library, encoding search initialization, and Tcl_FindExecutable structure.
+[tclInit] no longer driven by the value of $::tcl_libPath (TCLLIBPATH).
+(porter)
+ *** POTENTIAL INCOMPATIBILITY : makes encoding names case sensitive
+ on Windows, where they have been case insensitive ***
+
2004-12-02 (bug fix)[1074671] Ensure tilde paths are not returned specially
by 'glob' (darley)
---- Released 8.4.9, December 6, 2004 --- See ChangeLog for details ---
+Doc improvements [759545,926590,935853,1017072,1018486,1022527,1027849,
+ 1032243,1047928,1048005,1058446,1062647,1065732,1073334,etc.]
+Test suite expansion [1036649,1001997,etc.]
+
+--- Released 8.5a2, December 7, 2004 --- See ChangeLog for details ---
-2004-12-29 (platform support)[1092952,1091967] MSVC7, gcc OPT compiles (hobbs)
+2004-12-13 (bug fix)[1083082] encoding memory leaks (ade,porter)
+
+2004-12-13 (bug fix)[1082349] restored C++ extension support (porter)
+
+2004-12-14 (bug fix)[1081541] workaround automake-ism "$U" (porter)
-2005-01-05 (bug fix)[1084595] encoding maps for some Chinese locales (fellows)
+2004-12-15 (new feature) CallFrames on execution, not C, stack (sofer)
+
+2004-12-16 (bug fix)[1085023] [interp limit] support in [vwait], etc. (fellows)
+
+2004-12-29 (bug fix)[1090413] make [clock scan 0030] work (morian,kenny)
+
+2004-12-29 (bug fix)[1092789] make [clock scan 10000] work (porter,kenny)
+
+2004-12-29 (platform support)[1092952,1091967] MSVC7, gcc OPT compiles (hobbs)
2005-01-06 (performance)[1020491] [http::mapReply] (fellows)
=> http 2.5.1
+2005-01-09 (bug fix)[1095909] stopped use of readdir_r (english)
+
+2005-01-10 (enhancement)[1081595] stopped use of TCL_DBGX (english)
+
+2005-01-17 (bug fix)[1100542] [glob] of Windows shares (schar,darley)
+
+2005-01-19 (new feature)[TIP 235] C API for ensembles (fellows)
+
+2005-01-21 (new feature)[TIP 233] virtual time (kupries)
+
2005-01-25 (bug fix)[1101670] [auto_reset] update for [namespace] (porter)
+***POTENTIAL INCOMPATIBILITY***
+May cause re-[source]-ing of files that have not anticipated that before.
2005-01-27 (new feature)[TIP 218] Tcl_Channel API update for threads (kupries)
@@ -6153,7 +6390,7 @@ by 'glob' (darley)
2005-02-10 (bug fix)[1119369] Tcl_EvalObjEx: avoid shimmer loss of List intrep
(sofer,macdonald)
-2005-02-10 (platform support) correct gcc builds for AIX-4+, HP-UX-11 (hobbs)
+2005-02-11 (platform support) correct gcc builds for AIX-4+, HP-UX-11 (hobbs)
2005-02-24 (bug fix)[1119798] prevent [source $directory] (porter,mpettigr)
=> tcltest 2.2.8
@@ -6162,34 +6399,76 @@ by 'glob' (darley)
2005-03-15 (platform support) OpenBSD ports patch (thoyts)
-2005-03-15 (platform support)[1163422] time_t wider than long (kenny)
-
2005-03-18 (bug fix)[1115904] restore recursion limit in direct eval (porter)
+2005-03-24 (bug fix) stop conflict between Tcltest and Thread packages (porter)
+
2005-03-29 (platform support) allow msys builds without cygwin (hobbs)
-2005-04-06 (bug fix)[1178445] fix memory waste at thread exit (vasiljevic)
+2005-04-01 (internal change)[1158008] internal rep of "list" Tcl_Obj's
+now uses a refcounted struct (sofer)
+***POTENTIAL INCOMPATIBILITY***
+For any code that goes poking into the internals of "list" Tcl_Obj's
+
+2005-04-05 (performance)[1174551] Tcl_DecrRefCount of Tcl_Obj "chains" (sofer)
+
+2005-04-08 (performance)[1077262] better Tcl_Encoding cache lifetimes (porter)
+
+2005-04-10 (bug fix)[1180368] [interp invokehidden] mem leak (kenny,porter)
+
+2005-04-12 (performance)[1177363] startup encoding file scan (porter)
+
+2005-04-12 (performance)[1182459] [clock format] (kenny)
2005-04-13 (bug fix) min buffer size dropped from 10 to 1 byte (gravereaux)
-2005-04-19 (bug fix)[947693] Windows pipes honor -blocking during close
-(gravereaux) ***POTENTIAL INCOMPATIBILITY***
-async pipes on windows, set -blocking 1 before [close] to receive exit status
+2005-04-16 (bug fix)[1178445] fix memory waste at thread exit (vasiljevic)
+
+2004-04-16 (bug fix)[1084111] [array names] memory leak (ade,sofer)
+
+2005-04-19 (bug fix)[1185933] [clock] init clobbered global vars (ring,kenny)
+
+2005-04-19 (new feature) [::tcl::unsupported::EncodingDirs] - unsupported
+command to set search path for encoding files (porter)
2005-04-20 (bug fix)[1090869] Tcl_GetInt accept 0x80000000, 64-bit
(porter,singh)
2005-04-22 (bug fix)[1187123] [string is boolean] respect EIAS (porter)
+2005-04-25 (enhancement) update to tzdata2005i (kenny)
+
2005-04-25 (platform support) builds on Mac OS X 10.1 (steffen)
+2005-04-27 (new feature)[TIP 183] [open $f {... BINARY ...}] (porter)
+
+2005-04-29 (new feature)[TIP 176] simple index arithmetic (porter)
+
2005-05-06 (platform support) x86_64 Solarix cc and Solaris 10 builds (hobbs)
+2005-05-10 (bug fix)[1198892] [expr {i**0}] error (kaitschu,markus)
+
+2005-05-10 (new feature)[TIP 132] floating-point conversion to string (kenny)
+***POTENTIAL INCOMPATIBILITY***
+For scripts that rely on (tcl_precision==12) number formatting
+
+2005-05-10 (new feature)[TIP 232] math functions as commands (kenny)
+***POTENTIAL INCOMPATIBILITY***
+Tcl_GetMathFuncInfo functioning is reduced; routine is now deprecated
+
+2005-05-13 (feature removed) TCL_NO_MATH compiler directive (porter)
+
2005-05-14 (platform support) Mac OSX: configurable CoreFoundation API
(steffen)
2005-05-14 (platform support) Mac OSX: use realpath when threadsafe (steffen)
+2005-05-17 (feature removed) Tcl_ObjType's "list", "procbody", "index",
+"ensembleCommand", "localVarName", "levelReference, "boolean" are no
+longer registered (porter)
+***POTENTIAL INCOMPATIBILITY***
+For any callers of Tcl_GetObjType on those strings
+
2005-05-20 (bug fix)[1201589] boolean literal prefix in expressions (porter)
2005-05-24 (platform support) Darwin build support merged into unix (steffen)
@@ -6199,15 +6478,32 @@ Can support [load] from memory as well (steffen)
2005-05-24 (new feature)[1202178] [time] returns non-integer result (steffen)
+2005-05-25 (new feature)[TIP 182] [expr {bool(...)}] (mistachkin,porter)
+
+2005-05-30 (new feature)[TIP 229] [namespace path] (fellows)
+
2005-05-31 (bug fix)[1082283] Unix: notifier thread now joinable (vasiljevic)
+2005-06-01 (new feature)[TIP 241] -nocase: lsort, lsearch, switch (mistachkin)
+
+2005-06-01 (bug fix)[1209759] "return TCL_RETURN;" could cause panic (porter)
+
Documentation improvements [1075433,1085127,1117017,1124160,1149605,etc.]
---- Released 8.4.10, June 4, 2005 --- See ChangeLog for details ---
+--- Released 8.5a3, June 4, 2005 --- See ChangeLog for details ---
2005-06-06 (bug fix)[1213678] Windows/gcc: crash in stack.test (kenny)
-2005-06-07 (bug fix) Unix: --enable-threads compile failure (fellows)
+2005-06-07 (new feature)[TIP 208] [chan] and [chan truncate] (fellows)
+
+2005-06-07 (revert) Restored registration of "procbody" Tcl_ObjType (porter)
+Reduces the ***POTENTIAL INCOMPATIBILITY*** from 2005-05-17.
+
+2005-06-13 (bug fix)[1217375,1219176] [file mkdir] race (diekhans,darley)
+
+2005-06-14 (bug fix)[1220058] [namespace delete] crash (duquette,fellows)
+
+2005-06-17 (bug fix)[1221395] Tcl_LimitSetTime able to break [vwait] (fellows)
2005-06-18 (bug fix)[1154163] [format %h] on 64-bit OS's (kraft,fellows)
@@ -6223,18 +6519,16 @@ Documentation improvements [1075433,1085127,1117017,1124160,1149605,etc.]
2005-06-23 (bug fix)[1225957] Windows/gcc: crashes in assembler code (kenny)
-2005-06-27 (revert)[1101670] [auto_reset] disabled in non-global namespace.
-Restores Tcl 8.4.9 behavior (porter)
-
---- Released 8.4.11, June 28, 2005 --- See ChangeLog for details ---
+2005-06-24 (bug fix) make Tcl_Preserve safe in Tk exit handlers (kenny)
2005-07-01 (bug fix)[1222872] notifier spurious wake-up protection (vasiljevic)
-2005-07-05 (bug fix)[1077262] improved Tcl_Encoding lifetimes (porter)
-
2005-07-05 (bug fix)[1230597] allow idempotent [namespace import] (porter)
-2005-07-07 (bug fix)[1095909] readdir_r usage purged (hobbs)
+2005-07-15 (bug fix)[1237907] localtime() => NULL => crash (kenny)
+
+2005-07-21 (dropped support) IRIX 4, RISCos, Ultrix, and ancient BSD (kenny)
+***POTENTIAL INCOMPATIBILITY***
2005-07-22 (enhancement)[1237755] 8.4 features in script library (fradin,porter)
@@ -6242,6 +6536,12 @@ Restores Tcl 8.4.9 behavior (porter)
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)
+***POTENTIAL INCOMPATIBILITY***
+
+2005-07-27 (bug fix)[1214462] [unknown] can return exceptions (porter)
+
+2005-07-27 (new feature) value of ::tcl_precision now kept per-thread (porter)
+***POTENTIAL INCOMPATIBILITY***
2005-07-28 (unix bug fix)[1245953] O_APPEND for >> redirection (fellows)
@@ -6253,16 +6553,31 @@ Restores Tcl 8.4.9 behavior (porter)
2005-08-05 (Solaris bug fix)[1252475] recognize cp1251 encoding (wagner,fellows)
-2005-08-17 (bug fix)[1217375] [file mkdir] race (diekhans,darley)
+2005-08-11 (config options) eliminated USE_THREAD_STORAGE option (kenny)
+
+2005-08-23 (toolchain support) autoconf-2.59 now required (dejong)
+
+2005-08-24 (new feature)[TIP 219] reflected channels ([chan create]) (kupries)
2005-08-25 (bug fix)[1267380] [lrepeat] buffer overflow prevention (fellows)
+2005-08-26 (bug fix) fix [namespace ensemble] crashes in Snit (fellows)
+
2005-08-29 (bug fix)[1275043] restore round() away from zero (kenny)
+2005-08-29 (bug fix)[1189657] correct [tcl::tm::roots] (porter)
+
2005-09-07 (bug fix)[1283976] invalid [format %c -1] result (porter)
+2005-09-08 (new feature)[1242844][TIP 254] new types for Tcl_LinkVar (fellows)
+
+2005-09-07 (toolchain support) deprecate TCL_VARARGS*; stdarg.h assumed (porter)
+***POTENTIAL INCOMPATIBILITY***
+
2005-09-15 (RHEL bug fix)[1287638] support open >2GB files RHEL 3 (palan)
+2005-09-08 (new feature)[TIP 255] [expr min()] and [expr max()] (hobbs)
+
2005-09-30 (bug fix)[1306162] $argv encoding and list formatting (porter)
2005-10-04 (bug fix)[1067708] [fconfigure -ttycontrol] leak (hobbs)
@@ -6274,99 +6589,159 @@ Restores Tcl 8.4.9 behavior (porter)
2005-10-05 (bug fix)[979640] buffer overrun mixing putenv(), ::env (bold,hobbs)
-2005-10-13 (bug fix)[1284178] [format] accept all integer values (porter)
+2005-10-08 (new feature)[TIP 237] unlimited range for integers (kenny,porter)
+***POTENTIAL INCOMPATIBILITY*** for any code that relies on implicit truncation
+of integer calculations to the range of a C long
+
+2005-10-14 (platform support)[1256937] MSVC++ static builds (thoyts)
-2005-10-22 (bug fix)[1251791] optimization exposed wide/int difference(sofer)
+2005-10-19 (bug fix)[1331475] [dict append] crash (bills,sofer)
-2005-10-23 (bug fix)[1334947] value refcount error in var setting (sofer)
+2005-10-20 (bug fix)[1333036] [lset] shared sublist handling (sofer)
+
+2005-10-23 (bug fix)[1335006] memleack in [glob] (melbardis,darley)
+
+2005-10-23 (bug fix)[1325803] Win: [file stat] on links (bonilla,darley)
2005-11-01 (bug fix)[1337941] Tcl_TraceCommand() -> crash (devilliers,porter)
-2005-11-03 (new Win NT/XP feature) Unicode console support (kovalenko,thoyts)
+2005-11-02 (platform support)[1256937] MSVC 8 support (thoyts)
-2005-11-03 (bug fix)[1201171] [encoding system] in Tclkit (schekin,porter)
+2005-11-03 (new Win NT/XP feature) Unicode console support (kovalenko,thoyts)
-2005-11-04 (bug fix)[1337229,1338280] [namespace delete] / unset traces (porter)
+2005-11-04 (bug fix)[1337229,1338280] [namespace delete] / unset traces (sofer)
2005-11-04 (enhancement) Korean timezone abbreviations (kenny)
-2005-11-04 (bug fix)[1317477] double encoding of time zone (kenny)
+2005-11-04 (platform support)[1163896] LynxOS [load] (heidibr)
-2005-11-04 (Win enhancement)[1267871] extended exit codes (newman,thoyts)
+2005-11-04 (bug fix)[1334947] value refcount error in var setting (sofer)
-2005-11-04 (platform support)[1163896] LynxOS [load] (heidibr)
+2005-11-04 (Win enhancement)[1267871] extended exit codes (newman,thoyts)
-2005-11-08 (bug fix)[1348775] unset trace memory leak (sofer)
+2005-11-07 (bug fix)[1348775] unset trace memory leak (sofer)
-2005-11-08 (bug fix)[1162286] [package ifneeded] warns reported (lavana,porter)
- *** POTENTIAL INCOMPATIBILITY ***
+2005-11-08 (bug fix)[1162286] [package require] checks that the script
+registered by [package ifneeded] provides the version it claims (lavana,porter)
+*** POTENTIAL INCOMPATIBILITY ***
-2005-11-09 (bug fix)[1350293] [after $negative $script] fixed (kenny)
+2005-11-09 (bug fix)[1350293,1350291] [after $negative $script] fixed (kenny)
-2005-11-15 (Win bug fix)[926016,1353840] correct [file mtime] (kenny)
+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)
+=> http 2.5.2
-2005-11-18 (bug fix)[1359094] Tclkit crash (thoyts, kupries)
+2005-11-18 (revert) Restored registration of "list" Tcl_ObjType (porter)
+Reduces the ***POTENTIAL INCOMPATIBILITY*** from 2005-05-17.
-2005-11-18 (bug fix)[1355942,1355342] cmd delete trace/ namespace delete (sofer)
+2005-11-18 (bug fix)[1359094] Tclkit crash (thoyts, kupries)
2005-11-20 (bug fix)[1091431] Tcl_InitStubs failure crashes wish (english)
+2005-11-27 (platform support) Darwin 64bit, Tiger copyfile(), and
+Max OSX universal binaries support (steffen)
+
+2005-11-28 (bug fix) [clock] DST transition error (mackerras,kenny)
+
2005-11-29 (bug fix)[1366683] [lsearch -regexp] backrefs (cleverly,fellows)
-2005-11-29 (enhancement)[1369597] Win 64: --enable-64bit=amd64|ia64 (hobbs)
+2005-11-30 (performance) recoded portions of [clock] in C (kenny)
+
+2005-11-30 (enhancement) improved bytecode compiling of [switch] (fellows)
+*** POTENTIAL INCOMPATIBILITY ***
+For loading bytecode compiled and saved by earlier 8.5alpha releases
2005-12-05 (Darwin bug fix)[1034337] NFS recursive file delete (steffen)
---- Released 8.4.12, December 3, 2005 --- See ChangeLog for details ---
+2005-12-08 (platform support) Win x64 build (hobbs)
2005-12-09 (bug fix)[1374778] [lsearch -start $pastEnd] => -1 (fellows)
-2005-12-12 (bug fix)[1241572] correct [expr abs($LONG_MIN)] again (max)
-
2005-12-12 (bug fix)[1377619] configure syntax error exposed in bash-3.1 (hobbs)
-2006-01-09 (bug fix)[1400572] [info level $l] => "namespace inscope" (porter)
+2005-12-13 (bug fix)[1379349] [dict for] CoW error (ring,hippler,fellows)
+
+2005-12-18 (bug fix)[1382528] [dict for {k v} {} {}] crash (kovalenko,fellows)
+
+2005-12-27 clock tzdata updated to Olson's tzdata2005r (kenny)
+
+2005-12-27 libtommath updated to release 0.37 (kenny)
+
+2006-01-09 (bug fix)[1480572] [info level $l] => "namespace inscope" (porter)
+
+2006-01-11 (compat support)[1397843] when ::errorInfo is traced, fall back to
+old pattern of stack trace construction (porter).
+Reduces the ***POTENTIAL INCOMPATIBILITY*** from 2004-10-05.
+
+2006-01-12 (bug fix)[1366227] Win: [file stat] sharing violation (darley)
2006-01-23 (bug fix)[1410553] Tcl_GetRange Unicode confusion (twylite,spjuth)
+2006-01-23 (bug fix)[1412695] args handling in precompiled procs (traum,sofer)
+
+2006-02-01 (new feature)[1275435][TIP 250] [namespace upvar] (sofer)
+
+2006-02-01 (new feature)[958222][TIP 181] [namespace unknown] (madden)
+
+2006-02-01 (new feature)[944803][TIP 194] [apply] (mistachkin)
+
+2006-02-08 (new feature)[1413934][TIP 258] [encoding dirs], etc. (porter)
+
+2006-02-09 (new feature)[1413115][TIP 215] auto-init [incr] (leitgeb)
+
+2006-03-02 (bug fix)[1379287] norm of paths with /../ back to root (porter)
+
+2006-03-03 (compat support) Restored registration of a "boolean" Tcl_ObjType
+(porter)
+Reduces the ***POTENTIAL INCOMPATIBILITY*** from 2005-05-17.
+
2006-03-06 (bug fix)[1439836,1444291] fix TCL_EVAL_{GLOBAL,INVOKE} handling
when auto-loading or exec traces are present (porter)
2006-03-10 (bug fix)[1437595] Win socket finalize with threads (vasiljevic)
-2005-03-13 (revert 2005-07-26 change) ${prefix}/share on ::tcl_pkgPath (porter)
+2006-03-13 (revert 2005-07-26 change) ${prefix}/share on ::tcl_pkgPath (porter)
-2006-03-14 (bug fix)[1381436,859820] threadsafe Tcl_WaitPid (gravereaux,kupries)
+2006-03-14 (bug fix)[1448251] TCLX.y_TM_PATH handling (noble, kupries)
2006-03-14 (bug fix)[768659] pipeline error when last command missing (kupries)
2006-03-18 (bug fix)[1193497] Win porting of [file writable] (darley,vogel)
-2006-03-28 (bug fix)[1064247] BSD: path normalization with realpath() (steffen)
+2006-03-18 (bug fix)[1084705] [glob -nocomplain] silence empty result only,
+no other errors (darley)
+***POTENTIAL INCOMPATIBILITY***
-2006-03-28 (revert 2005-11-03 feature) Unicode console support (hobbs)
- *** POTENTIAL INCOMPATIBILITY ***
+2006-03-21 (platform enhancement)[823329] HFS globbing support (steffen)
+
+2006-03-23 (platform support) updated tcl.spec file (max)
+
+2006-03-28 (bug fix)[1064247] BSD: path normalization with realpath() (steffen)
2006-04-03 (bug fix)[1462248] crash reading utf-8 chars spanning multiple
buffers at end of file (kraft,kupries)
-2006-04-04 (revert 2005-11-08)[1162286] [package ifneeded] warns (porter)
- *** POTENTIAL INCOMPATIBILITY ***
-
2006-04-05 (bug fix)[1464039] Tcl_GetIndexFromObj: empty key (fellows)
2006-04-05 (bug fix) overdue dde, registry patchelevel increments (porter)
-=> dde 1.2.4
-=> registry 1.1.4
+=> dde 1.3.2
+=> registry 1.2
2006-04-06 (bug fix)[1457515] TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
removed (steffen)
2006-04-11 (bug fix)[1458266] enter/enterstep trace interference (leunissen)
---- Released 8.4.13, April 19, 2006 --- See ChangeLog for details ---
+2006-04-12 (feature change)[1376892] revised definition of [:print:] (fellows)
+
+(platform support) Use of _ANSI_ARGS_ purged. ANSI compiler required (fellows)
+
+Documentation improvements [1211078,1190891,1292427,1277503,1104682,1359183,
+1415725,666770]
+
+--- Released 8.5a4, April 27, 2006 --- See ChangeLog for details ---
2006-05-04 (bug fix)[1480509] srand() accept wide input (porter,afredd)
@@ -6375,20 +6750,33 @@ removed (steffen)
2006-05-13 (bug fix)[1482718] proc re-compile: preserve the previous
bytecode while references still on the stack (porter,ryazanov)
-2006-05-13 (bug fix)[943995] fixed [glob] on VFS (porter)
-
2006-05-27 (bug fix)[923072] Darwin: made unthreaded CoreFoundation notifier
naked-fork safe on Tiger (steffen)
-2006-05-31 (revert 2006-01-09)[1400572] namespace inscope & info level (porter)
- *** POTENTIAL INCOMPATIBILITY ***
+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
+interface for virtual filesystems
-2006-06-14 (platform support)[1424909] MS VS2005 support (thoyts)
+2006-07-05 (enhancement) Expression parser rewrite avoids stack overflow,
+reduces from O(N^2) to O(N) complexity, and greatly improves syntas error
+messages (porter)
+***POTENTIAL INCOMPATIBILITY***
+For any code relying on exact error messages.
2006-07-20 (platform support) Mac OS X weak linking (steffen)
2006-07-20 (bug fix) Darwin: execve() works iff event loop not yet run (steffen)
+2006-07-24 (bug fix)[1518166] Uninitialized Tcl_DString (afredd)
+
+2006-07-30 (bug fix)[1426279,1505383,1494664,1531530] [clock] fixes (kenny)
+
+2006-08-09 (bug fix)[1531184] [dict for {file stat} x {}] crash (fellows)
+
+2006-08-10 (bug fix)[1538262,1530474] code cleanup; optimizations (afredd)
+
2006-08-18 (bug fix) intermittent failures in TclUnixWaitForFile() (steffen)
2006-08-18 (platform support) Darwin x86_64 (steffen)
@@ -6397,61 +6785,168 @@ naked-fork safe on Tiger (steffen)
2006-08-21 (bug fix) Darwin: recursively called event loop (steffen)
+2006-08-21 (enhancement) Darwin: nanosec resolution clicks and [time] (steffen)
+
+2006-08-28 (bug fix)[1547681] TclFormatObj count arguments (mistachkin,porter)
+
+2006-08-28 (bug fix) stack.test failure on FreeBSD (mistachkin)
+
2006-08-30 (bug fix)[1548263] filesystem segfaults (hobbs,mccormack)
+2006-08-31 (bug fix)[1541274] [expr {sqrt(-1)}] => -NaN (suchenwirth,porter)
+
2006-09-06 (bug fix)[999544] use of MT-safe system calls (vasiljevic)
2006-09-10 (platform support) Darwin: msgcat use CFLocale (steffen)
-=> msgcat 1.3.4
+=> msgcat 1.4.2
+
+2006-09-10 (new feature) tcltest option: -verbose line (steffen)
+=> tcltest 2.3a1
+
+2006-09-19 (bug fix)[1555271,1561260] Several ** operator bugs (porter)
2006-09-22 (bug fix)[1562528] NULL terminates variadic calls (fellows,ryazanov)
+2006-09-22 (new feature)[1520767][TIP 268] [package] alpha/beta version;
+[package require] ranges, [package prefer] selection mode (kupries)
+
2006-09-26 (platform support) MSVC8 AMD64 support (thoyts)
+2006-09-27 (bug fix)[1567222] bignum << errors (porter)
+
+2006-09-30 (enhancement)[1190441] quiet no-op [history] (sofer)
+
+2006-10-04 clock tzdata updated to Olson's tzdata2006m (kenny)
+
2006-10-05 (bug fix)[1570718] make [lappend $nonList] complain (sofer,virden)
2006-10-05 (bug fix)[1122671] alignment fixes in unicode encoding routines
(hobbs,staplin)
-2006-10-05 (new feature) [set ::http::strict 1] (default value is 0) to enable
+2006-10-05 (enhancement) Allow "_" in Tcl Module filenames (kupries)
+
+2006-10-05 (new feature) [set ::http::strict 0] (default value is 1) to disable
URL validity checking against RFC 2986 (hobbs)
=> http 2.5.3
---- Released 8.4.14, October 19, 2006 --- See ChangeLog for details ---
+2006-10-06 (new feature)[1565751][TIP 275] [binary scan] unsigned (thoyts)
+
+2006-10-10 (bug fix)[1566526] crash cleaning up [namespace path] data (porter)
+
+2006-10-12 (bug fix)[1576006] better error messages from [interp alias] (sofer)
+
+2006-10-13 (platform support) get stack size on Darwin (steffen)
+
+--- Released 8.5a5, October 20, 2006 --- See ChangeLog for details ---
+
+2006-10-20 (configure change) Added autodetection for OS-supplied timezone
+files (max)
+
+2006-10-23 (enhancement)[1577278] Ensure the Tcl call stack always has a
+CallFrame, even at level 0 (sofer)
+ *** POTENTIAL INCOMPATIBILITY for users of tclInt.h ***
+
+2006-10-23 (enhancement)[1577492] Tcl_PushCallFrame and [info level]
+enhanced for ensemble rewrites (sofer)
+ *** POTENTIAL INCOMPATIBILITY for [info level 0] on interp alias ***
+
+2006-11-02 (feature change)[TIP 293] Replace {expand} with {*} (hobbs)
+ *** POTENTIAL INCOMPATIBILITY with previous 8.5 alphas only ***
+
+2006-11-04 (new feature)[TIP 274] Exponentiation operator is right
+associative (porter)
+
+2006-11-09 (new feature)[TIP 272] Added [lreverse] and [string reverse]
+commands (fellows)
+
+2006-11-14 (new feature)[TIP 261] [namespace import] returns list of
+imported commands (porter)
-2006-10-31 (platform support)[1582769] Fix build with VC2003 (thoyts)
+2006-11-15 (new feature)[TIP 270] New C routines Tcl_ObjPrintf,
+Tcl_AppendObjToErrorInfo, Tcl_Format, Tcl_AppendLimitedToObj,
+Tcl_AppendFormatToObj, Tcl_AppendPrintfToObj (porter)
-2006-11-07 (bug fix)[1586470] [file copy] on afs (kupries,dionizio)
+2006-11-22 (feature change) Moved TCL_REG_BOSONLY from tcl.h to tclInt (porter)
+
+2006-11-22 (new feature)[TIP 269] Added [string is list] classification
+command (mistackin, fellows)
+
+2006-11-25 (new feature)[TIP 174] Added commands corresponding to most
+expr operators in ::tcl::mathop (fellows)
2006-11-26 (platform support)[1230558] --enable-64bit on more systems (steffen)
-2006-11-27 (bug fix)[1602208] use > 32 async sockets on 64bit system (fontaine)
+2006-11-27 (bug fix)[1602208] Fix 64-bit handling of select() on unix where
+fd was greater than 32 (fontaine, kenny)
-2007-01-25 (configure change) ensure CPPFLAGS env var used when set (steffen)
+2006-11-28 (new feature)[TIP 280] Added [info frame] command for more
+Tcl-level debugging information (kupries)
-2007-01-30 (enhancement) new target: `install-private-headers` (hobbs, steffen)
+2006-12-01 (feature change)[TIP 298] Change Tcl_GetBignumAndClearObj to
+Tcl_TakeBignumFromObj (porter)
-2007-02-12 (bug fix)[1516109] escape encodings crossing chan buffers (dejong)
+2006-12-01 (new feature)[TIP 287] Added [chan pending] subcommand (cleverly)
-2007-03-01 (bug fix)[1671138] compiled [foreach {} x {}] hangs (fellows)
+2006-12-01 (new feature)[TIP 299] Added isqrt() expr operator (kenny)
-2007-03-10 (bug fix)[1675116] list shimmer crash in [lsort] (fellows)
+2006-12-04 (new feature)[TIP 267] Added -ignorestderr option to exec (fellows)
-2007-03-13 (bug fix)[1671087] list shimmer crash in [foreach] (porter)
+2006-12-05 (new feature)[TIP 291] ::tcl_platform(pointerSize) key (kupries)
-2007-03-13 (bug fix)[1669489] list shimmer crash in [array set] (porter)
+2007-01-11 (configure change) Remove "-Wconversion" from deflt CFLAGS (english)
-2007-03-17 (bug fix)[1682211] buffer overflow in [registry keys] (kenny)
-=> registry 1.1.5
+2007-01-25 (configure change) Ensure CPPFLAGS env var is used when set (steffen)
+
+2007-02-19 (configure change) Use SHLIB_SUFFIX=".so" on HP-UX IA64 (was
+".sl") (hobbs)
+
+2007-02-20 (bug fix)[1479814] Handle Windows NT \\?\... extended paths (thoyts)
+
+2007-03-01 (bug fix)[1671138] Fix infinite loop in compiled foreach with an
+empty list (fellows)
+
+2007-03-07 (enhancement) Improved Windows time zone tables to handle new US
+DST rules (kenny)
+
+2007-03-09 (enhancement) Improved Y2038 compliance of zoneinfo files (kenny)
-2007-04-29 (bug fix) fts_open() crash on 64bit Darwin 8 or earlier (steffen)
+2007-04-02 (enhancement) Added bytecode compilation for global, variable,
+upvar and namespace upvar (sofer)
---- Released 8.4.15, May 25, 2007 --- See ChangeLog for details ---
+2007-04-20 (bug fix) Improve clock localization for Japanese locale (kenny)
+
+2007-04-20 (enhancement) Document Tcl_SetNotifier & Tcl_ServiceModeHook (kenny)
+
+2007-04-23 (bug fix) fts_open() crash on 64bit Darwin 8 or earlier (steffen)
+
+--- Released 8.5a6, April 25, 2007 --- See ChangeLog for details ---
+
+2007-04-30 (bug fix)[1705778] many valgrind-detected leaks corrected
+
+2007-05-01 (bug fix)[1710709] leak in [string map] (porter)
+
+2007-05-02 (bug fix)[1710707] leaks in filesystem paths (mistachkin,kenny)
+
+2007-05-18 (feature change) {expand} syntax support removed. (porter)
+ *** POTENTIAL INCOMPATIBILITY with previous 8.5 alphas only ***
2007-05-29 (bug fix)[1712723] Joinable thread death on 64-bit (virden,hobbs)
+2007-05-30 (feature change)[1725186] When expanded literals are parsed,
+(example: {*}{1 2 3}), TCL_TOKEN_EXPAND_WORD token is no longer returned.
+Tokens reflecting the expansion are returned instead. (porter)
+ *** POTENTIAL INCOMPATIBILITY with previous 8.5 alphas only ***
+
2007-06-06 (platform support) Darwin: add plist to tclsh (steffen)
+2007-06-12 (enhancement) [info] is now a [namespace ensemble] (fellows)
+
+2007-06-20 (enhancement) better `make html` results (hobbs)
+
+2007-06-21 (feature change)[1740962] leave traces created during execution
+of traced command do not fire (sofer)
+ *** POTENTIAL INCOMPATIBILITY ***
+
2007-06-23 (bug fix) Darwin: prevent post-fork() abort() (steffen)
2007-06-27 (bug fix)[1743941] Infinite loop in Tcl_CreateTrace traces (porter)
@@ -6460,69 +6955,629 @@ URL validity checking against RFC 2986 (hobbs)
2007-06-30 (bug fix)[1726873] crash in thread sync objects (vasiljevic,twylite)
+2007-06-30 (bug fix)[1717186] [lsort -command \{ $l] leak (afredd,fellows)
+
2007-07-05 (bug fix)[1743676] no command named "" error message (porter,virden)
+2007-07-11 (bug fix)[1752146] [while 1 {}] & [interp limit] on commands (sofer)
+
+2007-07-31 (bug fix)[681877] tcl_platform(user) from system, not env (fellows)
+
+2007-07-31 (enhancement)[1750051] space efficiency of Tcl variables (sofer)
+ *** POTENTIAL INCOMPATIBILITY for C code that accesses internal
+ Tcl structs Var, Bytecode, Namespace, or CallFrame. ***
+
+2007-08-01 (enhancement)[1764318] word.tcl proc rewrites (petasis,fellows)
+
+2007-08-08 (bug fix)[1770224] [tcl::mathop::>> $big1 $big2] errors (porter)
+
2007-08-14 (platform support) Darwin [load] from VFS on intel & 64bit (steffen)
-2007-08-25 (bug fix)[1751117] [clock format ... %c] buffer overrun (kenny)
+2007-08-15 (bug fix)[1773127] corrected open mode "a+" (rottman,fellows)
+
+2007-08-16 (bug fix)[1773040] ::errorInfo trace crash (janssen,porter)
+
+2007-08-16 (performance)[1564517] pre-compile constant expressions (porter)
+
+2007-08-21 (bug fix)[1775878] 'puts \' in interactive tclsh failed to move to
+prompt for continuation line (porter)
+
+2007-08-25 (bug fix)[1781282] [clock scan] case senstivity (kenny)
+
+2007-08-25 (performance)[1767293] ** on native integer types (kenny)
+
+2007-09-03 clock tzdata updated to Olson's tzdata2007g (kenny)
+
+2007-09-06 (platform support) Darwin: drop support for Xcode 1.5 project, add
+project for Xcode 3.0 (steffen)
+
+2007-09-08 (bug fix)[1786481] nested [dict update] crash (fellows)
+
+2007-09-08 (bug fix)[1710710] TclPtrSetVar leak (mistachkin,sofer)
+
+2005-09-09 (feature removed) Tcl_ObjType "nsName" no longer registered (porter)
+ *** POTENTIAL INCOMPATIBILITY for Tcl_GetObjType("nsName") ***
2007-09-10 (bug fix)[1740631] Linked variable unlink prevention (maros,hobbs)
-2007-09-11 (platform support) Windows AMD64 support (thoyts)
+2007-09-11 (bug fix)[1786481] [dict update] stack management (sofer)
+ *** POTENTIAL INCOMPATIBILITY with previous 8.5 alpha bytecode only ***
+
+2007-09-11 (bug fix)[1578344] [package require -exact] 8.4 compat (porter)
+ *** POTENTIAL INCOMPATIBILITY with previous 8.5 alphas only ***
2007-09-11 (bug fix)[1772989,1071322] Support _, : in test constraints (porter)
-=> tcltest 2.2.9
+=> tcltest 2.3b1
+
+2007-09-11 (platform support) Windows AMD64 support (thoyts)
2007-09-14 (enhancement)[1793984] DTrace provider for Tcl (steffen)
+2007-09-14 (bug fix)[1519940] surplus ns path invalidation (fellows,bauer)
+
2007-09-15 (platform support) SunOS-5.1x link with cc, not ld (steffen)
---- Released 8.4.16, September 21, 2007 --- See ChangeLog for details ---
+2007-09-17 (platform support)[1748251] Fix NetBSD link failures (english)
-2007-10-03 (bug fix) Corrected find of deleted command (sofer,neumann)
+(bug fix)[1066755] Several stack efficiency efforts increases recursion limit
+on Windows to be larger than the default [interp recursionlimit] value
+
+--- Released 8.5b1, September 26, 2007 --- See ChangeLog for details ---
+
+2007-10-02 (bug fix)[1806422] proper [tcl::tm::path] autoload (porter)
+
+2007-10-02 (bug fix) Improve Tcl_DecrRefCount() robustness (staplin)
+
+2007-10-11 (bug fix)[1805887] [string is int -failindex] for 0o, 0b (porter)
2007-10-15 (bug fix)[1813528] Tcl_ParseBraces read past buffer (mistachkin)
-2007-10-30 (bug fix)[1810264] stop panic in RE lexer (fellows)
+2007-10-25 (bug fix)[1726873] intermittent crash in threads (vasiljevic)
+
+--- Released 8.5b2, October 26, 2007 --- See ChangeLog for details ---
+
+2007-10-27 (bug fix)[1821159] fixed broken compile on x86_64 (sofer)
+
+2007-10-27 (bug fix)[1810264] stop panic in RE lexer (fellows)
+
+2007-10-28 (enhancement)[1826906] Embed iso8859-1 encoding in libtcl (fellows)
+
+2007-11-01 (bug fix)[1808258] [string is ascii \000] (fellows)
+
+2007-11-05 (bug fix)[1823576] [fconfigure $serial -xchar \000] (cassof)
+
+2007-11-07 (performance)[1827996] binary glob matching (hobbs)
+
+2007-11-07 (performance) binary [gets] (hobbs)
+
+2007-11-09 (performance)[1829248] interp state reset (sofer)
+
+2007-11-10 (performance) stack checking (sofer)
+
+2007-11-10 (performance) list indexing bytecode (sofer)
+
+2007-11-11 (performance)[1830038] macros to fetch Tcl_Obj intreps (sofer)
+
+2007-11-11 (performance)[1830166] RE bytecode for simple cases (hobbs)
+
+2007-11-13 (performance) [switch] & [regexp] use RE bytecode (hobbs, fellows)
+
+2007-11-14 (performance) bytecode for [info exists] (fellows)
+
+2007-11-15 (new feature)[1231022] configure option: --disable-rpath (fellows)
2007-11-15 (bug fix)[1810038] infinite loop in RE compiler (lane,porter)
-2007-11-27 (bug fix)[1823552] encoding conversion for [info hostname] (porter)
+Many significant documentation improvements (fellows, sofer)
+
+--- Released 8.5b3, November 19, 2007 --- See ChangeLog for details ---
+
+2007-11-20 (enhancement) string rep of dict has stable order (fellows)
+
+2007-11-21 (enhancement) compiled ensemble support (fellows)
+
+2007-11-22 (enhancement) [dict] is now an ensemble (fellows)
+
+2007-11-23 (enhancement) [string] is now an ensemble (fellows)
+
+2007-11-26 (bug fix)[1815573] Correct stack checking failure (sofer,golovan)
+
+2007-11-27 (bug fix)[800753] Document single byte char limit for
+[chan configure -eofchar] (cassoff)
+
+2007-12-03 (enhancement)[1836519] [switch $val $body] safe/fast (fellows,spjuth)
+
+2007-12-03 (release) tcltest package bump to 2.3.0 (porter)
+
+2007-12-03 (bug fix)[1618235] fix BSD compile errors (fellows)
2007-12-05 (bug fix)[1844789] fix [lsearch -exact -integer] crash (fellows)
-2007-12-13 (bug fix)[1773127] corrected open mode "a+" (rottman,fellows)
+2007-12-05 (performance)[1845092] Tcl_ObjType for channel names (hobbs)
+
+2007-12-14 (bug fix)[1602539] NUL pollution in [glob] result (hobbs)
+
+2007-12-17 (bug fix)[1851832,1851524] memory alignment correction (sofer)
2007-12-18 (bug fix)[1810264] revised regexp engine to prevent debilitating
over-consumption of resources (drewry,lane,ormandy,fellows)
---- Released 8.4.17, January 4, 2008 --- See ChangeLog for details ---
+Several documentation and release notes improvements
+
+--- Released 8.5.0, December 20, 2007 --- See ChangeLog for details ---
+
+2007-12-23 (bug fix)[1857126] restore backref support to regexps (hobbs)
+
+2007-12-26 (enhancement)[1856994] [lsort] performance (sofer)
+
+2008-01-10 (bug fix)[1867855] fix [format %lli 0] crash (porter)
+
+2008-01-11 (bug fix)[1850424,1860425] stack checking on *bsd (sofer,noble)
2008-01-13 (bug fix)[1353846] crash in read-only serial (hobbs,newman)
+2008-01-15 (bug fix)[1869989] mem leak; expr literals (porter,melbardis)
+
+2008-01-20 (bug fix)[1869405] binary [gets]; stacked channels (hobbs,ficicchia)
+
+2008-01-22 (bug fix)[1867855] fix [lreverse {}] crash (sofer,madden)
+
2008-01-30 (bug fix)[1882373] fix Tcl_GetAlias pointer code (an00na)
---- Released 8.4.18, February 8, 2008 --- See ChangeLog for details ---
+Several documentation and release notes improvements
+
+--- Released 8.5.1, February 5, 2008 --- See ChangeLog for details ---
+
+2008-02-06 (enhancement) [clock format] performance (kenny)
+
+2008-02-12 (bug fix)[1891827] compiled [switch -nocase] error (fellows)
2008-02-22 (bug fix)[1818565] missing state array in http::status (thoyts)
=> http 2.5.4
-2008-02-26 (bug fix) possible crash in [gets] (hobbs)
+2008-02-26 (bug fix)[1868845] corrected [eof] ordering (thoyts)
2008-02-26 (new feature) [http::meta] command (thoyts)
=> http 2.5.5
+2008-02-26 (bug fix)[1902436] fixed regexps ending in \* (hobbs)
+
+2008-02-27 (bug fix)[1862555,1902423] [clock] range & l10n (kenny)
+
+2008-02-28 (bug fix) [return -level 0] memory leak (porter)
+
+2008-02-28 (bug fix) [format %llx $big] memory leak (porter)
+
+2008-02-28 (bug fix) expression parser error message memory leak (porter)
+
+2008-02-28 (bug fix) memory leak when enter trace modifies command (porter)
+
+2008-02-29 (enhancement) Consumer refcounting for Tcl_SetReturnOptions()
+and Tcl_AddObjToErrorInfo() (spjuth,porter)
+ *** POTENTIAL INCOMPATIBILITY ***
+
2008-03-07 (bug fix)[1899164] Avoid expr and script bytecode confusion (porter)
+2008-03-07 (bug fix)[1904907] finalize crash in Tcl_GetReturnOptions (kupries)
+
+2008-03-10 (bug fix)[1893815] expr {abs(-1e-350)} => -0.0 (porter)
+
+2008-03-10 (bug fix)[1901113] crash in [tcl::Bgerror {} {}] (madden,porter)
+
+2008-03-11 (bug fix)[1911919] unset trace inf loop in namespace delete (sofer)
+
+2008-03-12 (new feature) some HTTP 1.1 support in http (and more!) (hobbs)
+=> http 2.7
+
+2008-03-13 (enhancement) support space in INSTALL_ROOT or $builddir (steffen)
+
+2008-03-16 (bug fix)[1903325] bytecode stack space prediction crash (fellows)
+
+2008-03-18 (bug fix)[1914604] Tcl Modules: encoding fixed to utf-8; environment
+variables without "." added to customization hooks (kupries)
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2008-03-18 (bug fix)[1914503] alignment of TclStackAlloc() return (sofer)\
+
+2008-03-20 (bug fix)[1868171] expose Tcl_GetMemoryInfo (for AOLserver) (fellows)
+
2008-03-24 (bug fix)[1923966] crash in [binary format x0s] (thoyts)
2008-03-27 (platform support)[1921166] Solaris 64bit build fixes (steffen)
-2008-04-04 (bug fix)[780533] [fcopy -size -command] callback failure (ferrieux)
+2008-03-27 clock tzdata updated to Olson's tzdata2008b (kenny)
+
+--- Released 8.5.2, March 28, 2008 --- See ChangeLog for details ---
+
+2008-03-30 (bug fix)[1783544] more robust TclIsNaN() (kenny,teterin)
+
+2008-04-01 (bug fix)[1839067] FP round fix for Solaris/x86 (kupries,schlenker)
+
+2008-04-02 (bug fix)[780533,1932639] [fcopy] callbacks unreliable (ferrieux)
+
+2008-04-04 (bug fix) [chan postevent] crash (kupries)
+
+2008-04-07 (bug fix) Fix broken [format {% d}] (max)
+
+2008-04-07 (bug fix)[1350564] Bi-directional [fcopy] now supported (ferrieux)
+
+2008-05-07 (bug fix) [dict append] crash (mccormack,fellows)
+
+2008-05-21 (bug fix)[1968882] [info complete "\\\n"] => 0 (porter)
+
+2008-05-22 (bug fix)[1968245] Tcl_LogCommandInfo() accept length=-1 (darroch)
+
+2008-05-23 (bug fix)[1965787] 32-bit overflow in [tell] result (ferrieux)
+
+2008-06-12 (platform support) Solaris static build with DTrace (steffen)
+
+2008-06-12 (platform support) Solaris/amd64 gcc 64bit support (steffen)
+
+2008-06-20 (bug fix)[1999035] make [interp bgerror $i] act in $i (porter)
+
+2008-06-23 (bug fix)[1972879] bad path intrep caching (porter)
+
+2008-06-24 (bug fix)[1999176] crash in [glob -dir {} a] (porter)
+
+2008-06-25 (bug fix)[1999119] Support TM packages in Safe Base (kupries)
+
+--- Released 8.5.3, June 30, 2008 --- See ChangeLog for details ---
+
+2008-07-03 (bug fix)[1969717] fix package finding on Samba shares (jos)
+
+2008-07-03 (bug fix)[1987821] mem leak in [seek] on reflected chan (kupries)
+
+2008-07-20 (enhancement)[2008248] dict->list preserve item intreps (pasadyn)
+
+2008-07-21 (bug fix)[2015723] [file] bad use of inodes on Windows (thoyts)
+
+2008-07-21 (enhancement) [info frame] returns file data in more cases (kupries)
+
+2008-07-29 (bug fix)[2030670] fix rare panic in TclStackFree (pasadyn,sofer)
+
+2008-08-08 tzdata updated to Olson's tzdata2008e (kenny)
+
+2008-08-11 (bug fix)[2046846] 64bit support for http zlib crc (thoyts)
+=> http 2.7.1
+
+2008-08-11 (enhancement) automatic [package provide] for TMs (kupries)
+
+--- Released 8.5.4, August 15, 2008 --- See ChangeLog for details ---
+
+2008-08-14 (bug fix)[2055782] fix crash in [namespace inscope] (sofer)
+
+2008-08-21 (bug fix)[2065115] correct handling of ***= RE's (hobbs,porter)
+
+2008-09-10 (enhancement) efficient list->dict conversion (elby,fellows)
+
+2008-09-17 (bug fix)[2116053] export [min] and [max] from tcl::mathfunc (sofer)
+
+2008-09-27 (bug fix)[2130992] prevent overflow crash in [lrepeat] (fellows)
+
+2008-10-05 (bug fix)[2143288] correct bad isqrt() results (boffey,kenny)
+
+2008-10-08 (bug fix)[2151707] fix stack trace from variable trace (porter)
+
+--- Released 8.5.5, October 15, 2008 --- See ChangeLog for details ---
+
+2008-10-24 (bug fix) fix failure to read SHOUTcast streams (thoyts)
+=> http 2.7.2
+
+2008-11-10 (bug fix)[2255235] [platform::shell::LOCATE] update (ring,kupries)
+=> platform::shell 1.1.4
+
+2008-11-13 (bug fix)[2269431] VFS [load] -> tempfile litter (ficicchia,nijtmans)
+
+2008-11-30 (bug fix)[2362156] [clock]: colon in format string (mizuno,kenny)
+
+2008-12-01 (bug fix)[2251175] [{*}{\{}] errors (hellström,ferrieux,porter)
+
+2008-12-02 (bug fix)[2270477] hang in channel finalization (ferrieux,kupries)
+
+2008-12-04 (bug fix)[2385549] [file normalize] failed on some paths (porter)
+
+2008-12-10 tzdata updated to Olson's tzdata2008i (kenny)
+
+2008-12-11 (bug fix)[2407783] spoil ChannelState when channel name passes
+among multiple interps (kupries)
+
+2008-12-21 (bug fix) Fix ability to join threads on 64-bit Windows (thoyts)
+
+2008-12-21 (bug fix)[2114900] updated tclIndex file (cassoff,kenny)
+
+--- Released 8.5.6, December 21, 2008 --- See ChangeLog for details ---
+
+2009-01-03 (bug fix)[2481670] [clock add] error message (talvo)
+
+2009-01-19 (new feature) CONFIG_INSTALL_DIR - where tclConfig.sh goes (cassoff)
+
+2009-01-19 (platform support) better tools for BSD ports (cassoff)
+
+2009-01-21 (bug fix)[2458202] exit crash with [chan create]d channel (kupries)
+
+2009-01-29 (bug fix)[2519474] Tcl_FindCommand() bug exposed by oo (fellows)
+
+2009-02-04 (bug fix)[2561746] [string repeat] overflow crash (porter)
+
+2009-02-17 (platform support) MSVC and _WIN64 (hobbs)
+
+2009-02-20 (bug fix)[2571597] [file pathtype /a] wrong result (nadkarni,porter)
+
+2009-03-15 (platform support) translate SIGINFO where defined (BSD) (teterin)
+
+2009-03-18 (bug fix)[2688184] memleak in [file normalize] (mistachkin)
+
+2009-03-20 (bug fix)[2597185] crash in Tcl_AppendStringToObj (porter)
+
+2009-03-27 (bug fix)[2710920] [file dirname|tail /foo/] errors (epler,porter)
+
+2009-03-30 (bug fix)[2603158] Tcl_AppendObjToObj: append to self crash (porter)
+
+2009-04-07 (bug fix)[2561794,2669109,2494093,2553906] string overflow (porter)
+
+2009-04-08 (bug fix)[2570363] unsafe [eval]s in tcltest (bron,porter)
+=> tcltest 2.3.1
+
+2009-04-08 (platform support) more Darwin kernel patterns (steffen)
+=> platform 1.0.4
+
+2009-04-09 (bug fix)[26245326] [http::geturl] connection failures (golovan)
+=> http 2.7.3
+
+2009-04-10 (new feature) Darwin: embeddable CoreFoundation notifier (steffen)
+
+2009-04-10 (bug fix)[1961211] Darwin [load] back-compatibility (steffen)
+
+2009-04-14 tzdata updated to Olson's tzdata2009f (kenny)
+
+--- Released 8.5.7, April 15, 2009 --- See ChangeLog for details ---
+
+2009-04-27 (bug fix)[2446662] uniformly declare EOF on RST on sockets (ferrieux)
+
+2009-04-27 (bug fix)[1028264] delay WSACleanup() from under our feet (ferrieux)
+
+2009-05-07 (bug fix)[2785893] find command in deleted namespace (sofer)
+
+2009-05-29 (platform support) account for ia64_32 (kupries)
+=> platform 1.0.5
+
+2009-06-02 (bug fix)[2798543] incorrect [expr] integer ** results (porter)
+
+2009-06-10 (bug fix)[2801413] overflow in [format] (porter)
+
+2009-06-13 (bug fix)[2802881] corrected compile env context (tasada,porter)
+
+2009-07-01 (bug fix)[2806622] Win: bad tcl_platform(user) value (thoyts)
+
+2009-07-16 (bug fix)[2819200] underflow settings on MIPS systems (porter)
+
+2009-07-23 (bug fix)[2820349] plug event leak in notifier (mistachkin)
+
+2009-07-24 (bug fix)[2826248] crash in Tcl_GetChannelHandle (sonnenburg,kupries)
+
+2009-07-31 (bug fix)[2830354] overflow in [format] (misch,porter)
+
+2009-08-06 (bug fix)[2827000] reflected channels can signal EGAIN (kupries)
+
+2009-08-20 (bug fix)[2806250] EIAS violation in ~foo pathnames (porter)
+
+2009-08-21 (bug fix)[2837800] [glob */foo] return ./~x/foo (porter)
+
+2009-08-24 (bug fix) nested event loop notifier w/TkAqua Cocoa (alaoui,steffen)
+
+2009-08-25 (bug fix) [info frame] account for continuation lines (kupries)
+
+2009-08-27 (bug fix)[2845535] overflows in [format] (porter)
+
+2009-09-01 (bug fix) improved error message in tcltest (porter)
+=> tcltest 2.3.2
+
+2009-09-11 (bug fix)[2849860] http handle "quoted" charset value (fellows)
+=> http 2.7.4
+
+2009-10-04 (bug fix)[2569449] Core Foundation memory bug in Tiger (steffen)
+
+2009-10-06 (bug fix)[1941434] broken tclTomMath.h includes (porter)
+
+2009-10-07 (bug fix)[2871908] leaked hash table (mistachkin,kupries)
+
+2009-10-08 (bug fix)[2874678] bignum leak in [dict incr] (fellows)
+
+2009-10-17 (bug fix)[2629338] crash in var unset traces (raney,fellows)
+
+2009-10-19 (bug fix)[2107634] extend [read] and [gets] to Tcl string limits
+(morrison,parker,porter)
+
+2009-10-21 (bug fix)[2882561] Haiku OS signal support (morrison,fellows)
+
+2009-10-24 Broken DST applied EU rules to US zones (lehenbauer,kenny)
+
+2009-10-29 (bug fix)[2800740] halved bignum memory on 64-bit systems (porter)
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2009-11-03 tzdata updated to Olson's tzdata2009q (kenny)
+
+2009-11-03 (bug fix)[2854929] TM search path support in Safe Base (kupries)
+
+2009-11-11 (bug fix)[2888099] [close] loses ENOSPC error (khomoutov,ferrieux)
+
+2009-11-11 (bug fix)[2891171] RFC 3986 compliance for ? in URL (nijtmans)
+=> http 2.7.5
+
+2009-11-12 (bug fix)[2895565] [fcopy -size] miscounts when converting encodings
+(kupries)
+
+--- Released 8.5.8, November 16, 2009 --- See ChangeLog for details ---
+
+2009-11-16 (bug fix)[2891556] encoding finalization crash (mistachkin,ferrieux)
+
+2009-12-09 (enhancement) rewrite of the Safe Base commands (kupries)
+
+2009-12-16 (bug fix)[2913616] msgcat: improved safe interp support (fellows)
+=> msgcat 1.4.3
+
+2009-12-23 (bug fix)[2913625] [info script/nameof] in safe interps (fellows)
+
+2009-12-28 (bug fix)[2891362] enable time limit in child interps (fellows)
+
+2009-12-28 (bug fix)[2895741] enable min(), max() in safe interps (fellows)
+
+2010-01-05 (bug fix)[2918610] [file rootname] corruption (magerya,porter)
+
+2010-01-06 (enhancement) Haiku, CYGWIN support improvements (nijtmans)
+
+2010-01-18 (bug fix)[2932421] less [format %s] shimmer (ferrieux)
+
+2010-01-18 (bug fix)[2918110] [chan postevent] crash (bron,kupries)
+
+2010-02-01 (bug fix)[2942697] faster match: some pathological regexp patterns
+(lane,fellows)
+
+2010-02-02 (bug fix)[2939073] [array unset] unset trace crash (ferrieux)
+
+2010-02-02 (bug fix)[2933089] [info frame] shared lit trouble (kupries)
+
+2010-02-11 (bug fix)[2949740] [open |noSuch rb] crash (kovalenko,fellows)
+
+2010-02-11 (bug fix)[2954959] get sign of abs($zero) right (nijtmans)
+
+2010-03-09 (bug fix)[2936225] stop [chan copy] to slow channel consuming all
+memory with buffer backup (ferrieux)
+
+2010-03-20 (enhancement) permit [fcopy] of > 2**31 bytes (fellows)
+
+2010-03-24 (bug fix)[2383005] [return -errorcode] reject non-list (porter)
+
+2010-03-25 (bug fix)[2976504] broken fstatfs() call (reeuwijk,fellows)
+
+2010-03-30 (bug fix)[2978773] refchan mem preservation (kupries)
+
+2010-05-19 (bug fix)[3004007] dict/list shimmer w/o string rep loss (fellows)
+
+2010-06-09 (bug fixes) platform: several fixes for 64 bit systems (kupries)
+=> platform 1.0.9
+
+2010-06-16 (bug fix)[3016135] [clock format] in he_IL locale (nijtmans)
+
+2010-06-28 (bug fix)[3019634] support errno.h changes in MSVC++ 2010 (nijtmans)
+
+2010-07-02 (enhancement) -errorcode for [expr] domain errors (fellows)
+
+2010-07-28 (bug fix)[3037525] crash deleting vars @ callframe pop (sofer)
+
+2010-08-04 (bug fix)[3034840] mem corrupt when refchan loses interp (kupries)
+
+2010-08-04 (enhancement) Win [load] use LOAD_WITH_ALTERED_SEARCH_PATH (hobbs)
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2010-08-12 (bug fix)[2826551] line-sensitive matching in regexp (dejong)
+
+2010-08-19 (bug fix)[3048354] buffer overflow detect in Fortify build (fellows)
+
+2010-08-23 tzdata updated to Olson's tzdata2010l (kenny)
+
+2010-09-01 (bug fix)[3057639] no read traces [lappend arr(elem) ...] (hobbs)
+ *** POTENTIAL INCOMPATIBILITY ***
+
+--- Released 8.5.9, September 8, 2010 --- See ChangeLog for details ---
+
+2010-09-24 (bug fix)[3056775] race condition in Win sockets (twylite,kupries)
+
+2010-10-23 (update)[3085863] Update Unicode data to 6.0 (nijtmans)
+
+2010-11-02 Safe Tcl handling of empty path lists (cassoff)
+
+2010-11-03 (bug fix)[3098302] crash in compiled [catch] (kenny)
+
+2010-11-15 (TIP 378)[3081184] improved TIP 280 performance (kupries)
+
+2010-11-30 (enhancement) Restore TclFormatInt for performance (hobbs)
+
+2010-11-30 (enhancement) Tcl_PrintDouble performance improvements (kenny)
+
+2010-12-12 (platform) OpenBSD build improvements (cassoff)
+
+2010-12-17 (platform) Revisions to support rpm 4.4.2 (cassoff)
+
+2011-01-13 (bug fix)[3142026] GrowEvaluationStack OBOE (harder,sofer)
+
+2011-01-19 (bug fix)[3072640] protect writes to ::error* variables (sofer)
+
+2011-03-06 (bug fix)[3200987,3192636] parser buffer overruns (porter)
+
+2011-03-08 (bug fix)[3202905] failed intrep release of interp result (mccormack)
+
+2011-03-09 (bug fix)[3202171] repair [namespace inscope] optimizer (porter)
+
+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-04-12 (bug fix)[3285472] intrep corruption in [string reverse] (porter)
+
+2011-04-13 (bug fix)[2662380] crash when variable append trace unsets (sofer)
+
+2011-04-13 (bug fix)[3285375] Buffer overflow in [concat] (porter)
+
+2011-05-02 (internals change) revised TclFindElement() interface (porter)
+ *** POTENTIAL INCOMPATIBILITY ***
+
+2011-05-05 (enhancement) dict->list w/o string rep generation (porter)
+
+2011-05-10 (bug fix)[3173086] Crash parsing long lists (rogers,porter)
+
+2011-05-12 (bug fix)[2715421] surplus \n in POST (passadyn,thoyts)
+=> http 2.7.6
+
+2011-05-24 tzdata updated to Olson's tzdata2011g (iyer)
+
+2011-05-25 (enhancement) msgcat internal improvements (fellows)
+=> msgcat 1.4.4
+
+2011-06-02 (bug fix)[3185407] cmd resolution epoch flaw (nadkarni,fellows)
+
+2011-06-13 (bug fix)[3315098] mem leak generating double string rep (neumann)
+
+2011-06-21 (new cmd) [tcltest::loadIntoSlaveInterpreter] (fellows)
+=> tcltest 2.3.3
+
+2011-06-22 (new feature) DEB_HOST_MULTIARCH support (kupries)
+=> platform 1.0.10
+
+--- Released 8.5.10, June 23, 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-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.7.7
+
+2011-09-16 (bug fix)[3400658] wrong num args msg with TclOO (rsooltan,fellows)
-2008-04-07 (new feature)[1350564] eased fileevent constraints during [fcopy]
-(ferrieux)
+2011-10-11 (bug fix)[2935503] [file stat] returns bad mode (nadkarni,nijtmans)
-2008-04-10 (bug fix)[1557855] crash on some [fcopy -size] values (ferrieux)
+2011-10-15 tzdata updated to Olson's tzdata2011l (iyer)
---- Released 8.4.19, April 18, 2008 --- See ChangeLog for details ---
+--- Released 8.5.11, November 4, 2011 --- See ChangeLog for details ---
diff --git a/compat/fixstrtod.c b/compat/fixstrtod.c
index ba1a480..91f309e 100644
--- a/compat/fixstrtod.c
+++ b/compat/fixstrtod.c
@@ -20,12 +20,12 @@
* somes systems (e.g. SunOS 4.1.4) stdlib.h doesn't declare strtod.
*/
-extern double strtod();
+extern double strtod(char *, char **);
double
-fixstrtod(string, endPtr)
- char *string;
- char **endPtr;
+fixstrtod(
+ char *string,
+ char **endPtr)
{
double d;
d = strtod(string, endPtr);
diff --git a/compat/gettod.c b/compat/gettod.c
index 059c36a..28e1432 100644
--- a/compat/gettod.c
+++ b/compat/gettod.c
@@ -10,18 +10,18 @@
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include "tcl.h"
#include "tclPort.h"
#include <sys/timeb.h>
#undef timezone
int
-gettimeofday(tp, tz)
-struct timeval *tp;
-struct timezone *tz;
+gettimeofday(
+ struct timeval *tp,
+ struct timezone *tz)
{
struct timeb t;
+
ftime(&t);
tp->tv_sec = t.time;
tp->tv_usec = t. millitm * 1000;
diff --git a/compat/memcmp.c b/compat/memcmp.c
index 3a4974b..5fce528 100644
--- a/compat/memcmp.c
+++ b/compat/memcmp.c
@@ -1,24 +1,21 @@
-/*
+/*
* memcmp.c --
*
* Source code for the "memcmp" library routine.
*
* Copyright (c) 1998 Sun Microsystems, Inc.
*
- * 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.
*/
-#include "tcl.h"
#include "tclPort.h"
/*
- * Here is the prototype just in case it is not included
- * in tclPort.h.
+ * Here is the prototype just in case it is not included in tclPort.h.
*/
-int memcmp _ANSI_ARGS_((CONST VOID *s1,
- CONST VOID *s2, size_t n));
+int memcmp(CONST VOID *s1, CONST VOID *s2, size_t n);
/*
*----------------------------------------------------------------------
@@ -28,11 +25,10 @@ int memcmp _ANSI_ARGS_((CONST VOID *s1,
* Compares two bytes sequences.
*
* Results:
- * compares its arguments, looking at the first n
- * bytes (each interpreted as an unsigned char), and returns
- * an integer less than, equal to, or greater than 0, accord-
- * ing as s1 is less than, equal to, or
- * greater than s2 when taken to be unsigned 8 bit numbers.
+ * Compares its arguments, looking at the first n bytes (each interpreted
+ * as an unsigned char), and returns an integer less than, equal to, or
+ * greater than 0, according as s1 is less than, equal to, or greater
+ * than s2 when taken to be unsigned 8 bit numbers.
*
* Side effects:
* None.
@@ -41,10 +37,10 @@ int memcmp _ANSI_ARGS_((CONST VOID *s1,
*/
int
-memcmp(s1, s2, n)
- CONST VOID *s1; /* First string. */
- CONST VOID *s2; /* Second string. */
- size_t n; /* Length to compare. */
+memcmp(
+ CONST VOID *s1, /* First string. */
+ CONST VOID *s2, /* Second string. */
+ size_t n) /* Length to compare. */
{
CONST unsigned char *ptr1 = (CONST unsigned char *) s1;
CONST unsigned char *ptr2 = (CONST unsigned char *) s2;
@@ -52,9 +48,17 @@ memcmp(s1, s2, n)
for ( ; n-- ; ptr1++, ptr2++) {
unsigned char u1 = *ptr1, u2 = *ptr2;
- if ( u1 != u2) {
+ if (u1 != u2) {
return (u1-u2);
}
}
return 0;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/compat/opendir.c b/compat/opendir.c
index 25e8392..3fe70c1 100644
--- a/compat/opendir.c
+++ b/compat/opendir.c
@@ -1,14 +1,12 @@
/*
* opendir.c --
*
- * This file provides dirent-style directory-reading procedures
- * for V7 Unix systems that don't have such procedures. The
- * origin of this code is unclear, but it seems to have come
- * originally from Larry Wall.
+ * This file provides dirent-style directory-reading procedures for V7
+ * Unix systems that don't have such procedures. The origin of this code
+ * is unclear, but it seems to have come originally from Larry Wall.
*/
#include "tclInt.h"
-#include "tclPort.h"
#undef DIRSIZ
#define DIRSIZ(dp) \
@@ -17,24 +15,28 @@
/*
* open a directory.
*/
+
DIR *
-opendir(name)
-char *name;
+opendir(
+ char *name)
{
- register DIR *dirp;
- register int fd;
- char *myname;
+ register DIR *dirp;
+ register int fd;
+ char *myname;
- myname = ((*name == '\0') ? "." : name);
- if ((fd = open(myname, 0, 0)) == -1)
- return NULL;
- if ((dirp = (DIR *)ckalloc(sizeof(DIR))) == NULL) {
- close (fd);
- return NULL;
- }
- dirp->dd_fd = fd;
- dirp->dd_loc = 0;
- return dirp;
+ myname = ((*name == '\0') ? "." : name);
+ if ((fd = open(myname, 0, 0)) == -1) {
+ return NULL;
+ }
+ dirp = (DIR *) ckalloc(sizeof(DIR));
+ if (dirp == NULL) {
+ /* unreachable? */
+ close(fd);
+ return NULL;
+ }
+ dirp->dd_fd = fd;
+ dirp->dd_loc = 0;
+ return dirp;
}
/*
@@ -44,62 +46,65 @@ char *name;
#define ODIRSIZ 14
struct olddirect {
- ino_t od_ino;
- char od_name[ODIRSIZ];
+ ino_t od_ino;
+ char od_name[ODIRSIZ];
};
#else /* a Pyramid in the ATT universe */
#define ODIRSIZ 248
struct olddirect {
- long od_ino;
- short od_fill1, od_fill2;
- char od_name[ODIRSIZ];
+ long od_ino;
+ short od_fill1, od_fill2;
+ char od_name[ODIRSIZ];
};
#endif
/*
* get next entry in a directory.
*/
+
struct dirent *
-readdir(dirp)
-register DIR *dirp;
+readdir(
+ register DIR *dirp)
{
- register struct olddirect *dp;
- static struct dirent dir;
+ register struct olddirect *dp;
+ static struct dirent dir;
- for (;;) {
- if (dirp->dd_loc == 0) {
- dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf,
- DIRBLKSIZ);
- if (dirp->dd_size <= 0)
- return NULL;
- }
- if (dirp->dd_loc >= dirp->dd_size) {
- dirp->dd_loc = 0;
- continue;
- }
- dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc);
- dirp->dd_loc += sizeof(struct olddirect);
- if (dp->od_ino == 0)
- continue;
- dir.d_ino = dp->od_ino;
- strncpy(dir.d_name, dp->od_name, ODIRSIZ);
- dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */
- dir.d_namlen = strlen(dir.d_name);
- dir.d_reclen = DIRSIZ(&dir);
- return (&dir);
+ for (;;) {
+ if (dirp->dd_loc == 0) {
+ dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ);
+ if (dirp->dd_size <= 0) {
+ return NULL;
+ }
+ }
+ if (dirp->dd_loc >= dirp->dd_size) {
+ dirp->dd_loc = 0;
+ continue;
}
+ dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc);
+ dirp->dd_loc += sizeof(struct olddirect);
+ if (dp->od_ino == 0) {
+ continue;
+ }
+ dir.d_ino = dp->od_ino;
+ strncpy(dir.d_name, dp->od_name, ODIRSIZ);
+ dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */
+ dir.d_namlen = strlen(dir.d_name);
+ dir.d_reclen = DIRSIZ(&dir);
+ return &dir;
+ }
}
/*
* close a directory.
*/
+
void
-closedir(dirp)
-register DIR *dirp;
+closedir(
+ register DIR *dirp)
{
- close(dirp->dd_fd);
- dirp->dd_fd = -1;
- dirp->dd_loc = 0;
- ckfree((char *) dirp);
+ close(dirp->dd_fd);
+ dirp->dd_fd = -1;
+ dirp->dd_loc = 0;
+ ckfree((char *) dirp);
}
diff --git a/compat/strftime.c b/compat/strftime.c
deleted file mode 100644
index 68016ac..0000000
--- a/compat/strftime.c
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * strftime.c --
- *
- * This file contains a modified version of the BSD 4.4 strftime
- * function.
- *
- * This file is a modified version of the strftime.c file from the BSD 4.4
- * source. See the copyright notice below for details on redistribution
- * restrictions. The "license.terms" file does not apply to this file.
- *
- * Changes 2002 Copyright (c) 2002 ActiveState Corporation.
- */
-
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <time.h>
-#include <string.h>
-#include <locale.h>
-#include "tclInt.h"
-#include "tclPort.h"
-
-#define TM_YEAR_BASE 1900
-#define IsLeapYear(x) ((x % 4 == 0) && (x % 100 != 0 || x % 400 == 0))
-
-typedef struct {
- const char *abday[7];
- const char *day[7];
- const char *abmon[12];
- const char *mon[12];
- const char *am_pm[2];
- const char *d_t_fmt;
- const char *d_fmt;
- const char *t_fmt;
- const char *t_fmt_ampm;
-} _TimeLocale;
-
-/*
- * This is the C locale default. On Windows, if we wanted to make this
- * localized, we would use GetLocaleInfo to get the correct values.
- * It may be acceptable to do localization of month/day names, as the
- * numerical values would be considered the locale-independent versions.
- */
-static const _TimeLocale _DefaultTimeLocale =
-{
- {
- "Sun","Mon","Tue","Wed","Thu","Fri","Sat",
- },
- {
- "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
- "Friday", "Saturday"
- },
- {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
- },
- {
- "January", "February", "March", "April", "May", "June", "July",
- "August", "September", "October", "November", "December"
- },
- {
- "AM", "PM"
- },
- "%a %b %d %H:%M:%S %Y",
- "%m/%d/%y",
- "%H:%M:%S",
- "%I:%M:%S %p"
-};
-
-static const _TimeLocale *_CurrentTimeLocale = &_DefaultTimeLocale;
-
-static int isGMT;
-static size_t gsize;
-static char *pt;
-static int _add _ANSI_ARGS_((const char* str));
-static int _conv _ANSI_ARGS_((int n, int digits, int pad));
-static int _secs _ANSI_ARGS_((const struct tm *t));
-static size_t _fmt _ANSI_ARGS_((const char *format,
- const struct tm *t));
-static int ISO8601Week _ANSI_ARGS_((CONST struct tm* t, int *year ));
-
-size_t
-TclpStrftime(s, maxsize, format, t, useGMT)
- char *s;
- size_t maxsize;
- const char *format;
- const struct tm *t;
- int useGMT;
-{
- if (format[0] == '%' && format[1] == 'Q') {
- /* Format as a stardate */
- sprintf(s, "Stardate %2d%03d.%01d",
- (((t->tm_year + TM_YEAR_BASE) + 377) - 2323),
- (((t->tm_yday + 1) * 1000) /
- (365 + IsLeapYear((t->tm_year + TM_YEAR_BASE)))),
- (((t->tm_hour * 60) + t->tm_min)/144));
- return(strlen(s));
- }
-
- isGMT = useGMT;
- /*
- * We may be able to skip this for useGMT, but it should be harmless.
- * -- hobbs
- */
- tzset();
-
- pt = s;
- if ((gsize = maxsize) < 1)
- return(0);
- if (_fmt(format, t)) {
- *pt = '\0';
- return(maxsize - gsize);
- }
- return(0);
-}
-
-#define SUN_WEEK(t) (((t)->tm_yday + 7 - \
- ((t)->tm_wday)) / 7)
-#define MON_WEEK(t) (((t)->tm_yday + 7 - \
- ((t)->tm_wday ? (t)->tm_wday - 1 : 6)) / 7)
-
-static size_t
-_fmt(format, t)
- const char *format;
- const struct tm *t;
-{
-#ifdef WIN32
-#define BUF_SIZ 256
- TCHAR buf[BUF_SIZ];
- SYSTEMTIME syst = {
- t->tm_year + 1900,
- t->tm_mon + 1,
- t->tm_wday,
- t->tm_mday,
- t->tm_hour,
- t->tm_min,
- t->tm_sec,
- 0,
- };
-#endif
- for (; *format; ++format) {
- if (*format == '%') {
- ++format;
- if (*format == 'E') {
- /* Alternate Era */
- ++format;
- } else if (*format == 'O') {
- /* Alternate numeric symbols */
- ++format;
- }
- switch(*format) {
- case '\0':
- --format;
- break;
- case 'A':
- if (t->tm_wday < 0 || t->tm_wday > 6)
- return(0);
- if (!_add(_CurrentTimeLocale->day[t->tm_wday]))
- return(0);
- continue;
- case 'a':
- if (t->tm_wday < 0 || t->tm_wday > 6)
- return(0);
- if (!_add(_CurrentTimeLocale->abday[t->tm_wday]))
- return(0);
- continue;
- case 'B':
- if (t->tm_mon < 0 || t->tm_mon > 11)
- return(0);
- if (!_add(_CurrentTimeLocale->mon[t->tm_mon]))
- return(0);
- continue;
- case 'b':
- case 'h':
- if (t->tm_mon < 0 || t->tm_mon > 11)
- return(0);
- if (!_add(_CurrentTimeLocale->abmon[t->tm_mon]))
- return(0);
- continue;
- case 'C':
- if (!_conv((t->tm_year + TM_YEAR_BASE) / 100,
- 2, '0'))
- return(0);
- continue;
- case 'D':
- if (!_fmt("%m/%d/%y", t))
- return(0);
- continue;
- case 'd':
- if (!_conv(t->tm_mday, 2, '0'))
- return(0);
- continue;
- case 'e':
- if (!_conv(t->tm_mday, 2, ' '))
- return(0);
- continue;
- case 'g':
- {
- int year;
- ISO8601Week( t, &year );
- if ( !_conv( year%100, 2, '0' ) ) {
- return( 0 );
- }
- continue;
- }
- case 'G':
- {
- int year;
- ISO8601Week( t, &year );
- if ( !_conv( year, 4, '0' ) ) {
- return( 0 );
- }
- continue;
- }
- case 'H':
- if (!_conv(t->tm_hour, 2, '0'))
- return(0);
- continue;
- case 'I':
- if (!_conv(t->tm_hour % 12 ?
- t->tm_hour % 12 : 12, 2, '0'))
- return(0);
- continue;
- case 'j':
- if (!_conv(t->tm_yday + 1, 3, '0'))
- return(0);
- continue;
- case 'k':
- if (!_conv(t->tm_hour, 2, ' '))
- return(0);
- continue;
- case 'l':
- if (!_conv(t->tm_hour % 12 ?
- t->tm_hour % 12: 12, 2, ' '))
- return(0);
- continue;
- case 'M':
- if (!_conv(t->tm_min, 2, '0'))
- return(0);
- continue;
- case 'm':
- if (!_conv(t->tm_mon + 1, 2, '0'))
- return(0);
- continue;
- case 'n':
- if (!_add("\n"))
- return(0);
- continue;
- case 'p':
- if (!_add(_CurrentTimeLocale->am_pm[t->tm_hour >= 12]))
- return(0);
- continue;
- case 'R':
- if (!_fmt("%H:%M", t))
- return(0);
- continue;
- case 'r':
- if (!_fmt(_CurrentTimeLocale->t_fmt_ampm, t))
- return(0);
- continue;
- case 'S':
- if (!_conv(t->tm_sec, 2, '0'))
- return(0);
- continue;
- case 's':
- if (!_secs(t))
- return(0);
- continue;
- case 'T':
- if (!_fmt("%H:%M:%S", t))
- return(0);
- continue;
- case 't':
- if (!_add("\t"))
- return(0);
- continue;
- case 'U':
- if (!_conv(SUN_WEEK(t), 2, '0'))
- return(0);
- continue;
- case 'u':
- if (!_conv(t->tm_wday ? t->tm_wday : 7, 1, '0'))
- return(0);
- continue;
- case 'V':
- {
- int week = ISO8601Week( t, NULL );
- if (!_conv(week, 2, '0'))
- return(0);
- continue;
- }
- case 'W':
- if (!_conv(MON_WEEK(t), 2, '0'))
- return(0);
- continue;
- case 'w':
- if (!_conv(t->tm_wday, 1, '0'))
- return(0);
- continue;
-#ifdef WIN32
- /*
- * To properly handle the localized time routines on Windows,
- * we must make use of the special localized calls.
- */
- case 'c':
- if (!GetDateFormat(LOCALE_USER_DEFAULT,
- DATE_LONGDATE | LOCALE_USE_CP_ACP,
- &syst, NULL, buf, BUF_SIZ)
- || !_add(buf)
- || !_add(" ")) {
- return(0);
- }
- /*
- * %c is created with LONGDATE + " " + TIME on Windows,
- * so continue to %X case here.
- */
- case 'X':
- if (!GetTimeFormat(LOCALE_USER_DEFAULT,
- LOCALE_USE_CP_ACP,
- &syst, NULL, buf, BUF_SIZ)
- || !_add(buf)) {
- return(0);
- }
- continue;
- case 'x':
- if (!GetDateFormat(LOCALE_USER_DEFAULT,
- DATE_SHORTDATE | LOCALE_USE_CP_ACP,
- &syst, NULL, buf, BUF_SIZ)
- || !_add(buf)) {
- return(0);
- }
- continue;
-#else
- case 'c':
- if (!_fmt(_CurrentTimeLocale->d_t_fmt, t))
- return(0);
- continue;
- case 'x':
- if (!_fmt(_CurrentTimeLocale->d_fmt, t))
- return(0);
- continue;
- case 'X':
- if (!_fmt(_CurrentTimeLocale->t_fmt, t))
- return(0);
- continue;
-#endif
- case 'y':
- if (!_conv((t->tm_year + TM_YEAR_BASE) % 100,
- 2, '0'))
- return(0);
- continue;
- case 'Y':
- if (!_conv((t->tm_year + TM_YEAR_BASE), 4, '0'))
- return(0);
- continue;
- case 'Z': {
- char *name = (isGMT ? "GMT" : TclpGetTZName(t->tm_isdst));
- int wrote;
- Tcl_UtfToExternal(NULL, NULL, name, -1, 0, NULL,
- pt, gsize, NULL, &wrote, NULL);
- pt += wrote;
- gsize -= wrote;
- continue;
- }
- case '%':
- /*
- * X311J/88-090 (4.12.3.5): if conversion char is
- * undefined, behavior is undefined. Print out the
- * character itself as printf(3) does.
- */
- default:
- break;
- }
- }
- if (!gsize--)
- return(0);
- *pt++ = *format;
- }
- return(gsize);
-}
-
-static int
-_secs(t)
- const struct tm *t;
-{
- static char buf[15];
- register time_t s;
- register char *p;
- struct tm tmp;
-
- /* Make a copy, mktime(3) modifies the tm struct. */
- tmp = *t;
- s = mktime(&tmp);
- for (p = buf + sizeof(buf) - 2; s > 0 && p > buf; s /= 10)
- *p-- = (char)(s % 10 + '0');
- return(_add(++p));
-}
-
-static int
-_conv(n, digits, pad)
- int n, digits;
- int pad;
-{
- static char buf[10];
- register char *p;
-
- p = buf + sizeof( buf ) - 1;
- *p-- = '\0';
- if ( n == 0 ) {
- *p-- = '0'; --digits;
- } else {
- for (; n > 0 && p > buf; n /= 10, --digits)
- *p-- = (char)(n % 10 + '0');
- }
- while (p > buf && digits-- > 0)
- *p-- = (char) pad;
- return(_add(++p));
-}
-
-static int
-_add(str)
- const char *str;
-{
- for (;; ++pt, --gsize) {
- if (!gsize)
- return(0);
- if (!(*pt = *str++))
- return(1);
- }
-}
-
-static int
-ISO8601Week( t, year )
- CONST struct tm* t;
- int* year;
-{
- /* Find the day-of-year of the Thursday in
- * the week in question. */
-
- int ydayThursday;
- int week;
- if ( t->tm_wday == 0 ) {
- ydayThursday = t->tm_yday - 3;
- } else {
- ydayThursday = t->tm_yday - t->tm_wday + 4;
- }
-
- if ( ydayThursday < 0 ) {
-
- /* This is the last week of the previous year. */
- if ( IsLeapYear(( t->tm_year + TM_YEAR_BASE - 1 )) ) {
- ydayThursday += 366;
- } else {
- ydayThursday += 365;
- }
- week = ydayThursday / 7 + 1;
- if ( year != NULL ) {
- *year = t->tm_year + 1899;
- }
-
- } else if ( ( IsLeapYear(( t -> tm_year + TM_YEAR_BASE ))
- && ydayThursday >= 366 )
- || ( !IsLeapYear(( t -> tm_year
- + TM_YEAR_BASE ))
- && ydayThursday >= 365 ) ) {
-
- /* This is week 1 of the following year */
-
- week = 1;
- if ( year != NULL ) {
- *year = t->tm_year + 1901;
- }
-
- } else {
-
- week = ydayThursday / 7 + 1;
- if ( year != NULL ) {
- *year = t->tm_year + 1900;
- }
-
- }
-
- return week;
-
-}
diff --git a/compat/string.h b/compat/string.h
index fbf9cf8..4eb2b86 100644
--- a/compat/string.h
+++ b/compat/string.h
@@ -22,9 +22,7 @@
* it exists everywhere)
*/
-#ifndef MAC_TCL
#include <sys/types.h>
-#endif
#ifdef __APPLE__
extern VOID * memchr _ANSI_ARGS_((CONST VOID *s, int c, size_t n));
diff --git a/compat/strncasecmp.c b/compat/strncasecmp.c
index d00ea5b..76cf549 100644
--- a/compat/strncasecmp.c
+++ b/compat/strncasecmp.c
@@ -6,16 +6,16 @@
* Copyright (c) 1988-1993 The Regents of the University of California.
* Copyright (c) 1995-1996 Sun Microsystems, Inc.
*
- * 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.
*/
#include "tclPort.h"
/*
- * This array is designed for mapping upper and lower case letter
- * together for a case independent comparison. The mappings are
- * based upon ASCII character sequences.
+ * This array is designed for mapping upper and lower case letter together for
+ * a case independent comparison. The mappings are based upon ASCII character
+ * sequences.
*/
static unsigned char charmap[] = {
@@ -54,14 +54,11 @@ static unsigned char charmap[] = {
};
/*
- * Here are the prototypes just in case they are not included
- * in tclPort.h.
+ * Here are the prototypes just in case they are not included in tclPort.h.
*/
-int strncasecmp _ANSI_ARGS_((CONST char *s1,
- CONST char *s2, size_t n));
-int strcasecmp _ANSI_ARGS_((CONST char *s1,
- CONST char *s2));
+int strncasecmp(CONST char *s1, CONST char *s2, size_t n);
+int strcasecmp(CONST char *s1, CONST char *s2);
/*
*----------------------------------------------------------------------
@@ -71,9 +68,8 @@ int strcasecmp _ANSI_ARGS_((CONST char *s1,
* Compares two strings, ignoring case differences.
*
* Results:
- * Compares two null-terminated strings s1 and s2, returning -1, 0,
- * or 1 if s1 is lexicographically less than, equal to, or greater
- * than s2.
+ * Compares two null-terminated strings s1 and s2, returning -1, 0, or 1
+ * if s1 is lexicographically less than, equal to, or greater than s2.
*
* Side effects:
* None.
@@ -82,9 +78,9 @@ int strcasecmp _ANSI_ARGS_((CONST char *s1,
*/
int
-strcasecmp(s1, s2)
- CONST char *s1; /* First string. */
- CONST char *s2; /* Second string. */
+strcasecmp(
+ CONST char *s1, /* First string. */
+ CONST char *s2) /* Second string. */
{
unsigned char u1, u2;
@@ -106,9 +102,9 @@ strcasecmp(s1, s2)
* Compares two strings, ignoring case differences.
*
* Results:
- * Compares up to length chars of s1 and s2, returning -1, 0, or 1
- * if s1 is lexicographically less than, equal to, or greater
- * than s2 over those characters.
+ * Compares up to length chars of s1 and s2, returning -1, 0, or 1 if s1
+ * is lexicographically less than, equal to, or greater than s2 over
+ * those characters.
*
* Side effects:
* None.
@@ -117,10 +113,10 @@ strcasecmp(s1, s2)
*/
int
-strncasecmp(s1, s2, length)
- CONST char *s1; /* First string. */
- CONST char *s2; /* Second string. */
- size_t length; /* Maximum number of characters to compare
+strncasecmp(
+ CONST char *s1, /* First string. */
+ CONST char *s2, /* Second string. */
+ size_t length) /* Maximum number of characters to compare
* (stop earlier if the end of either string
* is reached). */
{
diff --git a/compat/strstr.c b/compat/strstr.c
index 98d567d..6698c9f 100644
--- a/compat/strstr.c
+++ b/compat/strstr.c
@@ -6,11 +6,11 @@
* Copyright (c) 1988-1993 The Regents of the University of California.
* Copyright (c) 1994 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
-#include <tcl.h>
+#include "tcl.h"
#ifndef NULL
#define NULL 0
#endif
@@ -23,12 +23,10 @@
* Locate the first instance of a substring in a string.
*
* Results:
- * If string contains substring, the return value is the
- * location of the first matching instance of substring
- * in string. If string doesn't contain substring, the
- * return value is 0. Matching is done on an exact
- * character-for-character basis with no wildcards or special
- * characters.
+ * If string contains substring, the return value is the location of the
+ * first matching instance of substring in string. If string doesn't
+ * contain substring, the return value is 0. Matching is done on an exact
+ * character-for-character basis with no wildcards or special characters.
*
* Side effects:
* None.
@@ -37,15 +35,16 @@
*/
char *
-strstr(string, substring)
- register char *string; /* String to search. */
- char *substring; /* Substring to try to find in string. */
+strstr(
+ register char *string, /* String to search. */
+ char *substring) /* Substring to try to find in string. */
{
register char *a, *b;
- /* First scan quickly through the two strings looking for a
- * single-character match. When it's found, then compare the
- * rest of the substring.
+ /*
+ * First scan quickly through the two strings looking for a
+ * single-character match. When it's found, then compare the rest of the
+ * substring.
*/
b = substring;
diff --git a/compat/strtod.c b/compat/strtod.c
index c5d4b96..1147825 100644
--- a/compat/strtod.c
+++ b/compat/strtod.c
@@ -11,7 +11,6 @@
*/
#include "tclInt.h"
-#include "tclPort.h"
#include <ctype.h>
#ifndef TRUE
@@ -61,20 +60,19 @@ static double powersOf10[] = { /* Table giving binary powers of 10. Entry */
*/
double
-strtod(string, endPtr)
- CONST char *string; /* A decimal ASCII floating-point number,
- * optionally preceded by white space.
- * Must have form "-I.FE-X", where I is the
- * integer part of the mantissa, F is the
- * fractional part of the mantissa, and X
- * is the exponent. Either of the signs
- * may be "+", "-", or omitted. Either I
- * or F may be omitted, or both. The decimal
- * point isn't necessary unless F is present.
- * The "E" may actually be an "e". E and X
- * may both be omitted (but not just one).
- */
- char **endPtr; /* If non-NULL, store terminating character's
+strtod(
+ CONST char *string, /* A decimal ASCII floating-point number,
+ * optionally preceded by white space. Must
+ * have form "-I.FE-X", where I is the integer
+ * part of the mantissa, F is the fractional
+ * part of the mantissa, and X is the
+ * exponent. Either of the signs may be "+",
+ * "-", or omitted. Either I or F may be
+ * omitted, or both. The decimal point isn't
+ * necessary unless F is present. The "E" may
+ * actually be an "e". E and X may both be
+ * omitted (but not just one). */
+ char **endPtr) /* If non-NULL, store terminating character's
* address here. */
{
int sign, expSign = FALSE;
@@ -83,19 +81,19 @@ strtod(string, endPtr)
register int c;
int exp = 0; /* Exponent read from "EX" field. */
int fracExp = 0; /* Exponent that derives from the fractional
- * part. Under normal circumstatnces, it is
+ * part. Under normal circumstatnces, it is
* the negative of the number of digits in F.
* However, if I is very long, the last digits
* of I get dropped (otherwise a long I with a
* large negative exponent could cause an
- * unnecessary overflow on I alone). In this
+ * unnecessary overflow on I alone). In this
* case, fracExp is incremented one for each
* dropped digit. */
int mantSize; /* Number of digits in mantissa. */
int decPt; /* Number of mantissa digits BEFORE decimal
* point. */
- CONST char *pExp; /* Temporarily holds location of exponent
- * in string. */
+ CONST char *pExp; /* Temporarily holds location of exponent in
+ * string. */
/*
* Strip off leading blanks and check for a sign.
@@ -134,10 +132,10 @@ strtod(string, endPtr)
}
/*
- * Now suck up the digits in the mantissa. Use two integers to
- * collect 9 digits each (this is faster than using floating-point).
- * If the mantissa has more than 18 digits, ignore the extras, since
- * they can't affect the value anyway.
+ * Now suck up the digits in the mantissa. Use two integers to collect 9
+ * digits each (this is faster than using floating-point). If the mantissa
+ * has more than 18 digits, ignore the extras, since they can't affect the
+ * value anyway.
*/
pExp = p;
@@ -145,7 +143,7 @@ strtod(string, endPtr)
if (decPt < 0) {
decPt = mantSize;
} else {
- mantSize -= 1; /* One of the digits was the point. */
+ mantSize -= 1; /* One of the digits was the point. */
}
if (mantSize > 18) {
fracExp = decPt - 18;
@@ -159,9 +157,9 @@ strtod(string, endPtr)
goto done;
} else {
int frac1, frac2;
+
frac1 = 0;
- for ( ; mantSize > 9; mantSize -= 1)
- {
+ for ( ; mantSize > 9; mantSize -= 1) {
c = *p;
p += 1;
if (c == '.') {
@@ -171,8 +169,7 @@ strtod(string, endPtr)
frac1 = 10*frac1 + (c - '0');
}
frac2 = 0;
- for (; mantSize > 0; mantSize -= 1)
- {
+ for (; mantSize > 0; mantSize -= 1) {
c = *p;
p += 1;
if (c == '.') {
@@ -216,10 +213,9 @@ strtod(string, endPtr)
}
/*
- * Generate a floating-point number that represents the exponent.
- * Do this by processing the exponent one bit at a time to combine
- * many powers of 2 of 10. Then combine the exponent with the
- * fraction.
+ * Generate a floating-point number that represents the exponent. Do this
+ * by processing the exponent one bit at a time to combine many powers of
+ * 2 of 10. Then combine the exponent with the fraction.
*/
if (exp < 0) {
@@ -244,7 +240,7 @@ strtod(string, endPtr)
fraction *= dblExp;
}
-done:
+ done:
if (endPtr != NULL) {
*endPtr = (char *) p;
}
diff --git a/compat/strtol.c b/compat/strtol.c
index bc21c4b..793f094 100644
--- a/compat/strtol.c
+++ b/compat/strtol.c
@@ -6,14 +6,12 @@
* Copyright (c) 1988 The Regents of the University of California.
* Copyright (c) 1994 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <ctype.h>
#include "tclInt.h"
-#include "tclPort.h"
-
/*
*----------------------------------------------------------------------
@@ -23,11 +21,10 @@
* Convert an ASCII string into an integer.
*
* Results:
- * The return value is the integer equivalent of string. If endPtr
- * is non-NULL, then *endPtr is filled in with the character
- * after the last one that was part of the integer. If string
- * doesn't contain a valid integer value, then zero is returned
- * and *endPtr is set to string.
+ * The return value is the integer equivalent of string. If endPtr is
+ * non-NULL, then *endPtr is filled in with the character after the last
+ * one that was part of the integer. If string doesn't contain a valid
+ * integer value, then zero is returned and *endPtr is set to string.
*
* Side effects:
* None.
@@ -36,20 +33,18 @@
*/
long int
-strtol(string, endPtr, base)
- CONST char *string; /* String of ASCII digits, possibly
- * preceded by white space. For bases
- * greater than 10, either lower- or
- * upper-case digits may be used.
- */
- char **endPtr; /* Where to store address of terminating
+strtol(
+ CONST char *string, /* String of ASCII digits, possibly preceded
+ * by white space. For bases greater than 10,
+ * either lower- or upper-case digits may be
+ * used. */
+ char **endPtr, /* Where to store address of terminating
* character, or NULL. */
- int base; /* Base for conversion. Must be less
- * than 37. If 0, then the base is chosen
- * from the leading characters of string:
- * "0x" means hex, "0" means octal, anything
- * else means decimal.
- */
+ int base) /* Base for conversion. Must be less than 37.
+ * If 0, then the base is chosen from the
+ * leading characters of string: "0x" means
+ * hex, "0" means octal, anything else means
+ * decimal. */
{
register CONST char *p;
long result;
diff --git a/compat/strtoll.c b/compat/strtoll.c
deleted file mode 100644
index a829d70..0000000
--- a/compat/strtoll.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * strtoll.c --
- *
- * Source code for the "strtoll" library procedure.
- *
- * Copyright (c) 1988 The Regents of the University of California.
- * Copyright (c) 1994 Sun Microsystems, Inc.
- *
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- */
-
-#include "tcl.h"
-#include "tclPort.h"
-#include <ctype.h>
-
-#define TCL_WIDEINT_MAX (((Tcl_WideUInt)Tcl_LongAsWide(-1))>>1)
-
-
-/*
- *----------------------------------------------------------------------
- *
- * strtoll --
- *
- * Convert an ASCII string into an integer.
- *
- * Results:
- * The return value is the integer equivalent of string. If endPtr
- * is non-NULL, then *endPtr is filled in with the character
- * after the last one that was part of the integer. If string
- * doesn't contain a valid integer value, then zero is returned
- * and *endPtr is set to string.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-#if TCL_WIDE_INT_IS_LONG
-long long
-#else
-Tcl_WideInt
-#endif
-strtoll(string, endPtr, base)
- CONST char *string; /* String of ASCII digits, possibly
- * preceded by white space. For bases
- * greater than 10, either lower- or
- * upper-case digits may be used.
- */
- char **endPtr; /* Where to store address of terminating
- * character, or NULL. */
- int base; /* Base for conversion. Must be less
- * than 37. If 0, then the base is chosen
- * from the leading characters of string:
- * "0x" means hex, "0" means octal, anything
- * else means decimal.
- */
-{
- register CONST char *p;
- Tcl_WideInt result = Tcl_LongAsWide(0);
- Tcl_WideUInt uwResult;
-
- /*
- * Skip any leading blanks.
- */
-
- p = string;
- while (isspace(UCHAR(*p))) {
- p += 1;
- }
-
- /*
- * Check for a sign.
- */
-
- errno = 0;
- if (*p == '-') {
- p += 1;
- uwResult = strtoull(p, endPtr, base);
- if (errno != ERANGE) {
- if (uwResult > TCL_WIDEINT_MAX+1) {
- errno = ERANGE;
- return Tcl_LongAsWide(-1);
- } else if (uwResult > TCL_WIDEINT_MAX) {
- return ~((Tcl_WideInt)TCL_WIDEINT_MAX);
- } else {
- result = -((Tcl_WideInt) uwResult);
- }
- }
- } else {
- if (*p == '+') {
- p += 1;
- }
- uwResult = strtoull(p, endPtr, base);
- if (errno != ERANGE) {
- if (uwResult > TCL_WIDEINT_MAX) {
- errno = ERANGE;
- return Tcl_LongAsWide(-1);
- } else {
- result = uwResult;
- }
- }
- }
- if ((result == 0) && (endPtr != 0) && (*endPtr == p)) {
- *endPtr = (char *) string;
- }
- return result;
-}
diff --git a/compat/strtoul.c b/compat/strtoul.c
index b9d2785..9d3f372 100644
--- a/compat/strtoul.c
+++ b/compat/strtoul.c
@@ -6,17 +6,16 @@
* Copyright (c) 1988 The Regents of the University of California.
* Copyright (c) 1994 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * 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 "tclPort.h"
/*
- * The table below is used to convert from ASCII digits to a
- * numerical equivalent. It maps from '0' through 'z' to integers
- * (100 for non-digit characters).
+ * The table below is used to convert from ASCII digits to a numerical
+ * equivalent. It maps from '0' through 'z' to integers (100 for non-digit
+ * characters).
*/
static char cvtIn[] = {
@@ -38,11 +37,10 @@ static char cvtIn[] = {
* Convert an ASCII string into an integer.
*
* Results:
- * The return value is the integer equivalent of string. If endPtr
- * is non-NULL, then *endPtr is filled in with the character
- * after the last one that was part of the integer. If string
- * doesn't contain a valid integer value, then zero is returned
- * and *endPtr is set to string.
+ * The return value is the integer equivalent of string. If endPtr is
+ * non-NULL, then *endPtr is filled in with the character after the last
+ * one that was part of the integer. If string doesn't contain a valid
+ * integer value, then zero is returned and *endPtr is set to string.
*
* Side effects:
* None.
@@ -51,20 +49,18 @@ static char cvtIn[] = {
*/
unsigned long int
-strtoul(string, endPtr, base)
- CONST char *string; /* String of ASCII digits, possibly
- * preceded by white space. For bases
- * greater than 10, either lower- or
- * upper-case digits may be used.
- */
- char **endPtr; /* Where to store address of terminating
+strtoul(
+ CONST char *string, /* String of ASCII digits, possibly preceded
+ * by white space. For bases greater than 10,
+ * either lower- or upper-case digits may be
+ * used. */
+ char **endPtr, /* Where to store address of terminating
* character, or NULL. */
- int base; /* Base for conversion. Must be less
- * than 37. If 0, then the base is chosen
- * from the leading characters of string:
- * "0x" means hex, "0" means octal, anything
- * else means decimal.
- */
+ int base) /* Base for conversion. Must be less than 37.
+ * If 0, then the base is chosen from the
+ * leading characters of string: "0x" means
+ * hex, "0" means octal, anything else means
+ * decimal. */
{
register CONST char *p;
register unsigned long int result = 0;
@@ -91,31 +87,29 @@ strtoul(string, endPtr, base)
}
/*
- * If no base was provided, pick one from the leading characters
- * of the string.
+ * If no base was provided, pick one from the leading characters of the
+ * string.
*/
- if (base == 0)
- {
+ if (base == 0) {
if (*p == '0') {
p += 1;
if ((*p == 'x') || (*p == 'X')) {
p += 1;
base = 16;
} else {
-
/*
- * Must set anyDigits here, otherwise "0" produces a
- * "no digits" error.
+ * Must set anyDigits here, otherwise "0" produces a "no
+ * digits" error.
*/
anyDigits = 1;
base = 8;
}
+ } else {
+ base = 10;
}
- else base = 10;
} else if (base == 16) {
-
/*
* Skip a leading "0x" from hex numbers.
*/
@@ -126,12 +120,13 @@ strtoul(string, endPtr, base)
}
/*
- * Sorry this code is so messy, but speed seems important. Do
- * different things for base 8, 10, 16, and other.
+ * Sorry this code is so messy, but speed seems important. Do different
+ * things for base 8, 10, 16, and other.
*/
if (base == 8) {
unsigned long maxres = ULONG_MAX >> 3;
+
for ( ; ; p += 1) {
digit = *p - '0';
if (digit > 7) {
@@ -145,6 +140,7 @@ strtoul(string, endPtr, base)
}
} else if (base == 10) {
unsigned long maxres = ULONG_MAX / 10;
+
for ( ; ; p += 1) {
digit = *p - '0';
if (digit > 9) {
@@ -158,6 +154,7 @@ strtoul(string, endPtr, base)
}
} else if (base == 16) {
unsigned long maxres = ULONG_MAX >> 4;
+
for ( ; ; p += 1) {
digit = *p - '0';
if (digit > ('z' - '0')) {
@@ -173,8 +170,9 @@ strtoul(string, endPtr, base)
result += digit;
anyDigits = 1;
}
- } else if ( base >= 2 && base <= 36 ) {
+ } else if (base >= 2 && base <= 36) {
unsigned long maxres = ULONG_MAX / base;
+
for ( ; ; p += 1) {
digit = *p - '0';
if (digit > ('z' - '0')) {
diff --git a/compat/strtoull.c b/compat/strtoull.c
deleted file mode 100644
index d0dd853..0000000
--- a/compat/strtoull.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * strtoull.c --
- *
- * Source code for the "strtoull" library procedure.
- *
- * Copyright (c) 1988 The Regents of the University of California.
- * Copyright (c) 1994 Sun Microsystems, Inc.
- *
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- */
-
-#include "tcl.h"
-#include "tclPort.h"
-#include <ctype.h>
-
-/*
- * The table below is used to convert from ASCII digits to a
- * numerical equivalent. It maps from '0' through 'z' to integers
- * (100 for non-digit characters).
- */
-
-static char cvtIn[] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* '0' - '9' */
- 100, 100, 100, 100, 100, 100, 100, /* punctuation */
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, /* 'A' - 'Z' */
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35,
- 100, 100, 100, 100, 100, 100, /* punctuation */
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, /* 'a' - 'z' */
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35};
-
-
-/*
- *----------------------------------------------------------------------
- *
- * strtoull --
- *
- * Convert an ASCII string into an integer.
- *
- * Results:
- * The return value is the integer equivalent of string. If endPtr
- * is non-NULL, then *endPtr is filled in with the character
- * after the last one that was part of the integer. If string
- * doesn't contain a valid integer value, then zero is returned
- * and *endPtr is set to string.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-#if TCL_WIDE_INT_IS_LONG
-unsigned long long
-#else
-Tcl_WideUInt
-#endif
-strtoull(string, endPtr, base)
- CONST char *string; /* String of ASCII digits, possibly
- * preceded by white space. For bases
- * greater than 10, either lower- or
- * upper-case digits may be used.
- */
- char **endPtr; /* Where to store address of terminating
- * character, or NULL. */
- int base; /* Base for conversion. Must be less
- * than 37. If 0, then the base is chosen
- * from the leading characters of string:
- * "0x" means hex, "0" means octal, anything
- * else means decimal.
- */
-{
- register CONST char *p;
- register Tcl_WideUInt result = 0;
- register unsigned digit;
- register Tcl_WideUInt shifted;
- int anyDigits = 0, negative = 0;
-
- /*
- * Skip any leading blanks.
- */
-
- p = string;
- while (isspace(UCHAR(*p))) { /* INTL: locale-dependent */
- p += 1;
- }
-
- /*
- * Check for a sign.
- */
-
- if (*p == '-') {
- p += 1;
- negative = 1;
- } else {
- if (*p == '+') {
- p += 1;
- }
- }
-
- /*
- * If no base was provided, pick one from the leading characters
- * of the string.
- */
-
- if (base == 0) {
- if (*p == '0') {
- p += 1;
- if (*p == 'x' || *p == 'X') {
- p += 1;
- base = 16;
- } else {
-
- /*
- * Must set anyDigits here, otherwise "0" produces a
- * "no digits" error.
- */
-
- anyDigits = 1;
- base = 8;
- }
- } else {
- base = 10;
- }
- } else if (base == 16) {
-
- /*
- * Skip a leading "0x" from hex numbers.
- */
-
- if ((p[0] == '0') && (p[1] == 'x' || *p == 'X')) {
- p += 2;
- }
- }
-
- /*
- * Sorry this code is so messy, but speed seems important. Do
- * different things for base 8, 10, 16, and other.
- */
-
- if (base == 8) {
- for ( ; ; p += 1) {
- digit = *p - '0';
- if (digit > 7) {
- break;
- }
- shifted = result << 3;
- if ((shifted >> 3) != result) {
- goto overflow;
- }
- result = shifted + digit;
- if ( result < shifted ) {
- goto overflow;
- }
- anyDigits = 1;
- }
- } else if (base == 10) {
- for ( ; ; p += 1) {
- digit = *p - '0';
- if (digit > 9) {
- break;
- }
- shifted = 10 * result;
- if ((shifted / 10) != result) {
- goto overflow;
- }
- result = shifted + digit;
- if ( result < shifted ) {
- goto overflow;
- }
- anyDigits = 1;
- }
- } else if (base == 16) {
- for ( ; ; p += 1) {
- digit = *p - '0';
- if (digit > ('z' - '0')) {
- break;
- }
- digit = cvtIn[digit];
- if (digit > 15) {
- break;
- }
- shifted = result << 4;
- if ((shifted >> 4) != result) {
- goto overflow;
- }
- result = shifted + digit;
- if ( result < shifted ) {
- goto overflow;
- }
- anyDigits = 1;
- }
- } else if ( base >= 2 && base <= 36 ) {
- for ( ; ; p += 1) {
- digit = *p - '0';
- if (digit > ('z' - '0')) {
- break;
- }
- digit = cvtIn[digit];
- if (digit >= (unsigned) base) {
- break;
- }
- shifted = result * base;
- if ((shifted/base) != result) {
- goto overflow;
- }
- result = shifted + digit;
- if ( result < shifted ) {
- goto overflow;
- }
- anyDigits = 1;
- }
- }
-
- /*
- * Negate if we found a '-' earlier.
- */
-
- if (negative) {
- result = (Tcl_WideUInt)(-((Tcl_WideInt)result));
- }
-
- /*
- * See if there were any digits at all.
- */
-
- if (!anyDigits) {
- p = string;
- }
-
- if (endPtr != 0) {
- *endPtr = (char *) p;
- }
-
- return result;
-
- /*
- * On overflow generate the right output
- */
-
- overflow:
- errno = ERANGE;
- if (endPtr != 0) {
- for ( ; ; p += 1) {
- digit = *p - '0';
- if (digit > ('z' - '0')) {
- break;
- }
- digit = cvtIn[digit];
- if (digit >= (unsigned) base) {
- break;
- }
- }
- *endPtr = (char *) p;
- }
- return (Tcl_WideUInt)Tcl_LongAsWide(-1);
-}
diff --git a/compat/tclErrno.h b/compat/tclErrno.h
deleted file mode 100644
index f4e3680..0000000
--- a/compat/tclErrno.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * tclErrno.h --
- *
- * This header file contains the various POSIX errno definitions that
- * are used by Tcl. This file is derived from the spec POSIX 2.4 and
- * previous implementations for Berkeley UNIX.
- *
- * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
- * Copyright (c) 1996 Sun Microsystems, Inc.
- *
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- */
-
-extern int errno; /* global error number */
-
-#define EPERM 1 /* Operation not permitted */
-#define ENOENT 2 /* No such file or directory */
-#define ESRCH 3 /* No such process */
-#define EINTR 4 /* Interrupted system call */
-#define EIO 5 /* Input/output error */
-#define ENXIO 6 /* Device not configured */
-#define E2BIG 7 /* Argument list too long */
-#define ENOEXEC 8 /* Exec format error */
-#define EBADF 9 /* Bad file descriptor */
-#define ECHILD 10 /* No child processes */
-#define EDEADLK 11 /* Resource deadlock avoided */
- /* 11 was EAGAIN */
-#define ENOMEM 12 /* Cannot allocate memory */
-#define EACCES 13 /* Permission denied */
-#define EFAULT 14 /* Bad address */
-#define ENOTBLK 15 /* Block device required */
-#define EBUSY 16 /* Device busy */
-#define EEXIST 17 /* File exists */
-#define EXDEV 18 /* Cross-device link */
-#define ENODEV 19 /* Operation not supported by device */
-#define ENOTDIR 20 /* Not a directory */
-#define EISDIR 21 /* Is a directory */
-#define EINVAL 22 /* Invalid argument */
-#define ENFILE 23 /* Too many open files in system */
-#define EMFILE 24 /* Too many open files */
-#define ENOTTY 25 /* Inappropriate ioctl for device */
-#define ETXTBSY 26 /* Text file busy */
-#define EFBIG 27 /* File too large */
-#define ENOSPC 28 /* No space left on device */
-#define ESPIPE 29 /* Illegal seek */
-#define EROFS 30 /* Read-only file system */
-#define EMLINK 31 /* Too many links */
-#define EPIPE 32 /* Broken pipe */
-#define EDOM 33 /* Numerical argument out of domain */
-#define ERANGE 34 /* Result too large */
-#define EAGAIN 35 /* Resource temporarily unavailable */
-#define EWOULDBLOCK EAGAIN /* Operation would block */
-#define EINPROGRESS 36 /* Operation now in progress */
-#define EALREADY 37 /* Operation already in progress */
-#define ENOTSOCK 38 /* Socket operation on non-socket */
-#define EDESTADDRREQ 39 /* Destination address required */
-#define EMSGSIZE 40 /* Message too long */
-#define EPROTOTYPE 41 /* Protocol wrong type for socket */
-#define ENOPROTOOPT 42 /* Protocol not available */
-#define EPROTONOSUPPORT 43 /* Protocol not supported */
-#define ESOCKTNOSUPPORT 44 /* Socket type not supported */
-#define EOPNOTSUPP 45 /* Operation not supported on socket */
-#define EPFNOSUPPORT 46 /* Protocol family not supported */
-#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
-#define EADDRINUSE 48 /* Address already in use */
-#define EADDRNOTAVAIL 49 /* Can't assign requested address */
-#define ENETDOWN 50 /* Network is down */
-#define ENETUNREACH 51 /* Network is unreachable */
-#define ENETRESET 52 /* Network dropped connection on reset */
-#define ECONNABORTED 53 /* Software caused connection abort */
-#define ECONNRESET 54 /* Connection reset by peer */
-#define ENOBUFS 55 /* No buffer space available */
-#define EISCONN 56 /* Socket is already connected */
-#define ENOTCONN 57 /* Socket is not connected */
-#define ESHUTDOWN 58 /* Can't send after socket shutdown */
-#define ETOOMANYREFS 59 /* Too many references: can't splice */
-#define ETIMEDOUT 60 /* Connection timed out */
-#define ECONNREFUSED 61 /* Connection refused */
-#define ELOOP 62 /* Too many levels of symbolic links */
-#define ENAMETOOLONG 63 /* File name too long */
-#define EHOSTDOWN 64 /* Host is down */
-#define EHOSTUNREACH 65 /* No route to host */
-#define ENOTEMPTY 66 /* Directory not empty */
-#define EPROCLIM 67 /* Too many processes */
-#define EUSERS 68 /* Too many users */
-#define EDQUOT 69 /* Disc quota exceeded */
-#define ESTALE 70 /* Stale NFS file handle */
-#define EREMOTE 71 /* Too many levels of remote in path */
-#define EBADRPC 72 /* RPC struct is bad */
-#define ERPCMISMATCH 73 /* RPC version wrong */
-#define EPROGUNAVAIL 74 /* RPC prog. not avail */
-#define EPROGMISMATCH 75 /* Program version wrong */
-#define EPROCUNAVAIL 76 /* Bad procedure for program */
-#define ENOLCK 77 /* No locks available */
-#define ENOSYS 78 /* Function not implemented */
-#define EOVERFLOW 79 /* Value too large to be stored in data type */
diff --git a/compat/tmpnam.c b/compat/tmpnam.c
deleted file mode 100644
index 89ce5fb..0000000
--- a/compat/tmpnam.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of California at Berkeley. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific written prior permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/file.h>
-#include <stdio.h>
-
-/*
- * Use /tmp instead of /usr/tmp, because L_tmpname is only 14 chars
- * on some machines (like NeXT machines) and /usr/tmp will cause
- * buffer overflows.
- */
-
-#ifdef P_tmpdir
-# undef P_tmpdir
-#endif
-#define P_tmpdir "/tmp"
-
-char *
-tmpnam(s)
- char *s;
-{
- static char name[50];
- char *mktemp();
-
- if (!s)
- s = name;
- (void)sprintf(s, "%s/XXXXXX", P_tmpdir);
- return(mktemp(s));
-}
diff --git a/compat/waitpid.c b/compat/waitpid.c
index a5960ce..8f65799 100644
--- a/compat/waitpid.c
+++ b/compat/waitpid.c
@@ -1,19 +1,17 @@
/*
* waitpid.c --
*
- * This procedure emulates the POSIX waitpid kernel call on
- * BSD systems that don't have waitpid but do have wait3.
- * This code is based on a prototype version written by
- * Mark Diekhans and Karl Lehenbauer.
+ * This procedure emulates the POSIX waitpid kernel call on BSD systems
+ * that don't have waitpid but do have wait3. This code is based on a
+ * prototype version written by Mark Diekhans and Karl Lehenbauer.
*
* Copyright (c) 1993 The Regents of the University of California.
* Copyright (c) 1994 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * 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 "tclPort.h"
#ifndef pid_t
@@ -21,40 +19,37 @@
#endif
/*
- * A linked list of the following structures is used to keep track
- * of processes for which we received notification from the kernel,
- * but the application hasn't waited for them yet (this can happen
- * because wait may not return the process we really want). We
- * save the information here until the application finally does
- * wait for the process.
+ * A linked list of the following structures is used to keep track of
+ * processes for which we received notification from the kernel, but the
+ * application hasn't waited for them yet (this can happen because wait may
+ * not return the process we really want). We save the information here until
+ * the application finally does wait for the process.
*/
typedef struct WaitInfo {
- pid_t pid; /* Pid of process that exited. */
- WAIT_STATUS_TYPE status; /* Status returned when child exited
- * or suspended. */
- struct WaitInfo *nextPtr; /* Next in list of exited processes. */
+ pid_t pid; /* Pid of process that exited. */
+ WAIT_STATUS_TYPE status; /* Status returned when child exited or
+ * suspended. */
+ struct WaitInfo *nextPtr; /* Next in list of exited processes. */
} WaitInfo;
-static WaitInfo *deadList = NULL; /* First in list of all dead
- * processes. */
+static WaitInfo *deadList = NULL;
+ /* First in list of all dead processes. */
/*
*----------------------------------------------------------------------
*
* waitpid --
*
- * This procedure emulates the functionality of the POSIX
- * waitpid kernel call, using the BSD wait3 kernel call.
- * Note: it doesn't emulate absolutely all of the waitpid
- * functionality, in that it doesn't support pid's of 0
- * or < -1.
+ * This procedure emulates the functionality of the POSIX waitpid kernel
+ * call, using the BSD wait3 kernel call. Note: it doesn't emulate
+ * absolutely all of the waitpid functionality, in that it doesn't
+ * support pid's of 0 or < -1.
*
* Results:
- * -1 is returned if there is an error in the wait kernel call.
- * Otherwise the pid of an exited or suspended process is
- * returned and *statusPtr is set to the status value of the
- * process.
+ * -1 is returned if there is an error in the wait kernel call. Otherwise
+ * the pid of an exited or suspended process is returned and *statusPtr
+ * is set to the status value of the process.
*
* Side effects:
* None.
@@ -67,12 +62,12 @@ static WaitInfo *deadList = NULL; /* First in list of all dead
#endif
pid_t
-waitpid(pid, statusPtr, options)
- pid_t pid; /* The pid to wait on. Must be -1 or
- * greater than zero. */
- int *statusPtr; /* Where to store wait status for the
+waitpid(
+ pid_t pid, /* The pid to wait on. Must be -1 or greater
+ * than zero. */
+ int *statusPtr, /* Where to store wait status for the
* process. */
- int options; /* OR'ed combination of WNOHANG and
+ int options) /* OR'ed combination of WNOHANG and
* WUNTRACED. */
{
register WaitInfo *waitPtr, *prevPtr;
@@ -85,9 +80,9 @@ waitpid(pid, statusPtr, options)
}
/*
- * See if there's a suitable process that has already stopped or
- * exited. If so, remove it from the list of exited processes and
- * return its information.
+ * See if there's a suitable process that has already stopped or exited.
+ * If so, remove it from the list of exited processes and return its
+ * information.
*/
for (waitPtr = deadList, prevPtr = NULL; waitPtr != NULL;
@@ -110,12 +105,12 @@ waitpid(pid, statusPtr, options)
}
/*
- * Wait for any process to stop or exit. If it's an acceptable one
- * then return it to the caller; otherwise store information about it
- * in the list of exited processes and try again. On systems that
- * have only wait but not wait3, there are several situations we can't
- * handle, but we do the best we can (e.g. can still handle some
- * combinations of options by invoking wait instead of wait3).
+ * Wait for any process to stop or exit. If it's an acceptable one then
+ * return it to the caller; otherwise store information about it in the
+ * list of exited processes and try again. On systems that have only wait
+ * but not wait3, there are several situations we can't handle, but we do
+ * the best we can (e.g. can still handle some combinations of options by
+ * invoking wait instead of wait3).
*/
while (1) {
@@ -148,13 +143,13 @@ waitpid(pid, statusPtr, options)
return result;
/*
- * Can't return this info to caller. Save it in the list of
- * stopped or exited processes. Tricky point: first check for
- * an existing entry for the process and overwrite it if it
- * exists (e.g. a previously stopped process might now be dead).
+ * Can't return this info to caller. Save it in the list of stopped or
+ * exited processes. Tricky point: first check for an existing entry
+ * for the process and overwrite it if it exists (e.g. a previously
+ * stopped process might now be dead).
*/
- saveInfo:
+ saveInfo:
for (waitPtr = deadList; waitPtr != NULL; waitPtr = waitPtr->nextPtr) {
if (waitPtr->pid == result) {
waitPtr->status = status;
@@ -167,6 +162,7 @@ waitpid(pid, statusPtr, options)
waitPtr->nextPtr = deadList;
deadList = waitPtr;
- waitAgain: continue;
+ waitAgain:
+ continue;
}
}
diff --git a/doc/Access.3 b/doc/Access.3
index cab6466..98d6635 100644
--- a/doc/Access.3
+++ b/doc/Access.3
@@ -19,7 +19,7 @@ int
int
\fBTcl_Stat\fR(\fIpath\fR, \fIstatPtr\fR)
.SH ARGUMENTS
-.AS "struct stat" *statPtr in
+.AS "struct stat" *statPtr out
.AP char *path in
Native name of the file to check the attributes of.
.AP int mode in
diff --git a/doc/AddErrInfo.3 b/doc/AddErrInfo.3
index 7351dce..136a16f 100644
--- a/doc/AddErrInfo.3
+++ b/doc/AddErrInfo.3
@@ -6,17 +6,29 @@
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.so man.macros
-.TH Tcl_AddErrorInfo 3 8.0 Tcl "Tcl Library Procedures"
+.TH Tcl_AddErrorInfo 3 8.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
-Tcl_AddObjErrorInfo, Tcl_AddErrorInfo, Tcl_SetObjErrorCode, Tcl_SetErrorCode, Tcl_SetErrorCodeVA, Tcl_PosixError, Tcl_LogCommandInfo \- record information about errors
+Tcl_GetReturnOptions, Tcl_SetReturnOptions, Tcl_AddErrorInfo, Tcl_AppendObjToErrorInfo, Tcl_AddObjErrorInfo, Tcl_SetObjErrorCode, Tcl_SetErrorCode, Tcl_SetErrorCodeVA, Tcl_PosixError, Tcl_LogCommandInfo \- retrieve or record information about errors and other return options
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
+.VS 8.5
.sp
-\fBTcl_AddObjErrorInfo\fR(\fIinterp, message, length\fR)
+Tcl_Obj *
+\fBTcl_GetReturnOptions\fR(\fIinterp, code\fR)
+.sp
+int
+\fBTcl_SetReturnOptions\fR(\fIinterp, options\fR)
+.VE 8.5
.sp
\fBTcl_AddErrorInfo\fR(\fIinterp, message\fR)
+.VS 8.5
+.sp
+\fBTcl_AppendObjToErrorInfo\fR(\fIinterp, objPtr\fR)
+.VE 8.5
+.sp
+\fBTcl_AddObjErrorInfo\fR(\fIinterp, message, length\fR)
.sp
\fBTcl_SetObjErrorCode\fR(\fIinterp, errorObjPtr\fR)
.sp
@@ -24,38 +36,47 @@ Tcl_AddObjErrorInfo, Tcl_AddErrorInfo, Tcl_SetObjErrorCode, Tcl_SetErrorCode, Tc
.sp
\fBTcl_SetErrorCodeVA\fR(\fIinterp, argList\fR)
.sp
-CONST char *
+const char *
\fBTcl_PosixError\fR(\fIinterp\fR)
.sp
void
\fBTcl_LogCommandInfo\fR(\fIinterp, script, command, commandLength\fR)
.SH ARGUMENTS
-.AS Tcl_Interp *message
+.AS Tcl_Interp commandLength
.AP Tcl_Interp *interp in
Interpreter in which to record information.
+.AP int code
+The code returned from script evaluation.
+.AP Tcl_Obj *options
+A dictionary of return options.
.AP char *message in
+For \fBTcl_AddErrorInfo\fR,
+this is a conventional C string to append to the \fB\-errorinfo\fR return option.
For \fBTcl_AddObjErrorInfo\fR,
-this points to the first byte of an array of bytes
-containing a string to record in the \fBerrorInfo\fR variable.
+this points to the first byte of an array of \fIlength\fR bytes
+containing a string to append to the \fB\-errorinfo\fR return option.
This byte array may contain embedded null bytes
unless \fIlength\fR is negative.
-For \fBTcl_AddErrorInfo\fR,
-this is a conventional C string to record in the \fBerrorInfo\fR variable.
+.VS 8.5
+.AP Tcl_Obj *objPtr in
+A message to be appended to the \fB\-errorinfo\fR return option
+in the form of a Tcl_Obj value.
+.VE 8.5
.AP int length in
The number of bytes to copy from \fImessage\fR when
-setting the \fBerrorInfo\fR variable.
+appending to the \fB\-errorinfo\fR return option.
If negative, all bytes up to the first null byte are used.
.AP Tcl_Obj *errorObjPtr in
-This variable \fBerrorCode\fR will be set to this value.
+The \fB\-errorcode\fR return option will be set to this value.
.AP char *element in
-String to record as one element of \fBerrorCode\fR variable.
+String to record as one element of the \fB\-errorcode\fR return option.
Last \fIelement\fR argument must be NULL.
.AP va_list argList in
An argument list which must have been initialized using
-\fBTCL_VARARGS_START\fR, and cleared using \fBva_end\fR.
-.AP "CONST char" *script in
+\fBva_start\fR, and cleared using \fBva_end\fR.
+.AP "const char" *script in
Pointer to first character in script containing command (must be <= command)
-.AP "CONST char" *command in
+.AP "const char" *command in
Pointer to first character in command that generated the error
.AP int commandLength in
Number of bytes in command; -1 means use all bytes up to first null byte
@@ -63,70 +84,156 @@ Number of bytes in command; -1 means use all bytes up to first null byte
.SH DESCRIPTION
.PP
-These procedures are used to manipulate two Tcl global variables
-that hold information about errors.
-The variable \fBerrorInfo\fR holds a stack trace of the
+.VS 8.5
+The \fBTcl_SetReturnOptions\fR and \fBTcl_GetReturnOptions\fR
+routines expose the same capabilities as the \fBreturn\fR and
+\fBcatch\fR commands, respectively, in the form of a C interface.
+.PP
+\fBTcl_GetReturnOptions\fR retrieves the dictionary of return options
+from an interpreter following a script evaluation.
+Routines such as \fBTcl_Eval\fR are called to evaluate a
+script in an interpreter. These routines return an integer
+completion code. These routines also leave in the interpreter
+both a result and a dictionary of return options generated
+by script evaluation. Just as \fBTcl_GetObjResult\fR retrieves
+the result, \fBTcl_GetReturnOptions\fR retrieves the dictionary
+of return options. The integer completion code should be
+passed as the \fIcode\fR argument to \fBTcl_GetReturnOptions\fR
+so that all required options will be present in the dictionary.
+Specifically, a \fIcode\fR value of \fBTCL_ERROR\fR will
+ensure that entries for the keys \fB\-errorinfo\fR,
+\fB\-errorcode\fR, and \fB\-errorline\fR will appear in the
+dictionary. Also, the entries for the keys \fB\-code\fR
+and \fB\-level\fR will be adjusted if necessary to agree
+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, without the need to check for a shared object.
+.PP
+A typical usage for \fBTcl_GetReturnOptions\fR is to
+retrieve the stack trace when script evaluation returns
+\fBTCL_ERROR\fR, like so:
+.CS
+int code = Tcl_Eval(interp, script);
+if (code == TCL_ERROR) {
+ Tcl_Obj *options = Tcl_GetReturnOptions(interp, code);
+ Tcl_Obj *key = Tcl_NewStringObj("-errorinfo", -1);
+ Tcl_Obj *stackTrace;
+ Tcl_IncrRefCount(key);
+ Tcl_DictObjGet(NULL, options, key, &stackTrace);
+ Tcl_DecrRefCount(key);
+ /* Do something with stackTrace */
+}
+.CE
+.PP
+\fBTcl_SetReturnOptions\fR sets the return options
+of \fIinterp\fR to be \fIoptions\fR. If \fIoptions\fR
+contains any invalid value for any key, TCL_ERROR will
+be returned, and the interp result will be set to an
+appropriate error message. Otherwise, a completion code
+in agreement with the \fB\-code\fR and \fB\-level\fR
+keys in \fIoptions\fR will be returned.
+.PP
+As an example, Tcl's \fBreturn\fR command itself could
+be implemented in terms of \fBTcl_SetReturnOptions\fR
+like so:
+.CS
+if ((objc % 2) == 0) { /* explicit result argument */
+ objc--;
+ Tcl_SetObjResult(interp, objv[objc]);
+}
+return Tcl_SetReturnOptions(interp, Tcl_NewListObj(objc-1, objv+1));
+.CE
+(It is not really implemented that way. Internal access
+privileges allow for a more efficient alternative that meshes
+better with the bytecode compiler.)
+.PP
+Note that a newly created \fBTcl_Obj\fR may be passed
+in as the \fIoptions\fR argument without the need to tend
+to any reference counting. This is analogous to
+\fBTcl_SetObjResult\fR.
+.PP
+While \fBTcl_SetReturnOptions\fR provides a general interface
+to set any collection of return options, there are a handful
+of return options that are very frequently used. Most
+notably the \fB\-errorinfo\fR and \fB\-errorcode\fR return
+options should be set properly when the command procedure
+of a command returns \fBTCL_ERROR\fR. Tcl provides several
+simpler interfaces to more directly set these return options.
+.VE 8.5
+.PP
+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 variable \fBerrorCode\fR holds a list of items that
+The \fB\-errorcode\fR option holds a list of items that
are intended to be machine-readable.
-The first item in \fBerrorCode\fR identifies the class of
+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)
-and additional elements in \fBerrorCode\fR hold additional pieces
+and additional elements hold additional pieces
of information that depend on the class.
-See the Tcl overview manual entry for details on the various
-formats for \fBerrorCode\fR.
+See the tclvars manual entry for details on the various
+formats for the \fB\-errorcode\fR option used by
+Tcl's built-in commands.
.PP
-The \fBerrorInfo\fR variable is gradually built up as an
+The \fB\-errorinfo\fR option value is gradually built up as an
error unwinds through the nested operations.
-Each time an error code is returned to \fBTcl_EvalObjEx\fR
-(or \fBTcl_Eval\fR, which calls \fBTcl_EvalObjEx\fR)
-it calls the procedure \fBTcl_AddObjErrorInfo\fR to add
-additional text to \fBerrorInfo\fR describing the
+Each time an error code is returned to \fBTcl_Eval\fR, or
+any of the routines that performs script evaluation,
+the procedure \fBTcl_AddErrorInfo\fR is called to add
+additional text to the \fB\-errorinfo\fR value describing the
command that was being executed when the error occurred.
By the time the error has been passed all the way back
to the application, it will contain a complete trace
of the activity in progress when the error occurred.
.PP
It is sometimes useful to add additional information to
-\fBerrorInfo\fR beyond what can be supplied automatically
-by \fBTcl_EvalObjEx\fR.
-\fBTcl_AddObjErrorInfo\fR may be used for this purpose:
-its \fImessage\fR and \fIlength\fR arguments describe an additional
-string to be appended to \fBerrorInfo\fR.
-For example, the \fBsource\fR command calls \fBTcl_AddObjErrorInfo\fR
-to record the name of the file being processed and the
-line number on which the error occurred;
-for Tcl procedures, the procedure name and line number
+the \fB\-errorinfo\fR value beyond what can be supplied automatically
+by the script evaluation routines.
+\fBTcl_AddErrorInfo\fR may be used for this purpose:
+its \fImessage\fR argument is an additional
+string to be appended to the \fB\-errorinfo\fR option.
+For example, when an error arises during the \fBsource\fR command,
+the procedure \fBTcl_AddErrorInfo\fR is called to
+record the name of the file being processed and the
+line number on which the error occurred.
+Likewise, when an error arises during evaluation of a
+Tcl procedures, the procedure name and line number
within the procedure are recorded, and so on.
-The best time to call \fBTcl_AddObjErrorInfo\fR is just after
-\fBTcl_EvalObjEx\fR has returned \fBTCL_ERROR\fR.
-In calling \fBTcl_AddObjErrorInfo\fR, you may find it useful to
-use the \fBerrorLine\fR field of the interpreter (see the
-\fBTcl_Interp\fR manual entry for details).
-.PP
-\fBTcl_AddErrorInfo\fR resembles \fBTcl_AddObjErrorInfo\fR
-but differs in initializing \fBerrorInfo\fR from the string
-value of the interpreter's result
-if the error is just starting to be logged.
-It does not use the result as a Tcl object
-so any embedded null characters in the result
-will cause information to be lost.
-It also takes a conventional C string in \fImessage\fR
-instead of \fBTcl_AddObjErrorInfo\fR's counted string.
+The best time to call \fBTcl_AddErrorInfo\fR is just after
+a script evaluation routine has returned \fBTCL_ERROR\fR.
+The value of the \fB\-errorline\fR return option (retrieved
+via a call to \fBTcl_GetReturnOptions\fR) often makes up
+a useful part of the \fImessage\fR passed to \fBTcl_AddErrorInfo\fR.
+.PP
+.VS 8.5
+\fBTcl_AppendObjToErrorInfo\fR is an alternative interface to the
+same functionality as \fBTcl_AddErrorInfo\fR. \fBTcl_AppendObjToErrorInfo\fR
+is called when the string value to be appended to the \fB\-errorinfo\fR option
+is available as a \fBTcl_Obj\fR instead of as a \fBchar\fR array.
+.VE 8.5
+.PP
+\fBTcl_AddObjErrorInfo\fR is nearly identical
+to \fBTcl_AddErrorInfo\fR, except that it has an additional \fIlength\fR
+argument. This allows the \fImessage\fR string to contain
+embedded null bytes. This is essentially never a good idea.
+If the \fImessage\fR needs to contain the null character \fBU+0000\fR,
+Tcl's usual internal encoding rules should be used to avoid
+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
-\fBerrorCode\fR variable. \fIerrorObjPtr\fR contains a list object
-built up by the caller. \fBerrorCode\fR is set to this
-value. \fBTcl_SetObjErrorCode\fR is typically invoked just
-before returning an error in an object command. If an error is
+\fB\-errorcode\fR return option to the list object \fIerrorObjPtr\fR
+built up by the caller.
+\fBTcl_SetObjErrorCode\fR is typically invoked just
+before returning an error. If an error is
returned without calling \fBTcl_SetObjErrorCode\fR or
\fBTcl_SetErrorCode\fR the Tcl interpreter automatically sets
-\fBerrorCode\fR to \fBNONE\fR.
+the \fB\-errorcode\fR return option to \fBNONE\fR.
.PP
The procedure \fBTcl_SetErrorCode\fR is also used to set the
-\fBerrorCode\fR variable. However, it takes one or more strings to
+\fB\-errorcode\fR return option. However, it takes one or more strings to
record instead of an object. Otherwise, it is similar to
\fBTcl_SetObjErrorCode\fR in behavior.
.PP
@@ -134,9 +241,10 @@ record instead of an object. Otherwise, it is similar to
instead of taking a variable number of arguments it takes an argument list.
.PP
\fBTcl_PosixError\fR
-sets the \fBerrorCode\fR variable after an error in a POSIX kernel call.
+sets the \fB\-errorcode\fR variable after an error in a POSIX kernel call.
It reads the value of the \fBerrno\fR C variable and calls
-\fBTcl_SetErrorCode\fR to set \fBerrorCode\fR in the \fBPOSIX\fR format.
+\fBTcl_SetErrorCode\fR to set the \fB\-errorcode\fR return
+option in the \fBPOSIX\fR format.
The caller must previously have called \fBTcl_SetErrno\fR to set
\fBerrno\fR; this is necessary on some platforms (e.g. Windows) where Tcl
is linked into an application as a shared library, or when the error
@@ -146,41 +254,44 @@ occurs in a dynamically loaded extension. See the manual entry for
\fBTcl_PosixError\fR returns a human-readable diagnostic message
for the error
(this is the same value that will appear as the third element
-in \fBerrorCode\fR).
+in the \fB\-errorcode\fR value).
It may be convenient to include this string as part of the
error message returned to the application in
the interpreter's result.
.PP
\fBTcl_LogCommandInfo\fR is invoked after an error occurs in an
interpreter. It adds information about the command that was being
-executed when the error occurred to the \fBerrorInfo\fR variable, and
-the line number stored internally in the interpreter is set. On the
-first call to \fBTcl_LogCommandInfo\fR or \fBTcl_AddObjErrorInfo\fR
-since an error occurred, the old information in \fBerrorInfo\fR is
-deleted.
+executed when the error occurred to the \fB\-errorinfo\fR value, and
+the line number stored internally in the interpreter is set.
+.PP
+In older releases of Tcl, there was no \fBTcl_GetReturnOptions\fR
+routine. In its place, the global Tcl variables \fBerrorInfo\fR
+and \fBerrorCode\fR were the only place to retrieve the error
+information. Much existing code written for older Tcl releases
+still access this information via those global variables.
.PP
-It is important to call the procedures described here rather than
+It is important to realize that while reading from those
+global variables remains a supported way to access these
+return option values, it is important not to assume that
+writing to those global variables will properly set the
+corresponding return options. It has long been emphasized
+in this manual page that it is important to
+call the procedures described here rather than
setting \fBerrorInfo\fR or \fBerrorCode\fR directly with
\fBTcl_ObjSetVar2\fR.
-The reason for this is that the Tcl interpreter keeps information
-about whether these procedures have been called.
-For example, the first time \fBTcl_AddObjErrorInfo\fR is called
-for an error, it clears the existing value of \fBerrorInfo\fR
-and adds the error message in the interpreter's result to the variable
-before appending \fImessage\fR;
-in subsequent calls, it just appends the new \fImessage\fR.
-When \fBTcl_SetErrorCode\fR is called, it sets a flag indicating
-that \fBerrorCode\fR has been set;
-this allows the Tcl interpreter to set \fBerrorCode\fR to \fBNONE\fR
-if it receives an error return
-when \fBTcl_SetErrorCode\fR hasn't been called.
.PP
If the procedure \fBTcl_ResetResult\fR is called,
-it clears all of the state associated with
-\fBerrorInfo\fR and \fBerrorCode\fR
-(but it doesn't actually modify the variables).
-If an error had occurred, this will clear the error state to
-make it appear as if no error had occurred after all.
+it clears all of the state of the interpreter associated with
+script evaluation, including the entire return options dictionary.
+In particular, the \fB\-errorinfo\fR and \fB\-errorcode\fR options
+are reset.
+If an error had occurred, the \fBTcl_ResetResult\fR call will
+clear the error state to make it appear as if no error had
+occurred after all.
+The global variables \fBerrorInfo\fR and
+\fBerrorCode\fR are not modified by \fBTcl_ResetResult\fR
+so they continue to hold a record of information about the
+most recent error seen in an interpreter.
.SH "SEE ALSO"
Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_Interp, Tcl_ResetResult, Tcl_SetErrno
diff --git a/doc/Alloc.3 b/doc/Alloc.3
index e90114d..ca4f949 100644
--- a/doc/Alloc.3
+++ b/doc/Alloc.3
@@ -67,22 +67,24 @@ further allocation.
\fBTcl_Realloc\fR changes the size of the block pointed to by
\fIptr\fR to \fIsize\fR bytes and returns a pointer to the new block.
The contents will be unchanged up to the lesser of the new and old
-sizes. The returned location may be different from \fIptr\fR.
+sizes. The returned location may be different from \fIptr\fR. If
+\fIptr\fR is NULL, this is equivalent to calling \fBTcl_Alloc\fR with
+just the \fIsize\fR argument.
.PP
\fBTcl_AttemptAlloc\fR and \fBTcl_AttemptRealloc\fR are identical in
function to \fBTcl_Alloc\fR and \fBTcl_Realloc\fR, except that
\fBTcl_AttemptAlloc\fR and \fBTcl_AttemptRealloc\fR will not cause the Tcl
interpreter to \fBpanic\fR if the memory allocation fails. If the
allocation fails, these functions will return NULL. Note that on some
-platforms, attempting to allocate a block of memory will also cause
-these functions to return NULL.
+platforms, but not all, attempting to allocate a zero-sized block of
+memory will also cause these functions to return NULL.
.PP
The procedures \fBckalloc\fR, \fBckfree\fR, \fBckrealloc\fR,
\fBattemptckalloc\fR, and \fBattemptckrealloc\fR are implemented
as macros. Normally, they are synonyms for the corresponding
procedures documented on this page. When Tcl and all modules
calling Tcl are compiled with \fBTCL_MEM_DEBUG\fR defined, however,
-these macros are redefined to be special debugging versions of
+these macros are redefined to be special debugging versions
of these procedures. To support Tcl's memory debugging within a
module, use the macros rather than direct calls to \fBTcl_Alloc\fR, etc.
diff --git a/doc/AllowExc.3 b/doc/AllowExc.3
index 621ea47..ae595f1 100644
--- a/doc/AllowExc.3
+++ b/doc/AllowExc.3
@@ -16,7 +16,7 @@ Tcl_AllowExceptions \- allow all exceptions in next script evaluation
.sp
\fBTcl_AllowExceptions\fR(\fIinterp\fR)
.SH ARGUMENTS
-.AS Tcl_Interp *doublePtr
+.AS Tcl_Interp *interp
.AP Tcl_Interp *interp in
Interpreter in which script will be evaluated.
.BE
@@ -25,8 +25,8 @@ Interpreter in which script will be evaluated.
.PP
If a script is evaluated at top-level (i.e. no other scripts are
pending evaluation when the script is invoked), and if the script
-terminates with a completion code other than TCL_OK, TCL_ERROR
-or TCL_RETURN, then Tcl normally converts this into a TCL_ERROR
+terminates with a completion code other than \fBTCL_OK\fR, \fBTCL_ERROR\fR
+or \fBTCL_RETURN\fR, then Tcl normally converts this into a \fBTCL_ERROR\fR
return with an appropriate message. The particular script
evaluation procedures of Tcl that act in the manner are
\fBTcl_EvalObjEx\fR, \fBTcl_EvalObjv\fR, \fBTcl_Eval\fR, \fBTcl_EvalEx\fR,
@@ -38,7 +38,7 @@ calling one of those a procedures, then arbitrary completion
codes are permitted from the script, and they are returned without
modification.
This is useful in cases where the caller can deal with exceptions
-such as TCL_BREAK or TCL_CONTINUE in a meaningful way.
+such as \fBTCL_BREAK\fR or \fBTCL_CONTINUE\fR in a meaningful way.
.SH KEYWORDS
continue, break, exception, interpreter
diff --git a/doc/AppInit.3 b/doc/AppInit.3
index 14d30cf..0473090 100644
--- a/doc/AppInit.3
+++ b/doc/AppInit.3
@@ -24,7 +24,9 @@ Interpreter for the application.
.SH DESCRIPTION
.PP
-\fBTcl_AppInit\fR is a ``hook'' procedure that is invoked by
+\fBTcl_AppInit\fR is a
+.QW hook
+procedure that is invoked by
the main programs for Tcl applications such as \fBtclsh\fR and \fBwish\fR.
Its purpose is to allow new Tcl applications to be created without
modifying the main programs provided as part of Tcl and Tk.
@@ -47,8 +49,8 @@ Tcl variables \fBargv\fR and \fBargv0\fR in \fIinterp\fR.
.IP [3]
Invoke a startup script to initialize the application.
.LP
-\fBTcl_AppInit\fR returns TCL_OK or TCL_ERROR.
-If it returns TCL_ERROR then it must leave an error message in
+\fBTcl_AppInit\fR returns \fBTCL_OK\fR or \fBTCL_ERROR\fR.
+If it returns \fBTCL_ERROR\fR then it must leave an error message in
for the interpreter's result; otherwise the result is ignored.
.PP
In addition to \fBTcl_AppInit\fR, your application should also contain
@@ -58,7 +60,7 @@ Tcl_Main(argc, argv, Tcl_AppInit);
.CE
The third argument to \fBTcl_Main\fR gives the address of the
application-specific initialization procedure to invoke.
-This means that you don't have to use the name \fBTcl_AppInit\fR
+This means that you do not have to use the name \fBTcl_AppInit\fR
for the procedure, but in practice the name is nearly always
\fBTcl_AppInit\fR (in versions before Tcl 7.4 the name \fBTcl_AppInit\fR
was implicit; there was no way to specify the procedure explicitly).
diff --git a/doc/AssocData.3 b/doc/AssocData.3
index 105ebd6..e4c7bab 100644
--- a/doc/AssocData.3
+++ b/doc/AssocData.3
@@ -8,9 +8,7 @@
.TH Tcl_SetAssocData 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
-Tcl_GetAssocData, Tcl_SetAssocData, Tcl_DeleteAssocData \- manage
-associations of string keys and user specified data with Tcl
-interpreters.
+Tcl_GetAssocData, Tcl_SetAssocData, Tcl_DeleteAssocData \- manage associations of string keys and user specified data with Tcl interpreters
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -22,12 +20,10 @@ ClientData
.sp
\fBTcl_DeleteAssocData\fR(\fIinterp, key\fR)
.SH ARGUMENTS
-.AS Tcl_InterpDeleteProc *delProcPtr
+.AS Tcl_InterpDeleteProc **delProcPtr
.AP Tcl_Interp *interp in
Interpreter in which to execute the specified command.
-.VS 8.4
-.AP "CONST char" *key in
-.VE
+.AP "const char" *key in
Key for association with which to store data or from which to delete or
retrieve data. Typically the module prefix for a package.
.AP Tcl_InterpDeleteProc *delProc in
@@ -67,8 +63,8 @@ is deleted. \fIDeleteProc\fR should have arguments and result that match
the type \fBTcl_InterpDeleteProc\fR:
.CS
typedef void Tcl_InterpDeleteProc(
- ClientData \fIclientData\fR,
- Tcl_Interp *\fIinterp\fR);
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR);
.CE
When \fIdeleteProc\fR is invoked the \fIclientData\fR and \fIinterp\fR
arguments will be the same as the corresponding arguments passed to
diff --git a/doc/Async.3 b/doc/Async.3
index cc3354b..c4439a4 100644
--- a/doc/Async.3
+++ b/doc/Async.3
@@ -48,9 +48,9 @@ or 0 if \fIinterp\fR is NULL.
These procedures provide a safe mechanism for dealing with
asynchronous events such as signals.
If an event such as a signal occurs while a Tcl script is being
-evaluated then it isn't safe to take any substantive action to
+evaluated then it is not safe to take any substantive action to
process the event.
-For example, it isn't safe to evaluate a Tcl script since the
+For example, it is not safe to evaluate a Tcl script since the
interpreter may already be in the middle of evaluating a script;
it may not even be safe to allocate memory, since a memory
allocation could have been in progress when the event occurred.
@@ -140,7 +140,6 @@ If new handlers become ready while handlers are executing,
\fBTcl_AsyncInvoke\fR will invoke them all; at each point it
invokes the highest-priority (oldest) ready handler, repeating
this over and over until there are no longer any ready handlers.
-
.SH WARNING
.PP
It is almost always a bad idea for an asynchronous event
@@ -150,12 +149,11 @@ This sort of behavior can disrupt the execution of scripts in
subtle ways and result in bugs that are extremely difficult
to track down.
If an asynchronous event handler needs to evaluate Tcl scripts
-then it should first save the interpreter's result plus the values
-of the variables \fBerrorInfo\fR and \fBerrorCode\fR (this can
-be done, for example, by storing them in dynamic strings).
+then it should first save the interpreter's state by calling
+\fBTcl_SaveInterpState\fR, passing in the \fIcode\fR argument.
When the asynchronous handler is finished it should restore
-the interpreter's result, \fBerrorInfo\fR, and \fBerrorCode\fR,
-and return the \fIcode\fR argument.
+the interpreter's state by calling \fBTcl_RestoreInterpState\fR,
+and then returning the \fIcode\fR argument.
.SH KEYWORDS
-asynchronous event, handler, signal
+asynchronous event, handler, signal, Tcl_SaveInterpState, thread
diff --git a/doc/BackgdErr.3 b/doc/BackgdErr.3
index 532bb44..1e46b03 100644
--- a/doc/BackgdErr.3
+++ b/doc/BackgdErr.3
@@ -24,7 +24,8 @@ Interpreter in which the error occurred.
.SH DESCRIPTION
.PP
This procedure is typically invoked when a Tcl error occurs during
-``background processing'' such as executing an event handler.
+.QW "background processing"
+such as executing an event handler.
When such an error occurs, the error condition is reported to Tcl
or to a widget or some other C code, and there is not usually any
obvious way for that code to report the error to the user.
@@ -32,25 +33,29 @@ In these cases the code calls \fBTcl_BackgroundError\fR with an
\fIinterp\fR argument identifying the interpreter in which the
error occurred. At the time \fBTcl_BackgroundError\fR is invoked,
the interpreter's result is expected to contain an error message.
-\fBTcl_BackgroundError\fR will invoke the \fBbgerror\fR
-Tcl command to report the error in an application-specific fashion.
-If no \fBbgerror\fR command exists, or if it returns with an error condition,
-then \fBTcl_BackgroundError\fR reports the error itself by printing
-a message on the standard error file.
+\fBTcl_BackgroundError\fR will invoke the command registered
+in that interpreter to handle background errors by the
+\fBinterp bgerror\fR command.
+The registered handler command is meant to report the error
+in an application-specific fashion. The handler command
+receives two arguments, the result of the interp, and the
+return options of the interp at the time the error occurred.
+If the application registers no handler command, the default
+handler command will attempt to call \fBbgerror\fR to report
+the error. If an error condition arises while invoking the
+handler command, then \fBTcl_BackgroundError\fR reports the
+error itself by printing a message on the standard error file.
.PP
-\fBTcl_BackgroundError\fR does not invoke \fBbgerror\fR immediately
+\fBTcl_BackgroundError\fR does not invoke the handler command immediately
because this could potentially interfere with scripts that are in process
at the time the error occurred.
-Instead, it invokes \fBbgerror\fR later as an idle callback.
-\fBTcl_BackgroundError\fR saves the values of the \fBerrorInfo\fR and
-\fBerrorCode\fR variables and restores these values just before
-invoking \fBbgerror\fR.
+Instead, it invokes the handler command later as an idle callback.
.PP
It is possible for many background errors to accumulate before
-\fBbgerror\fR is invoked. When this happens, each of the errors
-is processed in order. However, if \fBbgerror\fR returns a
+the handler command is invoked. When this happens, each of the errors
+is processed in order. However, if the handle command returns a
break exception, then all remaining error reports for the
interpreter are skipped.
.SH KEYWORDS
-background, bgerror, error
+background, bgerror, error, interp
diff --git a/doc/Backslash.3 b/doc/Backslash.3
index eb859d7..8b399fc 100644
--- a/doc/Backslash.3
+++ b/doc/Backslash.3
@@ -17,35 +17,31 @@ Tcl_Backslash \- parse a backslash sequence
char
\fBTcl_Backslash\fR(\fIsrc, countPtr\fR)
.SH ARGUMENTS
-.AS char *countPtr
+.AS char *countPtr out
.AP char *src in
Pointer to a string starting with a backslash.
.AP int *countPtr out
-If \fIcountPtr\fR isn't NULL, \fI*countPtr\fR gets filled
+If \fIcountPtr\fR is not NULL, \fI*countPtr\fR gets filled
in with number of characters in the backslash sequence, including
the backslash character.
.BE
.SH DESCRIPTION
.PP
-.VS 8.1
The use of \fBTcl_Backslash\fR is deprecated in favor of
\fBTcl_UtfBackslash\fR.
.PP
This is a utility procedure provided for backwards compatibility with
non-internationalized Tcl extensions. It parses a backslash sequence and
returns the low byte of the Unicode character corresponding to the sequence.
-.VE
\fBTcl_Backslash\fR modifies \fI*countPtr\fR to contain the number of
characters in the backslash sequence.
.PP
See the Tcl manual entry for information on the valid backslash sequences.
All of the sequences described in the Tcl manual entry are supported by
\fBTcl_Backslash\fR.
-.VS 8.1 br
.SH "SEE ALSO"
Tcl(n), Tcl_UtfBackslash(3)
-.VE
.SH KEYWORDS
backslash, parse
diff --git a/doc/BoolObj.3 b/doc/BoolObj.3
index 2814e4e..395d159 100644
--- a/doc/BoolObj.3
+++ b/doc/BoolObj.3
@@ -1,14 +1,15 @@
'\"
'\" Copyright (c) 1996-1997 Sun Microsystems, Inc.
+'\" Contributions from Don Porter, NIST, 2005. (not subject to US copyright)
'\"
'\" 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.0 Tcl "Tcl Library Procedures"
+.TH Tcl_BooleanObj 3 8.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
-Tcl_NewBooleanObj, Tcl_SetBooleanObj, Tcl_GetBooleanFromObj \- manipulate Tcl objects as boolean values
+Tcl_NewBooleanObj, Tcl_SetBooleanObj, Tcl_GetBooleanFromObj \- store/retrieve boolean value in a Tcl_Obj
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -21,20 +22,14 @@ Tcl_Obj *
int
\fBTcl_GetBooleanFromObj\fR(\fIinterp, objPtr, boolPtr\fR)
.SH ARGUMENTS
-.AS Tcl_Interp *interp
+.AS Tcl_Interp boolValue in/out
.AP int boolValue in
-Integer value used to initialize or set a boolean object.
-If the integer is nonzero, the boolean object is set to 1;
-otherwise the boolean object is set to 0.
+Integer value to be stored as a boolean value in a Tcl_Obj.
.AP Tcl_Obj *objPtr in/out
-For \fBTcl_SetBooleanObj\fR, this points to the object to be converted
-to boolean type.
-For \fBTcl_GetBooleanFromObj\fR, this refers to the object
-from which to get a boolean value;
-if \fIobjPtr\fR does not already point to a boolean object,
-an attempt will be made to convert it to one.
+Points to the Tcl_Obj in which to store, or from which to
+retrieve a boolean value.
.AP Tcl_Interp *interp in/out
-If an error occurs during conversion,
+If a boolean value cannot be retrieved,
an error message is left in the interpreter's result object
unless \fIinterp\fR is NULL.
.AP int *boolPtr out
@@ -44,44 +39,57 @@ stores the boolean value (0 or 1) obtained from \fIobjPtr\fR.
.SH DESCRIPTION
.PP
-These procedures are used to create, modify, and read
-boolean Tcl objects from C code.
-\fBTcl_NewBooleanObj\fR and \fBTcl_SetBooleanObj\fR
-will create a new object of boolean type
-or modify an existing object to have boolean type.
-Both of these procedures set the object to have the
-boolean value (0 or 1) specified by \fIboolValue\fR;
-if \fIboolValue\fR is nonzero, the object is set to 1,
-otherwise to 0.
-\fBTcl_NewBooleanObj\fR returns a pointer to a newly created object
-with reference count zero.
-Both procedures set the object's type to be boolean
-and assign the boolean value to the object's internal representation
-\fIlongValue\fR member.
-\fBTcl_SetBooleanObj\fR invalidates any old string representation
-and, if the object is not already a boolean object,
-frees any old internal representation.
+These procedures are used to pass boolean values to and from
+Tcl as Tcl_Obj's. When storing a boolean value into a Tcl_Obj,
+any non-zero integer value in \fIboolValue\fR is taken to be
+the boolean value \fB1\fR, and the integer value \fB0\fR is
+taken to be the boolean value \fB0\fR.
.PP
-\fBTcl_GetBooleanFromObj\fR attempts to return a boolean value
-from the Tcl object \fIobjPtr\fR.
-If the object is not already a boolean object,
-it will attempt to convert it to one.
-If an error occurs during conversion, it returns \fBTCL_ERROR\fR
-and leaves an error message in the interpreter's result object
-unless \fIinterp\fR is NULL.
-Otherwise, \fBTcl_GetBooleanFromObj\fR returns \fBTCL_OK\fR
-and stores the boolean value in the address given by \fIboolPtr\fR.
-If the object is not already a boolean object,
-the conversion will free any old internal representation.
-Objects having a string representation equal to any of \fB0\fR,
-\fBfalse\fR, \fBno\fR, or \fBoff\fR have a boolean value 0; if the
-string representation is any of \fB1\fR, \fBtrue\fR, \fByes\fR, or
-\fBon\fR the boolean value is 1.
-Any of these string values may be abbreviated, and upper-case spellings
-are also acceptable.
+\fBTcl_NewBooleanObj\fR creates a new Tcl_Obj, stores the boolean
+value \fIboolValue\fR in it, and returns a pointer to the new Tcl_Obj.
+The new Tcl_Obj has reference count of zero.
+.PP
+\fBTcl_SetBooleanObj\fR accepts \fIobjPtr\fR, a pointer to
+an existing Tcl_Obj, and stores in the Tcl_Obj \fI*objPtr\fR
+the boolean value \fIboolValue\fR. This is a write operation
+on \fI*objPtr\fR, so \fIobjPtr\fR must be unshared. Attempts to
+write to a shared Tcl_Obj will panic. A successful write
+of \fIboolValue\fR into \fI*objPtr\fR implies the freeing of
+any former value stored in \fI*objPtr\fR.
+.PP
+\fBTcl_GetBooleanFromObj\fR attempts to retrieve a boolean value
+from the value stored in \fI*objPtr\fR.
+If \fIobjPtr\fR holds a string value recognized by \fBTcl_GetBoolean\fR,
+then the recognized boolean value is written at the address given
+by \fIboolPtr\fR.
+If \fIobjPtr\fR holds any value recognized as
+a number by Tcl, then if that value is zero a 0 is written at
+the address given by \fIboolPtr\fR and if that
+value is non-zero a 1 is written at the address given by \fIboolPtr\fR.
+In all cases where a value is written at the address given
+by \fIboolPtr\fR, \fBTcl_GetBooleanFromObj\fR returns \fBTCL_OK\fR.
+If the value of \fIobjPtr\fR does not meet any of the conditions
+above, then \fBTCL_ERROR\fR is returned and an error message is
+left in the interpreter's result unless \fIinterp\fR is NULL.
+\fBTcl_GetBooleanFromObj\fR may also make changes to the internal
+fields of \fI*objPtr\fR so that future calls to
+\fBTcl_GetBooleanFromObj\fR on the same \fIobjPtr\fR can be
+performed more efficiently.
+.PP
+Note that the routines \fBTcl_GetBooleanFromObj\fR and
+\fBTcl_GetBoolean\fR are not functional equivalents.
+The set of values for which \fBTcl_GetBooleanFromObj\fR
+will return \fBTCL_OK\fR is strictly larger than
+the set of values for which \fBTcl_GetBoolean\fR will do the same.
+For example, the value
+.QW 5
+passed to \fBTcl_GetBooleanFromObj\fR
+will lead to a \fBTCL_OK\fR return (and the boolean value 1),
+while the same value passed to \fBTcl_GetBoolean\fR will lead to
+a \fBTCL_ERROR\fR return.
.SH "SEE ALSO"
-Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_GetObjResult
+Tcl_NewObj, Tcl_IsShared, Tcl_GetBoolean
.SH KEYWORDS
-boolean, boolean object, boolean type, internal representation, object, object type, string representation
+boolean, object
diff --git a/doc/ByteArrObj.3 b/doc/ByteArrObj.3
index 51c4363..738da32 100644
--- a/doc/ByteArrObj.3
+++ b/doc/ByteArrObj.3
@@ -25,8 +25,8 @@ unsigned char *
unsigned char *
\fBTcl_SetByteArrayLength\fR(\fIobjPtr, length\fR)
.SH ARGUMENTS
-.AS "unsigned char" *lengthPtr in/out
-.AP "CONST unsigned char" *bytes in
+.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.
.AP int length in
The length of the array of bytes. It must be >= 0.
@@ -48,7 +48,7 @@ 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.
-Accesser functions are provided to get the string representation of a
+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
\fBTcl_GetStringFromObj\fR) produces a properly formed UTF-8 sequence with a
diff --git a/doc/CallDel.3 b/doc/CallDel.3
index 02bb445..8e6445b 100644
--- a/doc/CallDel.3
+++ b/doc/CallDel.3
@@ -38,8 +38,8 @@ time of the call.
type \fBTcl_InterpDeleteProc\fR:
.CS
typedef void Tcl_InterpDeleteProc(
- ClientData \fIclientData\fR,
- Tcl_Interp *\fIinterp\fR);
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR);
.CE
The \fIclientData\fR and \fIinterp\fR parameters are
copies of the \fIclientData\fR and \fIinterp\fR arguments given
@@ -51,7 +51,7 @@ interpreter is about to go away.
.PP
\fBTcl_DontCallWhenDeleted\fR cancels a previous call to
\fBTcl_CallWhenDeleted\fR with the same arguments, so that
-\fIproc\fR won't be called after all when \fIinterp\fR is
+\fIproc\fR will not be called after all when \fIinterp\fR is
deleted.
If there is no deletion callback that matches \fIinterp\fR,
\fIproc\fR, and \fIclientData\fR then the call to
diff --git a/doc/ChnlStack.3 b/doc/ChnlStack.3
index ebd8d63..8ac5a0d 100644
--- a/doc/ChnlStack.3
+++ b/doc/ChnlStack.3
@@ -8,7 +8,7 @@
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
-Tcl_StackChannel, Tcl_UnstackChannel, Tcl_GetStackedChannel, Tcl_GetTopChannel \- stack an I/O channel on top of another, and undo it
+Tcl_StackChannel, Tcl_UnstackChannel, Tcl_GetStackedChannel, Tcl_GetTopChannel \- manipulate stacked I/O channels
.SH SYNOPSIS
.nf
.nf
@@ -27,17 +27,17 @@ Tcl_Channel
\fBTcl_GetTopChannel\fR(\fIchannel\fR)
.sp
.SH ARGUMENTS
-.AS Tcl_ChannelType
+.AS Tcl_ChannelType clientData
.AP Tcl_Interp *interp in
Interpreter for error reporting.
.AP Tcl_ChannelType *typePtr in
-The new channel I/O procedures to use for \fIchannel\fP.
+The new channel I/O procedures to use for \fIchannel\fR.
.AP ClientData clientData in
Arbitrary one-word value to pass to channel I/O procedures.
.AP int mask in
Conditions under which \fIchannel\fR will be used: OR-ed combination of
\fBTCL_READABLE\fR, \fBTCL_WRITABLE\fR and \fBTCL_EXCEPTION\fR.
-This can be a subset of the operations currently allowed on \fIchannel\fP.
+This can be a subset of the operations currently allowed on \fIchannel\fR.
.AP Tcl_Channel channel in
An existing Tcl channel such as returned by \fBTcl_CreateChannel\fR.
.BE
@@ -55,9 +55,9 @@ stacked channels. Anyone using stacked channels or creating stacked
channel drivers should update to the new \fBTCL_CHANNEL_VERSION_2\fR
\fBTcl_ChannelType\fR structure. See \fBTcl_CreateChannel\fR for details.
.PP
-\fBTcl_StackChannel\fR stacks a new \fIchannel\fP on an existing channel
-with the same name that was registered for \fIchannel\fP by
-\fBTcl_RegisterChannel\fP.
+\fBTcl_StackChannel\fR stacks a new \fIchannel\fR on an existing channel
+with the same name that was registered for \fIchannel\fR by
+\fBTcl_RegisterChannel\fR.
.PP
\fBTcl_StackChannel\fR works by creating a new channel structure and
placing itself on top of the channel stack. EOL translation, encoding and
@@ -68,7 +68,7 @@ remain at the top of the channel stack. A pointer to the new top channel
structure is returned. If an error occurs when stacking the channel, NULL
is returned instead.
.PP
-The \fImask\fP parameter specifies the operations that are allowed on the
+The \fImask\fR parameter specifies the operations that are allowed on the
new channel. These can be a subset of the operations allowed on the
original channel. For example, a read-write channel may become read-only
after the \fBTcl_StackChannel\fR call.
@@ -77,10 +77,10 @@ Closing a channel closes the channels stacked below it. The close of
stacked channels is executed in a way that allows buffered data to be
properly flushed.
.PP
-\fBTcl_UnstackChannel\fP reverses the process. The old channel is
+\fBTcl_UnstackChannel\fR reverses the process. The old channel is
associated with the channel name, and the processing module added by
\fBTcl_StackChannel\fR is destroyed. If there is no old channel, then
-\fBTcl_UnstackChannel\fP is equivalent to \fBTcl_Close\fP. If an error
+\fBTcl_UnstackChannel\fR is equivalent to \fBTcl_Close\fR. If an error
occurs unstacking the channel, \fBTCL_ERROR\fR is returned, otherwise
\fBTCL_OK\fR is returned.
.PP
diff --git a/doc/CmdCmplt.3 b/doc/CmdCmplt.3
index e2a7064..eeae039 100644
--- a/doc/CmdCmplt.3
+++ b/doc/CmdCmplt.3
@@ -17,8 +17,8 @@ Tcl_CommandComplete \- Check for unmatched braces in a Tcl command
int
\fBTcl_CommandComplete\fR(\fIcmd\fR)
.SH ARGUMENTS
-.AS "CONST char" *cmd
-.AP "CONST char" *cmd in
+.AS "const char" *cmd
+.AP "const char" *cmd in
Command string to test for completeness.
.BE
diff --git a/doc/Concat.3 b/doc/Concat.3
index fdb479e..c38bf82 100644
--- a/doc/Concat.3
+++ b/doc/Concat.3
@@ -14,12 +14,13 @@ Tcl_Concat \- concatenate a collection of strings
.nf
\fB#include <tcl.h>\fR
.sp
-CONST char *
+const char *
\fBTcl_Concat\fR(\fIargc, argv\fR)
.SH ARGUMENTS
+.AS "const char *const" argv[]
.AP int argc in
Number of strings.
-.AP "CONST char * CONST" argv[] in
+.AP "const char *const" argv[] in
Array of strings to concatenate. Must have \fIargc\fR entries.
.BE
@@ -41,12 +42,9 @@ copies strings from \fBargv\fR to the result. If an element of
is ignored entirely. This white-space removal was added to make
the output of the \fBconcat\fR command cleaner-looking.
.PP
-.VS
The result string is dynamically allocated
using \fBTcl_Alloc\fR; the caller must eventually release the space
by calling \fBTcl_Free\fR.
-.VE
-.VS
.SH "SEE ALSO"
Tcl_ConcatObj
.SH KEYWORDS
diff --git a/doc/CrtChannel.3 b/doc/CrtChannel.3
index fc034a0..212a239 100644
--- a/doc/CrtChannel.3
+++ b/doc/CrtChannel.3
@@ -9,7 +9,7 @@
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
-Tcl_CreateChannel, Tcl_GetChannelInstanceData, Tcl_GetChannelType, Tcl_GetChannelName, Tcl_GetChannelHandle, Tcl_GetChannelMode, Tcl_GetChannelBufferSize, Tcl_SetChannelBufferSize, Tcl_NotifyChannel, Tcl_BadChannelOption, Tcl_ChannelName, Tcl_ChannelVersion, Tcl_ChannelBlockModeProc, Tcl_ChannelCloseProc, Tcl_ChannelClose2Proc, Tcl_ChannelInputProc, Tcl_ChannelOutputProc, Tcl_ChannelSeekProc, Tcl_ChannelWideSeekProc, Tcl_ChannelSetOptionProc, Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc, Tcl_ChannelGetHandleProc, Tcl_ChannelFlushProc, Tcl_ChannelHandlerProc, Tcl_ChannelThreadActionProc, Tcl_IsChannelShared, Tcl_IsChannelRegistered, Tcl_CutChannel, Tcl_SpliceChannel, Tcl_IsChannelExisting, Tcl_ClearChannelHandlers, Tcl_GetChannelThread, Tcl_ChannelBuffered \- procedures for creating and manipulating channels
+Tcl_CreateChannel, Tcl_GetChannelInstanceData, Tcl_GetChannelType, Tcl_GetChannelName, Tcl_GetChannelHandle, Tcl_GetChannelMode, Tcl_GetChannelBufferSize, Tcl_SetChannelBufferSize, Tcl_NotifyChannel, Tcl_BadChannelOption, Tcl_ChannelName, Tcl_ChannelVersion, Tcl_ChannelBlockModeProc, Tcl_ChannelCloseProc, Tcl_ChannelClose2Proc, Tcl_ChannelInputProc, Tcl_ChannelOutputProc, Tcl_ChannelSeekProc, Tcl_ChannelWideSeekProc, Tcl_ChannelTruncateProc, Tcl_ChannelSetOptionProc, Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc, Tcl_ChannelGetHandleProc, Tcl_ChannelFlushProc, Tcl_ChannelHandlerProc, Tcl_ChannelThreadActionProc, Tcl_IsChannelShared, Tcl_IsChannelRegistered, Tcl_CutChannel, Tcl_SpliceChannel, Tcl_IsChannelExisting, Tcl_ClearChannelHandlers, Tcl_GetChannelThread, Tcl_ChannelBuffered \- procedures for creating and manipulating channels
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -23,16 +23,14 @@ ClientData
Tcl_ChannelType *
\fBTcl_GetChannelType\fR(\fIchannel\fR)
.sp
-CONST char *
+const char *
\fBTcl_GetChannelName\fR(\fIchannel\fR)
.sp
int
\fBTcl_GetChannelHandle\fR(\fIchannel, direction, handlePtr\fR)
.sp
-.VS 8.4
Tcl_ThreadId
\fBTcl_GetChannelThread\fR(\fIchannel\fR)
-.VE 8.4
.sp
int
\fBTcl_GetChannelMode\fR(\fIchannel\fR)
@@ -46,7 +44,6 @@ int
.sp
int
\fBTcl_BadChannelOption\fR(\fIinterp, optionName, optionList\fR)
-.VS 8.4
.sp
int
\fBTcl_IsChannelShared\fR(\fIchannel\fR)
@@ -65,12 +62,11 @@ void
.sp
void
\fBTcl_ClearChannelHandlers\fR(\fIchannel\fR)
-.VE 8.4
.sp
int
\fBTcl_ChannelBuffered\fR(\fIchannel\fR)
.sp
-CONST char *
+const char *
\fBTcl_ChannelName\fR(\fItypePtr\fR)
.sp
Tcl_ChannelTypeVersion
@@ -94,13 +90,16 @@ Tcl_DriverOutputProc *
Tcl_DriverSeekProc *
\fBTcl_ChannelSeekProc\fR(\fItypePtr\fR)
.sp
-.VS 8.4
Tcl_DriverWideSeekProc *
\fBTcl_ChannelWideSeekProc\fR(\fItypePtr\fR)
.sp
Tcl_DriverThreadActionProc *
\fBTcl_ChannelThreadActionProc\fR(\fItypePtr\fR)
-.VE 8.4
+.sp
+.VS 8.5
+Tcl_DriverTruncateProc *
+\fBTcl_ChannelTruncateProc\fR(\fItypePtr\fR)
+.VE 8.5
.sp
Tcl_DriverSetOptionProc *
\fBTcl_ChannelSetOptionProc\fR(\fItypePtr\fR)
@@ -121,11 +120,11 @@ Tcl_DriverHandlerProc *
\fBTcl_ChannelHandlerProc\fR(\fItypePtr\fR)
.sp
.SH ARGUMENTS
-.AS Tcl_ChannelType *channelName in
-.AP Tcl_ChannelType *typePtr in
+.AS "const Tcl_ChannelType" *channelName
+.AP "const Tcl_ChannelType" *typePtr in
Points to a structure containing the addresses of procedures that
can be called to perform I/O and other functions on the channel.
-.AP "CONST char" *channelName in
+.AP "const char" *channelName in
The name of this channel, such as \fBfile3\fR; must not be in use
by any other channel. Can be NULL, in which case the channel is
created without a name.
@@ -151,10 +150,11 @@ and \fBTCL_EXCEPTION\fR that indicates events that have occurred on
this channel.
.AP Tcl_Interp *interp in
Current interpreter. (can be NULL)
-.AP "CONST char" *optionName in
+.AP "const char" *optionName in
Name of the invalid option.
-.AP "CONST char" *optionList in
-Specific options list (space separated words, without "-")
+.AP "const char" *optionList in
+Specific options list (space separated words, without
+.QW \- )
to append to the standard generic options list.
Can be NULL for generic options error message only.
@@ -178,7 +178,7 @@ driver provides a \fBTcl_ChannelType\fR structure containing pointers to
functions implementing the various operations used by the generic layer to
communicate with the channel driver. The \fBTcl_ChannelType\fR structure
and the functions referenced by it are described in the section
-TCL_CHANNELTYPE, below.
+\fBTCL_CHANNELTYPE\fR, below.
.PP
Second, channel drivers usually provide a Tcl command to create
instances of that type of channel. For example, the Tcl \fBopen\fR
@@ -205,7 +205,7 @@ structure to perform operations on the channel.
\fItypePtr\fR and \fIinstanceData\fR with it. The channel is opened in the
mode indicated by \fImask\fR.
For a discussion of channel drivers, their operations and the
-\fBTcl_ChannelType\fR structure, see the section TCL_CHANNELTYPE, below.
+\fBTcl_ChannelType\fR structure, see the section \fBTCL_CHANNELTYPE\fR, below.
.PP
\fBTcl_CreateChannel\fR interacts with the code managing the standard
channels. Once a standard channel was initialized either through a
@@ -237,11 +237,9 @@ then \fBTCL_ERROR\fR is returned instead. Different channel drivers
will return different types of handle. Refer to the manual entries
for each driver to determine what type of handle is returned.
.PP
-.VS 8.4
\fBTcl_GetChannelThread\fR returns the id of the thread currently managing
the specified \fIchannel\fR. This allows channel drivers to send their file
events to the correct event queue even for a multi-threaded core.
-.VE 8.4
.PP
\fBTcl_GetChannelMode\fR returns an OR-ed combination of \fBTCL_READABLE\fR
and \fBTCL_WRITABLE\fR, indicating whether the channel is open for input
@@ -265,15 +263,15 @@ occurred on the channel. Channel drivers are responsible for invoking
this function whenever the channel handlers need to be called for the
channel. See \fBWATCHPROC\fR below for more details.
.PP
-\fBTcl_BadChannelOption\fR is called from driver specific set or get option
-procs to generate a complete error message.
+\fBTcl_BadChannelOption\fR is called from driver specific
+\fIsetOptionProc\fR or \fIgetOptionProc\fR to generate a complete
+error message.
.PP
\fBTcl_ChannelBuffered\fR returns the number of bytes of input
currently buffered in the internal buffer (push back area) of the
channel itself. It does not report about the data in the overall
buffers for the stack of channels the supplied channel is part of.
.PP
-.VS 8.4
\fBTcl_IsChannelShared\fR checks the refcount of the specified
\fIchannel\fR and returns whether the \fIchannel\fR was shared among
multiple interpreters (result == 1) or not (result == 0).
@@ -290,26 +288,24 @@ name is registered in the (thread)-global list of all channels (result
(thread)global list of all channels (of the current thread).
Application to a channel still registered in some interpreter
is not allowed.
-.VS 8.4
+.VS 8.5
Also notifies the driver if the \fBTcl_ChannelType\fR version is
\fBTCL_CHANNEL_VERSION_4\fR (or higher), and
\fBTcl_DriverThreadActionProc\fR is defined for it.
-.VE 8.4
+.VE 8.5
.PP
\fBTcl_SpliceChannel\fR adds the specified \fIchannel\fR to the
(thread)global list of all channels (of the current thread).
Application to a channel registered in some interpreter is not allowed.
-.VS 8.4
+.VS 8.5
Also notifies the driver if the \fBTcl_ChannelType\fR version is
\fBTCL_CHANNEL_VERSION_4\fR (or higher), and
\fBTcl_DriverThreadActionProc\fR is defined for it.
-.VE 8.4
+.VE 8.5
.PP
-\fBTcl_ClearChannelHandlers\fR removes all channelhandlers and event
+\fBTcl_ClearChannelHandlers\fR removes all channel handlers and event
scripts associated with the specified \fIchannel\fR, thus shutting
down all event processing for this channel.
-.VE 8.4
-
.SH TCL_CHANNELTYPE
.PP
A channel driver provides a \fBTcl_ChannelType\fR structure that contains
@@ -322,22 +318,25 @@ details about the old structure.
The \fBTcl_ChannelType\fR structure contains the following fields:
.CS
typedef struct Tcl_ChannelType {
- char *\fItypeName\fR;
- Tcl_ChannelTypeVersion \fIversion\fR;
- Tcl_DriverCloseProc *\fIcloseProc\fR;
- Tcl_DriverInputProc *\fIinputProc\fR;
- Tcl_DriverOutputProc *\fIoutputProc\fR;
- Tcl_DriverSeekProc *\fIseekProc\fR;
- Tcl_DriverSetOptionProc *\fIsetOptionProc\fR;
- Tcl_DriverGetOptionProc *\fIgetOptionProc\fR;
- Tcl_DriverWatchProc *\fIwatchProc\fR;
- Tcl_DriverGetHandleProc *\fIgetHandleProc\fR;
- Tcl_DriverClose2Proc *\fIclose2Proc\fR;
- Tcl_DriverBlockModeProc *\fIblockModeProc\fR;
- Tcl_DriverFlushProc *\fIflushProc\fR;
- Tcl_DriverHandlerProc *\fIhandlerProc\fR;
- Tcl_DriverWideSeekProc *\fIwideSeekProc\fR;
- Tcl_DriverThreadActionProc *\fIthreadActionProc\fR;
+ char *\fItypeName\fR;
+ Tcl_ChannelTypeVersion \fIversion\fR;
+ Tcl_DriverCloseProc *\fIcloseProc\fR;
+ Tcl_DriverInputProc *\fIinputProc\fR;
+ Tcl_DriverOutputProc *\fIoutputProc\fR;
+ Tcl_DriverSeekProc *\fIseekProc\fR;
+ Tcl_DriverSetOptionProc *\fIsetOptionProc\fR;
+ Tcl_DriverGetOptionProc *\fIgetOptionProc\fR;
+ Tcl_DriverWatchProc *\fIwatchProc\fR;
+ Tcl_DriverGetHandleProc *\fIgetHandleProc\fR;
+ Tcl_DriverClose2Proc *\fIclose2Proc\fR;
+ Tcl_DriverBlockModeProc *\fIblockModeProc\fR;
+ Tcl_DriverFlushProc *\fIflushProc\fR;
+ Tcl_DriverHandlerProc *\fIhandlerProc\fR;
+ Tcl_DriverWideSeekProc *\fIwideSeekProc\fR;
+ Tcl_DriverThreadActionProc *\fIthreadActionProc\fR;
+.VS 8.5
+ Tcl_DriverTruncateProc *\fItruncateProc\fR;
+.VE 8.5
} Tcl_ChannelType;
.CE
.PP
@@ -345,11 +344,11 @@ It is not necessary to provide implementations for all channel
operations. Those which are not necessary may be set to NULL in the
struct: \fIblockModeProc\fR, \fIseekProc\fR, \fIsetOptionProc\fR,
\fIgetOptionProc\fR, and \fIclose2Proc\fR, in addition to
-\fIflushProc\fR, \fIhandlerProc\fR, and \fIthreadActionProc\fR. Other
-functions that cannot be implemented in a meaningful way should return
-\fBEINVAL\fR when called, to indicate that the operations they
-represent are not available. Also note that \fIwideSeekProc\fR can be
-NULL if \fIseekProc\fR is.
+\fIflushProc\fR, \fIhandlerProc\fR, \fIthreadActionProc\fR, and
+\fItruncateProc\fR. Other functions that cannot be implemented in a
+meaningful way should return \fBEINVAL\fR when called, to indicate
+that the operations they represent are not available. Also note that
+\fIwideSeekProc\fR can be NULL if \fIseekProc\fR is.
.PP
The user should only use the above structure for \fBTcl_ChannelType\fR
instantiation. When referencing fields in a \fBTcl_ChannelType\fR
@@ -358,20 +357,19 @@ structure, the following functions should be used to obtain the values:
\fBTcl_ChannelBlockModeProc\fR, \fBTcl_ChannelCloseProc\fR,
\fBTcl_ChannelClose2Proc\fR, \fBTcl_ChannelInputProc\fR,
\fBTcl_ChannelOutputProc\fR, \fBTcl_ChannelSeekProc\fR,
-.VS 8.4
-\fBTcl_ChannelWideSeekProc\fR,
-\fBTcl_ChannelThreadActionProc\fR,
-.VE 8.4
+\fBTcl_ChannelWideSeekProc\fR, \fBTcl_ChannelThreadActionProc\fR,
+.VS 8.5
+\fBTcl_ChannelTruncateProc\fR,
+.VE 8.5
\fBTcl_ChannelSetOptionProc\fR, \fBTcl_ChannelGetOptionProc\fR,
\fBTcl_ChannelWatchProc\fR, \fBTcl_ChannelGetHandleProc\fR,
\fBTcl_ChannelFlushProc\fR, or \fBTcl_ChannelHandlerProc\fR.
.PP
The change to the structures was made in such a way that standard channel
types are binary compatible. However, channel types that use stacked
-channels (ie: TLS, Trf) have new versions to correspond to the above change
+channels (i.e. TLS, Trf) have new versions to correspond to the above change
since the previous code for stacked channels had problems.
-
-.SH TYPENAME
+.SS TYPENAME
.PP
The \fItypeName\fR field contains a null-terminated string that
identifies the type of the device implemented by this driver, e.g.
@@ -379,19 +377,19 @@ identifies the type of the device implemented by this driver, e.g.
.PP
This value can be retrieved with \fBTcl_ChannelName\fR, which returns
a pointer to the string.
-
-.SH VERSION
+.SS VERSION
.PP
The \fIversion\fR field should be set to the version of the structure
that you require. \fBTCL_CHANNEL_VERSION_2\fR is the minimum recommended.
-.VS 8.4
-\fBTCL_CHANNEL_VERSION_3\fR must be set to specifiy the \fIwideSeekProc\fR member.
-.VE 8.4
-.VS 8.4
-\fBTCL_CHANNEL_VERSION_4\fR must be set to specifiy the
-\fIthreadActionProc\fR member (includes \fIwideSeekProc\fR).
-.VE 8.4
+\fBTCL_CHANNEL_VERSION_3\fR must be set to specify the \fIwideSeekProc\fR member.
+\fBTCL_CHANNEL_VERSION_4\fR must be set to specify the \fIthreadActionProc\fR member
+(includes \fIwideSeekProc\fR).
+.VS 8.5
+\fBTCL_CHANNEL_VERSION_5\fR must be set to specify the
+\fItruncateProc\fR members (includes
+\fIwideSeekProc\fR and \fIthreadActionProc\fR).
+.VE 8.5
If it is not set to any of these, then this
\fBTcl_ChannelType\fR is assumed to have the original structure. See
\fBOLD CHANNEL TYPES\fR for more details. While Tcl will recognize
@@ -399,12 +397,14 @@ and function with either structures, stacked channels must be of at
least \fBTCL_CHANNEL_VERSION_2\fR to function correctly.
.PP
This value can be retrieved with \fBTcl_ChannelVersion\fR, which returns
-.VS 8.4
-one of \fBTCL_CHANNEL_VERSION_4\fR, \fBTCL_CHANNEL_VERSION_3\fR,
-.VE 8.4
-\fBTCL_CHANNEL_VERSION_2\fR, or \fBTCL_CHANNEL_VERSION_1\fR.
-
-.SH BLOCKMODEPROC
+one of
+.VS 8.5
+\fBTCL_CHANNEL_VERSION_5\fR,
+.VE 8.5
+\fBTCL_CHANNEL_VERSION_4\fR,
+\fBTCL_CHANNEL_VERSION_3\fR,
+\fBTCL_CHANNEL_VERSION_2\fR or \fBTCL_CHANNEL_VERSION_1\fR.
+.SS BLOCKMODEPROC
.PP
The \fIblockModeProc\fR field contains the address of a function called by
the generic layer to set blocking and nonblocking mode on the device.
@@ -412,8 +412,8 @@ the generic layer to set blocking and nonblocking mode on the device.
.PP
.CS
typedef int Tcl_DriverBlockModeProc(
- ClientData \fIinstanceData\fR,
- int \fImode\fR);
+ ClientData \fIinstanceData\fR,
+ int \fImode\fR);
.CE
.PP
The \fIinstanceData\fR is the same as the value passed to
@@ -437,11 +437,9 @@ A channel driver \fBnot\fR supplying a \fIblockModeProc\fR has to be
very, very careful. It has to tell the generic layer exactly which
blocking mode is acceptable to it, and should this also document for
the user so that the blocking mode of the channel is not changed to an
-inacceptable value. Any confusion here may lead the interpreter into a
+unacceptable value. Any confusion here may lead the interpreter into a
(spurious and difficult to find) deadlock.
-
-
-.SH "CLOSEPROC AND CLOSE2PROC"
+.SS "CLOSEPROC AND CLOSE2PROC"
.PP
The \fIcloseProc\fR field contains the address of a function called by the
generic layer to clean up driver-related information when the channel is
@@ -449,8 +447,8 @@ closed. \fICloseProc\fR must match the following prototype:
.PP
.CS
typedef int Tcl_DriverCloseProc(
- ClientData \fIinstanceData\fR,
- Tcl_Interp *\fIinterp\fR);
+ ClientData \fIinstanceData\fR,
+ Tcl_Interp *\fIinterp\fR);
.CE
.PP
The \fIinstanceData\fR argument is the same as the value provided to
@@ -471,9 +469,9 @@ following prototype:
.PP
.CS
typedef int Tcl_DriverClose2Proc(
- ClientData \fIinstanceData\fR,
- Tcl_Interp *\fIinterp\fR,
- int \fIflags\fR);
+ ClientData \fIinstanceData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ int \fIflags\fR);
.CE
.PP
The \fIclose2Proc\fR will be called with \fIflags\fR set to an OR'ed
@@ -491,11 +489,10 @@ return a nonzero POSIX error code. In addition, if an error occurs and
\fIinterp\fR is not NULL, the procedure should store an error message
in the interpreter's result.
.PP
-These value can be retrieved with \fBTcl_ChannelCloseProc\fR or
-\fBTcl_ChannelClose2Proc\fR, which returns a pointer to the respective
-function.
-
-.SH INPUTPROC
+The \fIcloseProc\fR and \fIclose2Proc\fR values can be retrieved with
+\fBTcl_ChannelCloseProc\fR or \fBTcl_ChannelClose2Proc\fR, which
+return a pointer to the respective function.
+.SS INPUTPROC
.PP
The \fIinputProc\fR field contains the address of a function called by the
generic layer to read data from the file or device and store it in an
@@ -503,10 +500,10 @@ internal buffer. \fIInputProc\fR must match the following prototype:
.PP
.CS
typedef int Tcl_DriverInputProc(
- ClientData \fIinstanceData\fR,
- char *\fIbuf\fR,
- int \fIbufSize\fR,
- int *\fIerrorCodePtr\fR);
+ ClientData \fIinstanceData\fR,
+ char *\fIbuf\fR,
+ int \fIbufSize\fR,
+ int *\fIerrorCodePtr\fR);
.CE
.PP
\fIInstanceData\fR is the same as the value passed to
@@ -539,8 +536,7 @@ blocking.
.PP
This value can be retrieved with \fBTcl_ChannelInputProc\fR, which returns
a pointer to the function.
-
-.SH OUTPUTPROC
+.SS OUTPUTPROC
.PP
The \fIoutputProc\fR field contains the address of a function called by the
generic layer to transfer data from an internal buffer to the output device.
@@ -548,10 +544,10 @@ generic layer to transfer data from an internal buffer to the output device.
.PP
.CS
typedef int Tcl_DriverOutputProc(
- ClientData \fIinstanceData\fR,
- CONST char *\fIbuf\fR,
- int \fItoWrite\fR,
- int *\fIerrorCodePtr\fR);
+ ClientData \fIinstanceData\fR,
+ const char *\fIbuf\fR,
+ int \fItoWrite\fR,
+ int *\fIerrorCodePtr\fR);
.CE
.PP
\fIInstanceData\fR is the same as the value passed to
@@ -578,8 +574,7 @@ without writing any data.
.PP
This value can be retrieved with \fBTcl_ChannelOutputProc\fR, which returns
a pointer to the function.
-
-.SH "SEEKPROC AND WIDESEEKPROC"
+.SS "SEEKPROC AND WIDESEEKPROC"
.PP
The \fIseekProc\fR field contains the address of a function called by the
generic layer to move the access point at which subsequent input or output
@@ -588,10 +583,10 @@ prototype:
.PP
.CS
typedef int Tcl_DriverSeekProc(
- ClientData \fIinstanceData\fR,
- long \fIoffset\fR,
- int \fIseekMode\fR,
- int *\fIerrorCodePtr\fR);
+ ClientData \fIinstanceData\fR,
+ long \fIoffset\fR,
+ int \fIseekMode\fR,
+ int *\fIerrorCodePtr\fR);
.CE
.PP
The \fIinstanceData\fR argument is the same as the value given to
@@ -608,7 +603,6 @@ does not implement seeking.
The return value is the new access point or -1 in case of error. If an
error occurred, the function should not move the access point.
.PP
-.VS 8.4
If there is a non-NULL \fIseekProc\fR field, the \fIwideSeekProc\fR
field may contain the address of an alternative function to use which
handles wide (i.e. larger than 32-bit) offsets, so allowing seeks
@@ -619,10 +613,10 @@ following prototype:
.PP
.CS
typedef Tcl_WideInt Tcl_DriverWideSeekProc(
- ClientData \fIinstanceData\fR,
- Tcl_WideInt \fIoffset\fR,
- int \fIseekMode\fR,
- int *\fIerrorCodePtr\fR);
+ ClientData \fIinstanceData\fR,
+ Tcl_WideInt \fIoffset\fR,
+ int \fIseekMode\fR,
+ int *\fIerrorCodePtr\fR);
.CE
.PP
The arguments and return values mean the same thing as with
@@ -633,9 +627,7 @@ The \fIseekProc\fR value can be retrieved with
\fBTcl_ChannelSeekProc\fR, which returns a pointer to the function,
and similarly the \fIwideSeekProc\fR can be retrieved with
\fBTcl_ChannelWideSeekProc\fR.
-.VE 8.4
-
-.SH SETOPTIONPROC
+.SS SETOPTIONPROC
.PP
The \fIsetOptionProc\fR field contains the address of a function called by
the generic layer to set a channel type specific option on a channel.
@@ -643,10 +635,10 @@ the generic layer to set a channel type specific option on a channel.
.PP
.CS
typedef int Tcl_DriverSetOptionProc(
- ClientData \fIinstanceData\fR,
- Tcl_Interp *\fIinterp\fR,
- CONST char *\fIoptionName\fR,
- CONST char *\fInewValue\fR);
+ ClientData \fIinstanceData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ const char *\fIoptionName\fR,
+ const char *\fInewValue\fR);
.CE
.PP
\fIoptionName\fR is the name of an option to set, and \fInewValue\fR is
@@ -656,7 +648,7 @@ created. The function should do whatever channel type specific action is
required to implement the new value of the option.
.PP
Some options are handled by the generic code and this function is never
-called to set them, e.g. \fB-blockmode\fR. Other options are specific to
+called to set them, e.g. \fB\-blockmode\fR. Other options are specific to
each channel type and the \fIsetOptionProc\fR procedure of the channel
driver will get called to implement them. The \fIsetOptionProc\fR field can
be NULL, which indicates that this channel type supports no type specific
@@ -676,8 +668,7 @@ error code.
.PP
This value can be retrieved with \fBTcl_ChannelSetOptionProc\fR, which returns
a pointer to the function.
-
-.SH GETOPTIONPROC
+.SS GETOPTIONPROC
.PP
The \fIgetOptionProc\fR field contains the address of a function called by
the generic layer to get the value of a channel type specific option on a
@@ -685,10 +676,10 @@ channel. \fIgetOptionProc\fR must match the following prototype:
.PP
.CS
typedef int Tcl_DriverGetOptionProc(
- ClientData \fIinstanceData\fR,
- Tcl_Interp *\fIinterp\fR,
- CONST char *\fIoptionName\fR,
- Tcl_DString *\fIoptionValue\fR);
+ ClientData \fIinstanceData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ const char *\fIoptionName\fR,
+ Tcl_DString *\fIoptionValue\fR);
.CE
.PP
\fIOptionName\fR is the name of an option supported by this type of
@@ -706,7 +697,7 @@ function should also call \fBTcl_SetErrno\fR to store an appropriate POSIX
error code.
.PP
Some options are handled by the generic code and this function is never
-called to retrieve their value, e.g. \fB-blockmode\fR. Other options are
+called to retrieve their value, e.g. \fB\-blockmode\fR. Other options are
specific to each channel type and the \fIgetOptionProc\fR procedure of the
channel driver will get called to implement them. The \fIgetOptionProc\fR
field can be NULL, which indicates that this channel type supports no type
@@ -714,8 +705,7 @@ specific options.
.PP
This value can be retrieved with \fBTcl_ChannelGetOptionProc\fR, which returns
a pointer to the function.
-
-.SH WATCHPROC
+.SS WATCHPROC
.PP
The \fIwatchProc\fR field contains the address of a function called
by the generic layer to initialize the event notification mechanism to
@@ -724,8 +714,8 @@ notice events of interest on this channel.
.PP
.CS
typedef void Tcl_DriverWatchProc(
- ClientData \fIinstanceData\fR,
- int \fImask\fR);
+ ClientData \fIinstanceData\fR,
+ int \fImask\fR);
.CE
.PP
The \fIinstanceData\fR is the same as the value passed to
@@ -747,8 +737,7 @@ details on how to queue an event.
.PP
This value can be retrieved with \fBTcl_ChannelWatchProc\fR, which returns
a pointer to the function.
-
-.SH GETHANDLEPROC
+.SS GETHANDLEPROC
.PP
The \fIgetHandleProc\fR field contains the address of a function called by
the generic layer to retrieve a device-specific handle from the channel.
@@ -756,9 +745,9 @@ the generic layer to retrieve a device-specific handle from the channel.
.PP
.CS
typedef int Tcl_DriverGetHandleProc(
- ClientData \fIinstanceData\fR,
- int \fIdirection\fR,
- ClientData *\fIhandlePtr\fR);
+ ClientData \fIinstanceData\fR,
+ int \fIdirection\fR,
+ ClientData *\fIhandlePtr\fR);
.CE
.PP
\fIInstanceData\fR is the same as the value passed to
@@ -777,8 +766,7 @@ device handles, the function should return \fBTCL_ERROR\fR.
.PP
This value can be retrieved with \fBTcl_ChannelGetHandleProc\fR, which returns
a pointer to the function.
-
-.SH FLUSHPROC
+.SS FLUSHPROC
.PP
The \fIflushProc\fR field is currently reserved for future use.
It should be set to NULL.
@@ -786,13 +774,12 @@ It should be set to NULL.
.PP
.CS
typedef int Tcl_DriverFlushProc(
- ClientData \fIinstanceData\fR);
+ ClientData \fIinstanceData\fR);
.CE
.PP
This value can be retrieved with \fBTcl_ChannelFlushProc\fR, which returns
a pointer to the function.
-
-.SH HANDLERPROC
+.SS HANDLERPROC
.PP
The \fIhandlerProc\fR field contains the address of a function called by
the generic layer to notify the channel that an event occurred. It should
@@ -802,8 +789,8 @@ that occur on the underlying (stacked) channel.
.PP
.CS
typedef int Tcl_DriverHandlerProc(
- ClientData \fIinstanceData\fR,
- int \fIinterestMask\fR);
+ ClientData \fIinstanceData\fR,
+ int \fIinterestMask\fR);
.CE
.PP
\fIInstanceData\fR is the same as the value passed to \fBTcl_CreateChannel\fR
@@ -814,8 +801,7 @@ type of event occurred on this channel.
This value can be retrieved with \fBTcl_ChannelHandlerProc\fR, which returns
a pointer to the function.
-.VS 8.4
-.SH "THREADACTIONPROC"
+.SS "THREADACTIONPROC"
.PP
The \fIthreadActionProc\fR field contains the address of the function
called by the generic layer when a channel is created, closed, or
@@ -832,8 +818,8 @@ might be maintaining using the calling thread as the associate. See
.PP
.CS
typedef void Tcl_DriverThreadActionProc(
- ClientData \fIinstanceData\fR,
- int \fIaction\fR);
+ ClientData \fIinstanceData\fR,
+ int \fIaction\fR);
.CE
.PP
\fIInstanceData\fR is the same as the value passed to
@@ -841,53 +827,79 @@ typedef void Tcl_DriverThreadActionProc(
.PP
These values can be retrieved with \fBTcl_ChannelThreadActionProc\fR,
which returns a pointer to the function.
-.VE 8.4
-
+.SS "TRUNCATEPROC"
+.PP
+The \fItruncateProc\fR field contains the address of the function
+called by the generic layer when a channel is truncated to some
+length. It can be NULL.
+.PP
+.CS
+typedef int Tcl_DriverTruncateProc(
+ ClientData \fIinstanceData\fR,
+ Tcl_WideInt \fIlength\fR);
+.CE
+.PP
+\fIInstanceData\fR is the same as the value passed to
+\fBTcl_CreateChannel\fR when this channel was created, and
+\fIlength\fR is the new length of the underlying file, which should
+not be negative. The result should be 0 on success or an errno code
+(suitable for use with \fBTcl_SetErrno\fR) on failure.
+.PP
+These values can be retrieved with \fBTcl_ChannelTruncateProc\fR,
+which returns a pointer to the function.
.SH TCL_BADCHANNELOPTION
.PP
-This procedure generates a "bad option" error message in an
+This procedure generates a
+.QW "bad option"
+error message in an
(optional) interpreter. It is used by channel drivers when
-a invalid Set/Get option is requested. Its purpose is to concatenate
+an invalid Set/Get option is requested. Its purpose is to concatenate
the generic options list to the specific ones and factorize
the generic options error message string.
.PP
-It always return \fBTCL_ERROR\fR
+It always returns \fBTCL_ERROR\fR
.PP
An error message is generated in \fIinterp\fR's result object to
-indicate that a command was invoked with the a bad option
+indicate that a command was invoked with a bad option.
The message has the form
.CS
bad option "blah": should be one of
<...generic options...>+<...specific options...>
+.CE
so you get for instance:
+.CS
bad option "-blah": should be one of -blocking,
-buffering, -buffersize, -eofchar, -translation,
-peername, or -sockname
-when called with \fIoptionList\fR="peername sockname"
.CE
-``blah'' is the \fIoptionName\fR argument and ``<specific options>''
+when called with \fIoptionList\fR equal to
+.QW "peername sockname"
+.PP
+.QW blah
+is the \fIoptionName\fR argument and
+.QW "<specific options>"
is a space separated list of specific option words.
The function takes good care of inserting minus signs before
-each option, commas after, and an ``or'' before the last option.
-
+each option, commas after, and an
+.QW or
+before the last option.
.SH "OLD CHANNEL TYPES"
-
The original (8.3.1 and below) \fBTcl_ChannelType\fR structure contains
the following fields:
.PP
.CS
typedef struct Tcl_ChannelType {
- char *\fItypeName\fR;
- Tcl_DriverBlockModeProc *\fIblockModeProc\fR;
- Tcl_DriverCloseProc *\fIcloseProc\fR;
- Tcl_DriverInputProc *\fIinputProc\fR;
- Tcl_DriverOutputProc *\fIoutputProc\fR;
- Tcl_DriverSeekProc *\fIseekProc\fR;
- Tcl_DriverSetOptionProc *\fIsetOptionProc\fR;
- Tcl_DriverGetOptionProc *\fIgetOptionProc\fR;
- Tcl_DriverWatchProc *\fIwatchProc\fR;
- Tcl_DriverGetHandleProc *\fIgetHandleProc\fR;
- Tcl_DriverClose2Proc *\fIclose2Proc\fR;
+ char *\fItypeName\fR;
+ Tcl_DriverBlockModeProc *\fIblockModeProc\fR;
+ Tcl_DriverCloseProc *\fIcloseProc\fR;
+ Tcl_DriverInputProc *\fIinputProc\fR;
+ Tcl_DriverOutputProc *\fIoutputProc\fR;
+ Tcl_DriverSeekProc *\fIseekProc\fR;
+ Tcl_DriverSetOptionProc *\fIsetOptionProc\fR;
+ Tcl_DriverGetOptionProc *\fIgetOptionProc\fR;
+ Tcl_DriverWatchProc *\fIwatchProc\fR;
+ Tcl_DriverGetHandleProc *\fIgetHandleProc\fR;
+ Tcl_DriverClose2Proc *\fIclose2Proc\fR;
} Tcl_ChannelType;
.CE
.PP
@@ -897,33 +909,32 @@ the new \fBTcl_ChannelType\fR structure if you are creating a stacked
channel driver, due to problems with the earlier stacked channel
implementation (in 8.2.0 to 8.3.1).
.PP
-.VS 8.4
Prior to 8.4.0 (i.e. during the later releases of 8.3 and early part
of the 8.4 development cycle) the \fBTcl_ChannelType\fR structure
contained the following fields:
.PP
.CS
typedef struct Tcl_ChannelType {
- char *\fItypeName\fR;
- Tcl_ChannelTypeVersion \fIversion\fR;
- Tcl_DriverCloseProc *\fIcloseProc\fR;
- Tcl_DriverInputProc *\fIinputProc\fR;
- Tcl_DriverOutputProc *\fIoutputProc\fR;
- Tcl_DriverSeekProc *\fIseekProc\fR;
- Tcl_DriverSetOptionProc *\fIsetOptionProc\fR;
- Tcl_DriverGetOptionProc *\fIgetOptionProc\fR;
- Tcl_DriverWatchProc *\fIwatchProc\fR;
- Tcl_DriverGetHandleProc *\fIgetHandleProc\fR;
- Tcl_DriverClose2Proc *\fIclose2Proc\fR;
- Tcl_DriverBlockModeProc *\fIblockModeProc\fR;
- Tcl_DriverFlushProc *\fIflushProc\fR;
- Tcl_DriverHandlerProc *\fIhandlerProc\fR;
+ char *\fItypeName\fR;
+ Tcl_ChannelTypeVersion \fIversion\fR;
+ Tcl_DriverCloseProc *\fIcloseProc\fR;
+ Tcl_DriverInputProc *\fIinputProc\fR;
+ Tcl_DriverOutputProc *\fIoutputProc\fR;
+ Tcl_DriverSeekProc *\fIseekProc\fR;
+ Tcl_DriverSetOptionProc *\fIsetOptionProc\fR;
+ Tcl_DriverGetOptionProc *\fIgetOptionProc\fR;
+ Tcl_DriverWatchProc *\fIwatchProc\fR;
+ Tcl_DriverGetHandleProc *\fIgetHandleProc\fR;
+ Tcl_DriverClose2Proc *\fIclose2Proc\fR;
+ Tcl_DriverBlockModeProc *\fIblockModeProc\fR;
+ Tcl_DriverFlushProc *\fIflushProc\fR;
+ Tcl_DriverHandlerProc *\fIhandlerProc\fR;
+ Tcl_DriverTruncateProc *\fItruncateProc\fR;
} Tcl_ChannelType;
.CE
.PP
When the above structure is registered as a channel type, the
\fIversion\fR field should always be \fBTCL_CHANNEL_VERSION_2\fR.
-.VE 8.4
.SH "SEE ALSO"
Tcl_Close(3), Tcl_OpenFileChannel(3), Tcl_SetErrno(3), Tcl_QueueEvent(3), Tcl_StackChannel(3), Tcl_GetStdChannel(3)
diff --git a/doc/CrtChnlHdlr.3 b/doc/CrtChnlHdlr.3
index ea07ef2..f5fd1bd 100644
--- a/doc/CrtChnlHdlr.3
+++ b/doc/CrtChnlHdlr.3
@@ -48,8 +48,8 @@ what it means for a channel to be readable or writable.
\fIProc\fR must conform to the following prototype:
.CS
typedef void Tcl_ChannelProc(
- ClientData \fIclientData\fR,
- int \fImask\fR);
+ ClientData \fIclientData\fR,
+ int \fImask\fR);
.CE
.PP
The \fIclientData\fR argument is the same as the value passed to
@@ -62,7 +62,7 @@ contain a subset of the bits from the \fImask\fR argument to
.PP
Each channel handler is identified by a unique combination of \fIchannel\fR,
\fIproc\fR and \fIclientData\fR.
-There may be many handlers for a given channel as long as they don't
+There may be many handlers for a given channel as long as they do not
have the same \fIchannel\fR, \fIproc\fR, and \fIclientData\fR.
If \fBTcl_CreateChannelHandler\fR is invoked when there is already a handler
for \fIchannel\fR, \fIproc\fR, and \fIclientData\fR, then no new
diff --git a/doc/CrtCloseHdlr.3 b/doc/CrtCloseHdlr.3
index 35f8261..c8804b1 100644
--- a/doc/CrtCloseHdlr.3
+++ b/doc/CrtCloseHdlr.3
@@ -21,7 +21,7 @@ void
\fBTcl_DeleteCloseHandler\fR(\fIchannel, proc, clientData\fR)
.sp
.SH ARGUMENTS
-.AS Tcl_CloseProc callbackData in
+.AS Tcl_CloseProc clientData
.AP Tcl_Channel channel in
The channel for which to create or delete a close callback.
.AP Tcl_CloseProc *proc in
@@ -39,7 +39,7 @@ Arbitrary one-word value to pass to \fIproc\fR.
.PP
.CS
typedef void Tcl_CloseProc(
- ClientData \fIclientData\fR);
+ ClientData \fIclientData\fR);
.CE
.PP
The \fIclientData\fR is the same as the value provided in the call to
diff --git a/doc/CrtCommand.3 b/doc/CrtCommand.3
index da0da22..fcc04d5 100644
--- a/doc/CrtCommand.3
+++ b/doc/CrtCommand.3
@@ -17,12 +17,10 @@ Tcl_CreateCommand \- implement new commands in C
Tcl_Command
\fBTcl_CreateCommand\fR(\fIinterp, cmdName, proc, clientData, deleteProc\fR)
.SH ARGUMENTS
-.AS Tcl_CmdDeleteProc **deleteProcPtr
+.AS Tcl_CmdDeleteProc *deleteProc
.AP Tcl_Interp *interp in
Interpreter in which to create new command.
-.VS 8.4
-.AP "CONST char" *cmdName in
-.VE
+.AP "const char" *cmdName in
Name of command.
.AP Tcl_CmdProc *proc in
Implementation of new command: \fIproc\fR will be called whenever
@@ -79,10 +77,10 @@ and it returns NULL.
\fBTcl_CmdProc\fR:
.CS
typedef int Tcl_CmdProc(
- ClientData \fIclientData\fR,
- Tcl_Interp *\fIinterp\fR,
- int \fIargc\fR,
- CONST char *\fIargv\fR[]);
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ int \fIargc\fR,
+ const char *\fIargv\fR[]);
.CE
When \fIproc\fR is invoked the \fIclientData\fR and \fIinterp\fR
parameters will be copies of the \fIclientData\fR and \fIinterp\fR
@@ -95,26 +93,23 @@ the command name) and \fIargv\fR giving the values of the arguments
as strings. The \fIargv\fR array will contain \fIargc\fR+1 values;
the first \fIargc\fR values point to the argument strings, and the
last value is NULL.
-.VS
Note that the argument strings should not be modified as they may
point to constant strings or may be shared with other parts of the
interpreter.
-.VE
.PP
-.VS
Note that the argument strings are encoded in normalized UTF-8 since
version 8.1 of Tcl.
-.VE
.PP
-\fIProc\fR must return an integer code that is either \fBTCL_OK\fR, \fBTCL_ERROR\fR,
-\fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or \fBTCL_CONTINUE\fR. See the Tcl overview man page
+\fIProc\fR must return an integer code that is expected to be one of
+\fBTCL_OK\fR, \fBTCL_ERROR\fR, \fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or
+\fBTCL_CONTINUE\fR. See the Tcl overview man page
for details on what these codes mean. Most normal commands will only
return \fBTCL_OK\fR or \fBTCL_ERROR\fR. In addition, \fIproc\fR must set
the interpreter result to point to a string value;
in the case of a \fBTCL_OK\fR return code this gives the result
of the command, and in the case of \fBTCL_ERROR\fR it gives an error message.
The \fBTcl_SetResult\fR procedure provides an easy interface for setting
-the return value; for complete details on how the the interpreter result
+the return value; for complete details on how the interpreter result
field is managed, see the \fBTcl_Interp\fR man page.
Before invoking a command procedure,
\fBTcl_Eval\fR sets the interpreter result to point to an empty string,
@@ -135,11 +130,11 @@ application an opportunity to release any structures associated
with the command. \fIDeleteProc\fR should have arguments and
result that match the type \fBTcl_CmdDeleteProc\fR:
.CS
-typedef void Tcl_CmdDeleteProc(ClientData \fIclientData\fR);
+typedef void Tcl_CmdDeleteProc(
+ ClientData \fIclientData\fR);
.CE
The \fIclientData\fR argument will be the same as the \fIclientData\fR
argument passed to \fBTcl_CreateCommand\fR.
-.PP
.SH "SEE ALSO"
Tcl_CreateObjCommand, Tcl_DeleteCommand, Tcl_GetCommandInfo, Tcl_SetCommandInfo, Tcl_GetCommandName, Tcl_SetObjResult
diff --git a/doc/CrtFileHdlr.3 b/doc/CrtFileHdlr.3
index af21f0b..5627bd4 100644
--- a/doc/CrtFileHdlr.3
+++ b/doc/CrtFileHdlr.3
@@ -13,18 +13,14 @@ Tcl_CreateFileHandler, Tcl_DeleteFileHandler \- associate procedure callbacks wi
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
-.VS
.sp
\fBTcl_CreateFileHandler\fR(\fIfd, mask, proc, clientData\fR)
.sp
\fBTcl_DeleteFileHandler\fR(\fIfd\fR)
-.VE
.SH ARGUMENTS
.AS Tcl_FileProc clientData
-.VS
.AP int fd in
Unix file descriptor for an open file or device.
-.VE
.AP int mask in
Conditions under which \fIproc\fR should be called:
OR-ed combination of \fBTCL_READABLE\fR, \fBTCL_WRITABLE\fR,
@@ -39,12 +35,10 @@ Arbitrary one-word value to pass to \fIproc\fR.
.SH DESCRIPTION
.PP
-.VS
\fBTcl_CreateFileHandler\fR arranges for \fIproc\fR to be
invoked in the future whenever I/O becomes possible on a file
or an exceptional condition exists for the file. The file
is indicated by \fIfd\fR, and the conditions of interest
-.VE
are indicated by \fImask\fR. For example, if \fImask\fR
is \fBTCL_READABLE\fR, \fIproc\fR will be called when
the file is readable.
@@ -57,8 +51,8 @@ as \fBvwait\fR.
type \fBTcl_FileProc\fR:
.CS
typedef void Tcl_FileProc(
- ClientData \fIclientData\fR,
- int \fImask\fR);
+ ClientData \fIclientData\fR,
+ int \fImask\fR);
.CE
The \fIclientData\fR parameter to \fIproc\fR is a copy
of the \fIclientData\fR
@@ -85,14 +79,12 @@ events while waiting for files to become ready for I/O. For this to work
correctly, the application may need to use non-blocking I/O operations on
the files for which handlers are declared. Otherwise the application may
block if it reads or writes too much data; while waiting for the I/O to
-complete the application won't be able to service other events. Use
+complete the application will not be able to service other events. Use
\fBTcl_SetChannelOption\fR with \fB\-blocking\fR to set the channel into
blocking or nonblocking mode as required.
.PP
-.VS
Note that these interfaces are only supported by the Unix
implementation of the Tcl notifier.
-.VE
.SH KEYWORDS
callback, file, handler
diff --git a/doc/CrtMathFnc.3 b/doc/CrtMathFnc.3
index 43ba8fd..9629912 100644
--- a/doc/CrtMathFnc.3
+++ b/doc/CrtMathFnc.3
@@ -17,20 +17,17 @@ Tcl_CreateMathFunc, Tcl_GetMathFuncInfo, Tcl_ListMathFuncs \- Define, query and
void
\fBTcl_CreateMathFunc\fR(\fIinterp, name, numArgs, argTypes, proc, clientData\fR)
.sp
-.VS 8.4
int
-\fBTcl_GetMathFuncInfo\fR(\fIinterp, name, numArgsPtr, argTypesPtr, procPtr, clientDataPtr\fR)
+\fBTcl_GetMathFuncInfo\fR(\fIinterp, name, numArgsPtr, argTypesPtr, procPtr,
+ clientDataPtr\fR)
.sp
Tcl_Obj *
\fBTcl_ListMathFuncs\fR(\fIinterp, pattern\fR)
-.VE
.SH ARGUMENTS
-.AS Tcl_ValueType *clientDataPtr
+.AS Tcl_ValueType *clientDataPtr out
.AP Tcl_Interp *interp in
Interpreter in which new function will be defined.
-.VS 8.4
-.AP "CONST char" *name in
-.VE
+.AP "const char" *name in
Name for new function.
.AP int numArgs in
Number of arguments to new function; also gives size of \fIargTypes\fR array.
@@ -51,12 +48,12 @@ will need to be freed up using \fITcl_Free\fR.
.AP Tcl_MathProc **procPtr out
Points to a variable that will be set to contain a pointer to the
implementation code for the function (or NULL if the function is
-implemented directly in bytecode.)
+implemented directly in bytecode).
.AP ClientData *clientDataPtr out
Points to a variable that will be set to contain the clientData
argument passed to \fITcl_CreateMathFunc\fR when the function was
created if the function is not implemented directly in bytecode.
-.AP "CONST char" *pattern in
+.AP "const char" *pattern in
Pattern to match against function names so as to filter them (by
passing to \fITcl_StringMatch\fR), or NULL to not apply any filter.
.BE
@@ -65,71 +62,70 @@ passing to \fITcl_StringMatch\fR), or NULL to not apply any filter.
.PP
Tcl allows a number of mathematical functions to be used in
expressions, such as \fBsin\fR, \fBcos\fR, and \fBhypot\fR.
-\fBTcl_CreateMathFunc\fR allows applications to add additional functions
+These functions are represented by commands in the namespace,
+\fBtcl::mathfunc\fR. The \fBTcl_CreateMathFunc\fR function is
+an obsolete way for applications to add additional functions
to those already provided by Tcl or to replace existing functions.
+It should not be used by new applications, which should create
+math functions using \fBTcl_CreateObjCommand\fR to create a command
+in the \fBtcl::mathfunc\fR namespace.
+.PP
+In the \fBTcl_CreateMathFunc\fR interface,
\fIName\fR is the name of the function as it will appear in expressions.
-If \fIname\fR doesn't already exist as a function then a new function
-is created. If it does exist, then the existing function is replaced.
+If \fIname\fR does not already exist in the \fB::tcl::mathfunc\fR
+namespace, then a new command is created in that namespace.
+If \fIname\fR does exist, then the existing function is replaced.
\fINumArgs\fR and \fIargTypes\fR describe the arguments to the function.
Each entry in the \fIargTypes\fR array must be
-.VS 8.4
-one of TCL_INT, TCL_DOUBLE, TCL_WIDE_INT,
-or TCL_EITHER to indicate whether the corresponding argument must be an
+one of \fBTCL_INT\fR, \fBTCL_DOUBLE\fR, \fBTCL_WIDE_INT\fR,
+or \fBTCL_EITHER\fR to indicate whether the corresponding argument must be an
integer, a double-precision floating value, a wide (64-bit) integer,
or any, respectively.
-.VE 8.4
.PP
Whenever the function is invoked in an expression Tcl will invoke
\fIproc\fR. \fIProc\fR should have arguments and result that match
the type \fBTcl_MathProc\fR:
.CS
typedef int Tcl_MathProc(
- ClientData \fIclientData\fR,
- Tcl_Interp *\fIinterp\fR,
- Tcl_Value *\fIargs\fR,
- Tcl_Value *\fIresultPtr\fR);
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ Tcl_Value *\fIargs\fR,
+ Tcl_Value *\fIresultPtr\fR);
.CE
.PP
When \fIproc\fR is invoked the \fIclientData\fR and \fIinterp\fR
arguments will be the same as those passed to \fBTcl_CreateMathFunc\fR.
\fIArgs\fR will point to an array of \fInumArgs\fR Tcl_Value structures,
which describe the actual arguments to the function:
-.VS 8.4
.CS
typedef struct Tcl_Value {
- Tcl_ValueType \fItype\fR;
- long \fIintValue\fR;
- double \fIdoubleValue\fR;
- Tcl_WideInt \fIwideValue\fR;
+ Tcl_ValueType \fItype\fR;
+ long \fIintValue\fR;
+ double \fIdoubleValue\fR;
+ Tcl_WideInt \fIwideValue\fR;
} Tcl_Value;
.CE
.PP
The \fItype\fR field indicates the type of the argument and is
-one of TCL_INT, TCL_DOUBLE or TCL_WIDE_INT.
-.VE 8.4
+one of \fBTCL_INT\fR, \fBTCL_DOUBLE\fR or \fBTCL_WIDE_INT\fR.
It will match the \fIargTypes\fR value specified for the function unless
-the \fIargTypes\fR value was TCL_EITHER. Tcl converts
+the \fIargTypes\fR value was \fBTCL_EITHER\fR. Tcl converts
the argument supplied in the expression to the type requested in
\fIargTypes\fR, if that is necessary.
Depending on the value of the \fItype\fR field, the \fIintValue\fR,
-.VS 8.4
\fIdoubleValue\fR or \fIwideValue\fR
-.VE 8.4
field will contain the actual value of the argument.
.PP
\fIProc\fR should compute its result and store it either as an integer
in \fIresultPtr->intValue\fR or as a floating value in
\fIresultPtr->doubleValue\fR.
It should set also \fIresultPtr->type\fR to one of
-.VS 8.4
-TCL_INT, TCL_DOUBLE or TCL_WIDE_INT
-.VE 8.4
+\fBTCL_INT\fR, \fBTCL_DOUBLE\fR or \fBTCL_WIDE_INT\fR
to indicate which value was set.
-Under normal circumstances \fIproc\fR should return TCL_OK.
+Under normal circumstances \fIproc\fR should return \fBTCL_OK\fR.
If an error occurs while executing the function, \fIproc\fR should
-return TCL_ERROR and leave an error message in the interpreter's result.
+return \fBTCL_ERROR\fR and leave an error message in the interpreter's result.
.PP
-.VS 8.4
\fBTcl_GetMathFuncInfo\fR retrieves the values associated with
function \fIname\fR that were passed to a preceding
\fBTcl_CreateMathFunc\fR call. Normally, the return code is
@@ -140,20 +136,21 @@ result.
If an error did not occur, the array reference placed in the variable
pointed to by \fIargTypesPtr\fR is newly allocated, and should be
released by passing it to \fBTcl_Free\fR. Some functions (the
-standard set implemented in the core) are implemented directly at the
-bytecode level; attempting to retrieve values for them causes a NULL
-to be stored in the variable pointed to by \fIprocPtr\fR and the
-variable pointed to by \fIclientDataPtr\fR will not be modified.
+standard set implemented in the core, and those defined by placing
+commands in the \fBtcl::mathfunc\fR namespace) do not have
+argument type information; attempting to retrieve values for
+them causes a NULL to be stored in the variable pointed to by
+\fIprocPtr\fR and the variable pointed to by \fIclientDataPtr\fR
+will not be modified. The variable pointed to by \fInumArgsPointer\fR
+will contain -1, and no argument types will be stored in the variable
+pointed to by \fIargTypesPointer\fR.
.PP
\fBTcl_ListMathFuncs\fR returns a Tcl object containing a list of all
the math functions defined in the interpreter whose name matches
-\fIpattern\fR. In the case of an error, NULL is returned and an error
-message is left in the interpreter result, and otherwise the returned
-object will have a reference count of zero.
-.VE
+\fIpattern\fR. The returned object has a reference count of zero.
+
+.SH "SEE ALSO"
+expr(n), info(n), Tcl_CreateObjCommand(3), Tcl_Free(3), Tcl_NewListObj(3)
.SH KEYWORDS
expression, mathematical function
-
-.SH "SEE ALSO"
-expr(n), info(n), Tcl_Free(3), Tcl_NewListObj(3)
diff --git a/doc/CrtObjCmd.3 b/doc/CrtObjCmd.3
index bcb57f3..a05efc2 100644
--- a/doc/CrtObjCmd.3
+++ b/doc/CrtObjCmd.3
@@ -28,17 +28,13 @@ int
int
\fBTcl_SetCommandInfo\fR(\fIinterp, cmdName, infoPtr\fR)
.sp
-.VS 8.4
int
\fBTcl_GetCommandInfoFromToken\fR(\fItoken, infoPtr\fR)
.sp
int
\fBTcl_SetCommandInfoFromToken\fR(\fItoken, infoPtr\fR)
-.VE
.sp
-.VS 8.4
-CONST char *
-.VE
+const char *
\fBTcl_GetCommandName\fR(\fIinterp, token\fR)
.sp
void
@@ -47,12 +43,10 @@ void
Tcl_Command
\fBTcl_GetCommandFromObj\fR(\fIinterp, objPtr\fR)
.SH ARGUMENTS
-.AS Tcl_ObjCmdProc *deleteProc in/out
+.AS Tcl_CmdDeleteProc *deleteProc in/out
.AP Tcl_Interp *interp in
Interpreter in which to create a new command or that contains a command.
-.VS 8.4
.AP char *cmdName in
-.VE
Name of command.
.AP Tcl_ObjCmdProc *proc in
Implementation of the new command: \fIproc\fR will be called whenever
@@ -96,11 +90,10 @@ and it returns NULL.
\fBTcl_ObjCmdProc\fR:
.CS
typedef int Tcl_ObjCmdProc(
- ClientData \fIclientData\fR,
- Tcl_Interp *\fIinterp\fR,
- int \fIobjc\fR,
-.VS
- Tcl_Obj *CONST \fIobjv\fR[]);
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ int \fIobjc\fR,
+ Tcl_Obj *const \fIobjv\fR[]);
.CE
When \fIproc\fR is invoked, the \fIclientData\fR and \fIinterp\fR parameters
will be copies of the \fIclientData\fR and \fIinterp\fR arguments given to
@@ -117,7 +110,7 @@ Additionally, when \fIproc\fR is invoked, it must not modify the contents
of the \fIobjv\fR array by assigning new pointer values to any element of the
array (for example, \fIobjv\fR[\fB2\fR] = \fBNULL\fR) because this will
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
+\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
@@ -125,7 +118,6 @@ object argument. For instance, the user may call
representation of that object; that call may change the type of the object
that \fIobjv\fR[\fB2\fR] points at, but will not change where
\fIobjv\fR[\fB2\fR] points.
-.VE
.PP
\fIproc\fR must return an integer code that is either \fBTCL_OK\fR,
\fBTCL_ERROR\fR, \fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or \fBTCL_CONTINUE\fR.
@@ -168,7 +160,8 @@ application an opportunity to release any structures associated
with the command. \fIDeleteProc\fR should have arguments and
result that match the type \fBTcl_CmdDeleteProc\fR:
.CS
-typedef void Tcl_CmdDeleteProc(ClientData \fIclientData\fR);
+typedef void Tcl_CmdDeleteProc(
+ ClientData \fIclientData\fR);
.CE
The \fIclientData\fR argument will be the same as the \fIclientData\fR
argument passed to \fBTcl_CreateObjCommand\fR.
@@ -176,7 +169,7 @@ argument passed to \fBTcl_CreateObjCommand\fR.
\fBTcl_DeleteCommand\fR deletes a command from a command interpreter.
Once the call completes, attempts to invoke \fIcmdName\fR in
\fIinterp\fR will result in errors.
-If \fIcmdName\fR isn't bound as a command in \fIinterp\fR then
+If \fIcmdName\fR is not bound as a command in \fIinterp\fR then
\fBTcl_DeleteCommand\fR does nothing and returns -1; otherwise
it returns 0.
There are no restrictions on \fIcmdName\fR: it may refer to
@@ -206,14 +199,14 @@ pointed to by \fIinfoPtr\fR and returns 1.
A \fBTcl_CmdInfo\fR structure has the following fields:
.CS
typedef struct Tcl_CmdInfo {
- int isNativeObjectProc;
- Tcl_ObjCmdProc *objProc;
- ClientData objClientData;
- Tcl_CmdProc *proc;
- ClientData clientData;
- Tcl_CmdDeleteProc *deleteProc;
- ClientData deleteData;
- Tcl_Namespace *namespacePtr;
+ int \fIisNativeObjectProc\fR;
+ Tcl_ObjCmdProc *\fIobjProc\fR;
+ ClientData \fIobjClientData\fR;
+ Tcl_CmdProc *\fIproc\fR;
+ ClientData \fIclientData\fR;
+ Tcl_CmdDeleteProc *\fIdeleteProc\fR;
+ ClientData \fIdeleteData\fR;
+ Tcl_Namespace *\fInamespacePtr\fR;
} Tcl_CmdInfo;
.CE
The \fIisNativeObjectProc\fR field has the value 1
@@ -285,16 +278,16 @@ This name does not include any \fB::\fR namespace qualifiers.
The command corresponding to \fItoken\fR must not have been deleted.
The string returned by \fBTcl_GetCommandName\fR is in dynamic memory
owned by Tcl and is only guaranteed to retain its value as long as the
-command isn't deleted or renamed; callers should copy the string if
+command is not deleted or renamed; callers should copy the string if
they need to keep it for a long time.
.PP
-\fBTcl_GetCommandFullName\fR produces the fully-qualified name
+\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\fP.
+is appended to the object specified by \fIobjPtr\fR.
.PP
\fBTcl_GetCommandFromObj\fR returns a token for the command
-specified by the name in a \fBTcl_Obj\fP.
+specified by the name in a \fBTcl_Obj\fR.
The command name is resolved relative to the current namespace.
Returns NULL if the command is not found.
.SH "SEE ALSO"
diff --git a/doc/CrtSlave.3 b/doc/CrtSlave.3
index f87a4e0..3863373 100644
--- a/doc/CrtSlave.3
+++ b/doc/CrtSlave.3
@@ -8,7 +8,7 @@
.TH Tcl_CreateSlave 3 7.6 Tcl "Tcl Library Procedures"
.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.
+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
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -31,20 +31,21 @@ Tcl_Interp *
int
\fBTcl_GetInterpPath\fR(\fIaskingInterp, slaveInterp\fR)
.sp
-.VS
int
-\fBTcl_CreateAlias\fR(\fIslaveInterp, slaveCmd, targetInterp, targetCmd, argc, argv\fR)
+\fBTcl_CreateAlias\fR(\fIslaveInterp, slaveCmd, targetInterp, targetCmd,
+ argc, argv\fR)
.sp
int
-\fBTcl_CreateAliasObj\fR(\fIslaveInterp, slaveCmd, targetInterp, targetCmd, objc, objv\fR)
-.VE
+\fBTcl_CreateAliasObj\fR(\fIslaveInterp, slaveCmd, targetInterp, targetCmd,
+ objc, objv\fR)
.sp
int
-\fBTcl_GetAlias\fR(\fIinterp, slaveCmd, targetInterpPtr, targetCmdPtr, argcPtr, argvPtr\fR)
+\fBTcl_GetAlias\fR(\fIinterp, slaveCmd, targetInterpPtr, targetCmdPtr,
+ argcPtr, argvPtr\fR)
.sp
-.VS
int
-\fBTcl_GetAliasObj\fR(\fIinterp, slaveCmd, targetInterpPtr, targetCmdPtr, objcPtr, objvPtr\fR)
+\fBTcl_GetAliasObj\fR(\fIinterp, slaveCmd, targetInterpPtr, targetCmdPtr,
+ objcPtr, objvPtr\fR)
.sp
int
\fBTcl_ExposeCommand\fR(\fIinterp, hiddenCmdName, cmdName\fR)
@@ -52,44 +53,46 @@ int
int
\fBTcl_HideCommand\fR(\fIinterp, cmdName, hiddenCmdName\fR)
.SH ARGUMENTS
-.AS Tcl_InterpDeleteProc **hiddenCmdName
+.AS "const char *const" **targetInterpPtr out
.AP Tcl_Interp *interp in
Interpreter in which to execute the specified command.
-.AP "CONST char" *slaveName in
+.AP "const char" *slaveName in
Name of slave interpreter to create or manipulate.
.AP int isSafe in
-If non-zero, a ``safe'' slave that is suitable for running untrusted code
+If non-zero, a
+.QW safe
+slave that is suitable for running untrusted code
is created, otherwise a trusted slave is created.
.AP Tcl_Interp *slaveInterp in
Interpreter to use for creating the source command for an alias (see
below).
-.AP "CONST char" *slaveCmd in
+.AP "const char" *slaveCmd in
Name of source command for alias.
.AP Tcl_Interp *targetInterp in
Interpreter that contains the target command for an alias.
-.AP "CONST char" *targetCmd in
+.AP "const char" *targetCmd in
Name of target command for alias in \fItargetInterp\fR.
.AP int argc in
Count of additional arguments to pass to the alias command.
-.AP "CONST char * CONST" *argv in
+.AP "const char *const" *argv in
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.
-.AP Tcl_Object **objv in
+.AP Tcl_Obj **objv in
Vector of Tcl_Obj structures, the additional object arguments to pass to
the alias object 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
command is defined for an alias.
-.AP "CONST char" **targetCmdPtr out
+.AP "const char" **targetCmdPtr out
Pointer to location to store the address of the name of the target command
for an alias.
.AP int *argcPtr out
Pointer to location to store count of additional arguments to be passed to
the alias. The location is in storage owned by the caller.
-.AP "CONST char" ***argvPtr out
+.AP "const char" ***argvPtr out
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.
@@ -101,17 +104,11 @@ 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
owned by the caller, the vector of Tcl_Obj structures is owned by the
called function.
-.VS
-.VS 8.4
-.AP "CONST char" *cmdName in
-.VE
+.AP "const char" *cmdName in
Name of an exposed command to hide or create.
-.VS 8.4
-.AP "CONST char" *hiddenCmdName in
-.VE
+.AP "const char" *hiddenCmdName in
Name under which a hidden command is stored and with which it can be
exposed or invoked.
-.VE
.BE
.SH DESCRIPTION
@@ -129,16 +126,21 @@ It also creates a slave command named \fIslaveName\fR in \fIinterp\fR which
allows \fIinterp\fR to manipulate the new slave.
If \fIisSafe\fR is zero, the command creates a trusted slave in which Tcl
code has access to all the Tcl commands.
-If it is \fB1\fR, the command creates a ``safe'' slave in which Tcl code
-has access only to set of Tcl commands defined as ``Safe Tcl''; see the
-manual entry for the Tcl \fBinterp\fR command for details.
+If it is \fB1\fR, the command creates a
+.QW safe
+slave in which Tcl code has access only to set of Tcl commands defined as
+.QW "Safe Tcl" ;
+see the manual entry for the Tcl \fBinterp\fR command for details.
If the creation of the new slave interpreter failed, \fBNULL\fR is returned.
.PP
-\fBTcl_IsSafe\fR returns \fB1\fR if \fIinterp\fR is ``safe'' (was created
-with the \fBTCL_SAFE_INTERPRETER\fR flag specified),
+\fBTcl_IsSafe\fR returns \fB1\fR if \fIinterp\fR is
+.QW safe
+(was created with the \fBTCL_SAFE_INTERPRETER\fR flag specified),
\fB0\fR otherwise.
.PP
-\fBTcl_MakeSafe\fR marks \fIinterp\fR as ``safe'', so that future
+\fBTcl_MakeSafe\fR marks \fIinterp\fR as
+.QW safe ,
+so that future
calls to \fBTcl_IsSafe\fR will return 1. It also removes all known
potentially-unsafe core functionality (both commands and variables)
from \fIinterp\fR. However, it cannot know what parts of an extension
@@ -163,7 +165,6 @@ 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
-.VS
\fBTcl_CreateAlias\fR creates an object 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
@@ -180,7 +181,6 @@ restrictions on how they are related.
\fBTcl_CreateAliasObj\fR is similar to \fBTcl_CreateAlias\fR except
that it takes a vector of objects to pass as additional arguments instead
of a vector of strings.
-.VE
.PP
\fBTcl_GetAlias\fR returns information about an alias \fIaliasName\fR
in \fIinterp\fR. Any of the result fields can be \fBNULL\fR, in
@@ -188,7 +188,6 @@ which case the corresponding datum is not returned. If a result field is
non\-\fBNULL\fR, the address indicated is set to the corresponding datum.
For example, if \fItargetNamePtr\fR is non\-\fBNULL\fR it is set to a
pointer to the string containing the name of the target command.
-.VS
.PP
\fBTcl_GetAliasObj\fR is similar to \fBTcl_GetAlias\fR except that it
returns a pointer to a vector of Tcl_Obj structures instead of a vector of
diff --git a/doc/CrtTimerHdlr.3 b/doc/CrtTimerHdlr.3
index 9018ae2..e948728 100644
--- a/doc/CrtTimerHdlr.3
+++ b/doc/CrtTimerHdlr.3
@@ -9,8 +9,7 @@
.TH Tcl_CreateTimerHandler 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
-Tcl_CreateTimerHandler, Tcl_DeleteTimerHandler \- call a procedure at a
-given time
+Tcl_CreateTimerHandler, Tcl_DeleteTimerHandler \- call a procedure at a given time
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -28,7 +27,7 @@ Procedure to invoke after \fImilliseconds\fR have elapsed.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.AP Tcl_TimerToken token in
-Token for previously-created timer handler (the return value
+Token for previously created timer handler (the return value
from some previous call to \fBTcl_CreateTimerHandler\fR).
.BE
@@ -43,7 +42,7 @@ dispatch events through \fBTcl_DoOneEvent\fR or through Tcl commands
such as \fBvwait\fR.
The call to \fIproc\fR may not be made at the exact time given by
\fImilliseconds\fR: it will be made at the next opportunity
-after that time. For example, if \fBTcl_DoOneEvent\fR isn't
+after that time. For example, if \fBTcl_DoOneEvent\fR is not
called until long after the time has elapsed, or if there
are other pending events to process before the call to
\fIproc\fR, then the call to \fIproc\fR will be delayed.
@@ -61,7 +60,7 @@ structure containing application-specific information about
what to do in \fIproc\fR.
.PP
\fBTcl_DeleteTimerHandler\fR may be called to delete a
-previously-created timer handler. It deletes the handler
+previously created timer handler. It deletes the handler
indicated by \fItoken\fR so that no call to \fIproc\fR
will be made; if that handler no longer exists
(e.g. because the time period has already elapsed and \fIproc\fR
diff --git a/doc/CrtTrace.3 b/doc/CrtTrace.3
index e11bd55..076f47b 100644
--- a/doc/CrtTrace.3
+++ b/doc/CrtTrace.3
@@ -1,7 +1,7 @@
'\"
'\" Copyright (c) 1989-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
-'\" Copyright (c) 2002 by Kevin B. Kenny. All rights reserved.
+'\" Copyright (c) 2002 by Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -23,7 +23,7 @@ Tcl_Trace
.sp
\fBTcl_DeleteTrace\fR(\fIinterp, trace\fR)
.SH ARGUMENTS
-.AS Tcl_CmdObjTraceDeleteProc (clientData)()
+.AS Tcl_CmdObjTraceDeleteProc *deleteProc
.AP Tcl_Interp *interp in
Interpreter containing command to be traced or untraced.
.AP int level in
@@ -36,14 +36,14 @@ A value of 0 means that commands at any level are traced.
.AP int flags in
Flags governing the trace execution. See below for details.
.AP Tcl_CmdObjTraceProc *objProc in
-Procedure to call for each command that's executed. See below for
+Procedure to call for each command that is executed. See below for
details of the calling sequence.
.AP Tcl_CmdTraceProc *proc in
-Procedure to call for each command that's executed. See below for
+Procedure to call for each command that is executed. See below for
details on the calling sequence.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIobjProc\fR or \fIproc\fR.
-.AP Tcl_CmdObjTraceDeleteProc *deleteProc
+.AP Tcl_CmdObjTraceDeleteProc *deleteProc in
Procedure to call when the trace is deleted. See below for details of
the calling sequence. A NULL pointer is permissible and results in no
callback when the trace is deleted.
@@ -65,13 +65,13 @@ interpreter.
\fBTcl_CmdObjTraceProc\fR:
.CS
typedef int \fBTcl_CmdObjTraceProc\fR(
- \fBClientData\fR \fIclientData\fR,
- \fBTcl_Interp\fR* \fIinterp\fR,
- int \fIlevel\fR,
- CONST char* \fIcommand\fR,
- \fBTcl_Command\fR \fIcommandToken\fR,
- int \fIobjc\fR,
- \fBTcl_Obj\fR *CONST \fIobjv\fR[] );
+ \fBClientData\fR \fIclientData\fR,
+ \fBTcl_Interp\fR* \fIinterp\fR,
+ int \fIlevel\fR,
+ const char *\fIcommand\fR,
+ \fBTcl_Command\fR \fIcommandToken\fR,
+ int \fIobjc\fR,
+ \fBTcl_Obj\fR *const \fIobjv\fR[] );
.CE
The \fIclientData\fR and \fIinterp\fR parameters are copies of the
corresponding arguments given to \fBTcl_CreateTrace\fR.
@@ -141,8 +141,7 @@ When \fBTcl_DeleteTrace\fR is called, the interpreter invokes the
\fBTcl_CmdObjTraceDeleteProc\fR:
.CS
typedef void \fBTcl_CmdObjTraceDeleteProc\fR(
- \fBClientData\fR \fIclientData\fR
-);
+ \fBClientData\fR \fIclientData\fR);
.CE
The \fIclientData\fR parameter will be the same as the
\fIclientData\fR parameter that was originally passed to
@@ -156,14 +155,14 @@ that its \fIproc\fR parameter should have arguments and result that
match the type \fBTcl_CmdTraceProc\fR:
.CS
typedef void Tcl_CmdTraceProc(
- ClientData \fIclientData\fR,
- Tcl_Interp *\fIinterp\fR,
- int \fIlevel\fR,
- char *\fIcommand\fR,
- Tcl_CmdProc *\fIcmdProc\fR,
- ClientData \fIcmdClientData\fR,
- int \fIargc\fR,
- CONST char *\fIargv\fR[]);
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ int \fIlevel\fR,
+ char *\fIcommand\fR,
+ Tcl_CmdProc *\fIcmdProc\fR,
+ ClientData \fIcmdClientData\fR,
+ int \fIargc\fR,
+ const char *\fIargv\fR[]);
.CE
The parameters to the \fIproc\fR callback are similar to those of the
\fIobjProc\fR callback above. The \fIcommandToken\fR is
diff --git a/doc/DString.3 b/doc/DString.3
index 8c6f516..a85b1cf 100644
--- a/doc/DString.3
+++ b/doc/DString.3
@@ -17,10 +17,10 @@ Tcl_DStringInit, Tcl_DStringAppend, Tcl_DStringAppendElement, Tcl_DStringStartSu
\fBTcl_DStringInit\fR(\fIdsPtr\fR)
.sp
char *
-\fBTcl_DStringAppend\fR(\fIdsPtr, string, length\fR)
+\fBTcl_DStringAppend\fR(\fIdsPtr, bytes, length\fR)
.sp
char *
-\fBTcl_DStringAppendElement\fR(\fIdsPtr, string\fR)
+\fBTcl_DStringAppendElement\fR(\fIdsPtr, element\fR)
.sp
\fBTcl_DStringStartSublist\fR(\fIdsPtr\fR)
.sp
@@ -42,13 +42,15 @@ char *
.sp
\fBTcl_DStringGetResult\fR(\fIinterp, dsPtr\fR)
.SH ARGUMENTS
-.AS Tcl_DString newLength
+.AS Tcl_DString newLength in/out
.AP Tcl_DString *dsPtr in/out
Pointer to structure that is used to manage a dynamic string.
-.AP "CONST char" *string in
-Pointer to characters to add to dynamic string.
+.AP "const char" *bytes in
+Pointer to characters to append to dynamic string.
+.AP "const char" *element in
+Pointer to characters to append as list element to dynamic string.
.AP int length in
-Number of characters from string to add to dynamic string. If -1,
+Number of bytes from \fIbytes\fR to add to dynamic string. If -1,
add all characters up to null terminating character.
.AP int newLength in
New length for dynamic string, not including null terminating
@@ -75,7 +77,7 @@ string.
.PP
\fBTcl_DStringAppend\fR adds new information to a dynamic string,
allocating more memory for the string if needed.
-If \fIlength\fR is less than zero then everything in \fIstring\fR
+If \fIlength\fR is less than zero then everything in \fIbytes\fR
is appended to the dynamic string; otherwise \fIlength\fR
specifies the number of bytes to append.
\fBTcl_DStringAppend\fR returns a pointer to the characters of
@@ -83,14 +85,16 @@ the new string. The string can also be retrieved from the
\fIstring\fR field of the Tcl_DString structure.
.PP
\fBTcl_DStringAppendElement\fR is similar to \fBTcl_DStringAppend\fR
-except that it doesn't take a \fIlength\fR argument (it appends
-all of \fIstring\fR) and it converts the string to a proper list element
+except that it does not take a \fIlength\fR argument (it appends
+all of \fIelement\fR) and it converts the string to a proper list element
before appending.
\fBTcl_DStringAppendElement\fR adds a separator space before the
new list element unless the new list element is the first in a
list or sub-list (i.e. either the current string is empty, or it
-contains the single character ``{'', or the last two characters of
-the current string are `` {'').
+contains the single character
+.QW { ,
+or the last two characters of the current string are
+.QW " {" ).
\fBTcl_DStringAppendElement\fR returns a pointer to the
characters of the new string.
.PP
@@ -128,7 +132,7 @@ will still need to be called.
This procedure is now deprecated. \fBTcl_DStringSetLength\fR should
be used instead.
.PP
-\fBTcl_DStringFree\fR should be called when you're finished using
+\fBTcl_DStringFree\fR should be called when you are finished using
the string. It frees up any memory that was allocated for the string
and reinitializes the string's value to an empty string.
.PP
diff --git a/doc/DetachPids.3 b/doc/DetachPids.3
index 17b57eb..0535cd8 100644
--- a/doc/DetachPids.3
+++ b/doc/DetachPids.3
@@ -19,18 +19,18 @@ Tcl_DetachPids, Tcl_ReapDetachedProcs, Tcl_WaitPid \- manage child processes in
\fBTcl_ReapDetachedProcs\fR()
.sp
Tcl_Pid
-\fBTcl_WaitPid\fR(\fIpid, statPtr, options\fR)
+\fBTcl_WaitPid\fR(\fIpid, statusPtr, options\fR)
.SH ARGUMENTS
-.AS int *statusPtr
+.AS Tcl_Pid *statusPtr out
.AP int numPids in
Number of process ids contained in the array pointed to by \fIpidPtr\fR.
.AP int *pidPtr in
Address of array containing \fInumPids\fR process ids.
.AP Tcl_Pid pid in
The id of the process (pipe) to wait for.
-.AP int* statPtr out
+.AP int *statusPtr out
The result of waiting on a process (pipe). Either 0 or ECHILD.
-.AP int options
+.AP int options in
The options controlling the wait. WNOHANG specifies not to wait when
checking the process.
.BE
@@ -49,16 +49,16 @@ overflow, even if all the children have exited.
\fBTcl_DetachPids\fR may be called to ask Tcl to take responsibility
for one or more processes whose process ids are contained in the
\fIpidPtr\fR array passed as argument. The caller presumably
-has started these processes running in background and doesn't
+has started these processes running in background and does not
want to have to deal with them again.
.PP
\fBTcl_ReapDetachedProcs\fR invokes the \fBwaitpid\fR kernel call
on each of the background processes so that its state can be cleaned
-up if it has exited. If the process hasn't exited yet,
-\fBTcl_ReapDetachedProcs\fR doesn't wait for it to exit; it will check again
+up if it has exited. If the process has not exited yet,
+\fBTcl_ReapDetachedProcs\fR does not wait for it to exit; it will check again
the next time it is invoked.
Tcl automatically calls \fBTcl_ReapDetachedProcs\fR each time the
-\fBexec\fR command is executed, so in most cases it isn't necessary
+\fBexec\fR command is executed, so in most cases it is not necessary
for any code outside of Tcl to invoke \fBTcl_ReapDetachedProcs\fR.
However, if you call \fBTcl_DetachPids\fR in situations where the
\fBexec\fR command may never get executed, you may wish to call
diff --git a/doc/DictObj.3 b/doc/DictObj.3
new file mode 100644
index 0000000..74b8dd1
--- /dev/null
+++ b/doc/DictObj.3
@@ -0,0 +1,234 @@
+'\"
+'\" Copyright (c) 2003 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 Tcl_DictObj 3 8.5 Tcl "Tcl Library Procedures"
+.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
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_NewDictObj\fR()
+.sp
+int
+\fBTcl_DictObjGet\fR(\fIinterp, dictPtr, keyPtr, valuePtrPtr\fR)
+.sp
+int
+\fBTcl_DictObjPut\fR(\fIinterp, dictPtr, keyPtr, valuePtr\fR)
+.sp
+int
+\fBTcl_DictObjRemove\fR(\fIinterp, dictPtr, keyPtr\fR)
+.sp
+int
+\fBTcl_DictObjSize\fR(\fIinterp, dictPtr, sizePtr\fR)
+.sp
+int
+\fBTcl_DictObjFirst\fR(\fIinterp, dictPtr, searchPtr,
+ keyPtrPtr, valuePtrPtr, donePtr\fR)
+.sp
+void
+\fBTcl_DictObjNext\fR(\fIsearchPtr, keyPtrPtr, valuePtrPtr, donePtr\fR)
+.sp
+void
+\fBTcl_DictObjDone\fR(\fIsearchPtr\fR)
+.sp
+int
+\fBTcl_DictObjPutKeyList\fR(\fIinterp, dictPtr, keyc, keyv, valuePtr\fR)
+.sp
+int
+\fBTcl_DictObjRemoveKeyList\fR(\fIinterp, dictPtr, keyc, keyv\fR)
+.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
+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,
+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.
+.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
+\fBTcl_DictObjPutKeyList\fR.)
+.AP Tcl_Obj **valuePtrPtr out
+Points to a variable that will have the value from a key/value pair
+placed within it. For \fBTcl_DictObjFirst\fR and
+\fBTcl_DictObjNext\fR, this may be NULL to indicate that the caller is
+not interested in the value.
+.AP int *sizePtr out
+Points to a variable that will have the number of key/value pairs
+contained within the dictionary placed within it.
+.AP Tcl_DictSearch *searchPtr in/out
+Pointer to record to use to keep track of progress in enumerating all
+key/value pairs in a dictionary. The contents of the record will be
+initialized by the call to \fBTcl_DictObjFirst\fR. If the enumerating
+is to be terminated before all values in the dictionary have been
+returned, the search record \fImust\fR be passed to
+\fBTcl_DictObjDone\fR to enable the internal locks to be released.
+.AP int *donePtr out
+Points to a variable that will have a non-zero value written into it
+when the enumeration of the key/value pairs in a dictionary has
+completed, and a zero otherwise.
+.AP int keyc in
+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
+\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.
+.BE
+
+.SH DESCRIPTION
+.PP
+Tcl dictionary objects 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
+added (which adds them to the end of the order). If reinterpreted as a
+list, the values at the even-valued indices in the list will be the
+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.
+.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.
+.PP
+\fBTcl_DictObjGet\fR looks up the given key within the given
+dictionary and writes a pointer to the value associated with that key
+into the variable pointed to by \fIvaluePtrPtr\fR, or a NULL if the
+key has no mapping within the dictionary. The result of this
+procedure is \fBTCL_OK\fR, or \fBTCL_ERROR\fR if the \fIdictPtr\fR cannot be
+converted to a dictionary.
+.PP
+\fBTcl_DictObjPut\fR updates the given dictionary so that the given
+key maps to the given value; any key may exist at most once in any
+particular dictionary. The dictionary must not be shared, but the key
+and value may be. This procedure may increase the reference count of
+both key and value if it proves necessary to store them. Neither key
+nor value should be NULL. The result of this procedure is \fBTCL_OK\fR, or
+\fBTCL_ERROR\fR if the \fIdictPtr\fR cannot be converted to a dictionary.
+.PP
+\fBTcl_DictObjRemove\fR updates the given dictionary so that the given
+key has no mapping to any value. The dictionary must not be shared,
+but the key may be. The key actually stored in the dictionary will
+have its reference count decremented if it was present. It is not an
+error if the key did not previously exist. The result of this
+procedure is \fBTCL_OK\fR, or \fBTCL_ERROR\fR if the \fIdictPtr\fR cannot be
+converted to a dictionary.
+.PP
+\fBTcl_DictObjSize\fR updates the given variable with the number of
+key/value pairs currently in the given dictionary. The result of this
+procedure is \fBTCL_OK\fR, or \fBTCL_ERROR\fR if the \fIdictPtr\fR cannot be
+converted to a dictionary.
+.PP
+\fBTcl_DictObjFirst\fR commences an iteration across all the key/value
+pairs in the given dictionary, placing the key and value in the
+variables pointed to by the \fIkeyPtrPtr\fR and \fIvaluePtrPtr\fR
+arguments (which may be NULL to indicate that the caller is
+uninterested in they key or variable respectively.) The next
+key/value pair in the dictionary may be retrieved with
+\fBTcl_DictObjNext\fR. Concurrent updates of the dictionary's
+internal representation will not modify the iteration processing
+unless the dictionary is unshared, when this will trigger premature
+termination of the iteration instead (which Tcl scripts cannot trigger
+via the \fBdict\fR command.) The \fIsearchPtr\fR argument points to a
+piece of context that is used to identify which particular iteration
+is being performed, and is initialized by the call to
+\fBTcl_DictObjFirst\fR. The \fIdonePtr\fR argument points to a
+variable that is updated to be zero of there are further key/value
+pairs to be iterated over, or non-zero if the iteration is complete.
+The order of iteration is implementation-defined. If the
+\fIdictPtr\fR argument cannot be converted to a dictionary,
+\fBTcl_DictObjFirst\fR returns \fBTCL_ERROR\fR and the iteration is not
+commenced, and otherwise it returns \fBTCL_OK\fR.
+.PP
+When \fBTcl_DictObjFirst\fR is called upon a dictionary, a lock is placed on
+the dictionary to enable that dictionary to be iterated over safely without
+regard for whether the dictionary is modified during the iteration. Because of
+this, once the iteration over a dictionary's keys has finished (whether
+because all values have been iterated over as indicated by the variable
+indicated by the \fIdonePtr\fR argument being set to one, or because no
+further values are required) the \fBTcl_DictObjDone\fR function must be called
+with the same \fIsearchPtr\fR as was passed to \fBTcl_DictObjFirst\fR so that
+the internal locks can be released. Once a particular \fIsearchPtr\fR is
+passed to \fBTcl_DictObjDone\fR, passing it to \fBTcl_DictObjNext\fR (without
+first initializing it with \fBTcl_DictObjFirst\fR) will result in no values
+being produced and the variable pointed to by \fIdonePtr\fR being set to one.
+It is safe to call \fBTcl_DictObjDone\fR multiple times on the same
+\fIsearchPtr\fR for each call to \fBTcl_DictObjFirst\fR.
+.PP
+The procedures \fBTcl_DictObjPutKeyList\fR and
+\fBTcl_DictObjRemoveKeyList\fR are the close analogues of
+\fBTcl_DictObjPut\fR and \fBTcl_DictObjRemove\fR respectively, except
+that instead of working with a single dictionary, they are designed to
+operate on a nested tree of dictionaries, with inner dictionaries
+stored as values inside outer dictionaries. The \fIkeyc\fR and
+\fIkeyv\fR arguments specify a list of keys (with outermost keys
+first) that acts as a path to the key/value pair to be affected. Note
+that there is no corresponding operation for reading a value for a
+path as this is easy to construct from repeated use of
+\fBTcl_DictObjGet\fR. With \fBTcl_DictObjPutKeyList\fR, nested
+dictionaries are created for non-terminal keys where they do not
+already exist. With \fBTcl_DictObjRemoveKeyList\fR, all non-terminal
+keys must exist and have dictionaries as their values.
+.SH EXAMPLE
+Using the dictionary iteration interface to search determine if there
+is a key that maps to itself:
+.PP
+.CS
+Tcl_DictSearch search;
+Tcl_Obj *key, *value;
+int done;
+
+/*
+ * Assume interp and objPtr are parameters. This is the
+ * idiomatic way to start an iteration over the dictionary; it
+ * sets a lock on the internal representation that ensures that
+ * there are no concurrent modification issues when normal
+ * reference count management is also used. The lock is
+ * released automatically when the loop is finished, but must
+ * be released manually when an exceptional exit from the loop
+ * is performed. However it is safe to try to release the lock
+ * even if we've finished iterating over the loop.
+ */
+if (\fBTcl_DictObjFirst\fR(interp, objPtr, &search,
+ &key, &value, &done) != TCL_OK) {
+ return TCL_ERROR;
+}
+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
+ * purposes.
+ */
+ if (!strcmp(Tcl_GetString(key), Tcl_GetString(value))) {
+ break;
+ }
+}
+\fBTcl_DictObjDone\fR(&search);
+Tcl_SetObjResult(interp, Tcl_NewBooleanObj(!done));
+return TCL_OK;
+.CE
+.SH "SEE ALSO"
+Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_InitObjHashTable
+.SH KEYWORDS
+dict, dict object, dictionary, dictionary object, hash table, iteration, object
diff --git a/doc/DoOneEvent.3 b/doc/DoOneEvent.3
index 058307d..9bdf926 100644
--- a/doc/DoOneEvent.3
+++ b/doc/DoOneEvent.3
@@ -21,9 +21,9 @@ int
.AP int flags in
This parameter is normally zero. It may be an OR-ed combination
of any of the following flag bits:
-TCL_WINDOW_EVENTS,
-TCL_FILE_EVENTS, TCL_TIMER_EVENTS, TCL_IDLE_EVENTS, TCL_ALL_EVENTS, or
-TCL_DONT_WAIT.
+\fBTCL_WINDOW_EVENTS\fR, \fBTCL_FILE_EVENTS\fR,
+\fBTCL_TIMER_EVENTS\fR, \fBTCL_IDLE_EVENTS\fR, \fBTCL_ALL_EVENTS\fR,
+or \fBTCL_DONT_WAIT\fR.
.BE
.SH DESCRIPTION
@@ -71,7 +71,7 @@ Process all kinds of events: equivalent to OR-ing together all of the
above flags or specifying none of them.
.TP 27
\fBTCL_DONT_WAIT\fR \-
-Don't sleep: process only events that are ready at the time of the
+Do not sleep: process only events that are ready at the time of the
call.
.LP
If any of the flags \fBTCL_WINDOW_EVENTS\fR, \fBTCL_FILE_EVENTS\fR,
diff --git a/doc/DoWhenIdle.3 b/doc/DoWhenIdle.3
index a15f1cb..bfc19fb 100644
--- a/doc/DoWhenIdle.3
+++ b/doc/DoWhenIdle.3
@@ -30,7 +30,7 @@ Arbitrary one-word value to pass to \fIproc\fR.
\fBTcl_DoWhenIdle\fR arranges for \fIproc\fR to be invoked
when the application becomes idle. The application is
considered to be idle when \fBTcl_DoOneEvent\fR has been
-called, couldn't find any events to handle, and is about
+called, could not find any events to handle, and is about
to go to sleep waiting for an event to occur. At this
point all pending \fBTcl_DoWhenIdle\fR handlers are
invoked. For each call to \fBTcl_DoWhenIdle\fR there will
@@ -59,7 +59,7 @@ all of the handlers are removed. If no existing handlers match
\fIproc\fR and \fIclientData\fR then nothing happens.
.PP
\fBTcl_DoWhenIdle\fR is most useful in situations where
-(a) a piece of work will have to be done but (b) it's
+(a) a piece of work will have to be done but (b) it is
possible that something will happen in the near future
that will change what has to be done or require something
different to be done. \fBTcl_DoWhenIdle\fR allows the
diff --git a/doc/DoubleObj.3 b/doc/DoubleObj.3
index b65af58..12818b0 100644
--- a/doc/DoubleObj.3
+++ b/doc/DoubleObj.3
@@ -23,55 +23,42 @@ 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 double object.
+A double-precision floating-point value used to initialize or set a Tcl object.
.AP Tcl_Obj *objPtr in/out
-For \fBTcl_SetDoubleObj\fR, this points to the object to be converted
-to double type.
+For \fBTcl_SetDoubleObj\fR, this points to the object in which to store a
+double value.
For \fBTcl_GetDoubleFromObj\fR, this refers to the object
-from which to get a double value;
-if \fIobjPtr\fR does not already point to a double object,
-an attempt will be made to convert it to one.
+from which to retrieve a double value.
.AP Tcl_Interp *interp in/out
-If an error occurs during conversion,
-an error message is left in the interpreter's result object
-unless \fIinterp\fR is NULL.
+When non-NULL, an error message is left here when double value retrieval fails.
.AP double *doublePtr out
-Points to place to store the double value
-obtained from \fIobjPtr\fR.
+Points to place to store the double value obtained from \fIobjPtr\fR.
.BE
.SH DESCRIPTION
.PP
-These procedures are used to create, modify, and read
-double Tcl objects from C code.
-\fBTcl_NewDoubleObj\fR and \fBTcl_SetDoubleObj\fR
-will create a new object of double type
-or modify an existing object to have double type.
-Both of these procedures set the object to have the
-double-precision floating point value given by \fIdoubleValue\fR;
-\fBTcl_NewDoubleObj\fR returns a pointer to a newly created object
-with reference count zero.
-Both procedures set the object's type to be double
-and assign the double value to the object's internal representation
-\fIdoubleValue\fR member.
-\fBTcl_SetDoubleObj\fR invalidates any old string representation
-and, if the object is not already a double object,
-frees any old internal representation.
+These procedures are used to create, modify, and read Tcl objects that
+hold double-precision floating-point values.
.PP
-\fBTcl_GetDoubleFromObj\fR attempts to return a double value
-from the Tcl object \fIobjPtr\fR.
-If the object is not already a double object,
-it will attempt to convert it to one.
-If an error occurs during conversion, it returns \fBTCL_ERROR\fR
-and leaves an error message in the interpreter's result object
-unless \fIinterp\fR is NULL.
-Otherwise, it returns \fBTCL_OK\fR and stores the double value
-in the address given by \fIdoublePtr\fR.
-If the object is not already a double object,
-the conversion will free any old internal representation.
-
+\fBTcl_NewDoubleObj\fR creates and returns a new Tcl object initialized to
+the double value \fIdoubleValue\fR. The returned Tcl object is unshared.
+.PP
+\fBTcl_SetDoubleObj\fR sets the value of an existing Tcl object 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
+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
+returned, and the double value is written to the storage pointed to by
+\fIdoublePtr\fR. If the attempt fails, then \fBTCL_ERROR\fR is returned,
+and if \fIinterp\fR is non-NULL, an error message is left in \fIinterp\fR.
+The \fBTcl_ObjType\fR of \fIobjPtr\fR may be changed to make subsequent
+calls to \fBTcl_GetDoubleFromObj\fR more efficient.
+'\" TODO: add discussion of treatment of NaN value
.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
diff --git a/doc/DumpActiveMemory.3 b/doc/DumpActiveMemory.3
index 6e00eb3..1f6cb46 100644
--- a/doc/DumpActiveMemory.3
+++ b/doc/DumpActiveMemory.3
@@ -7,7 +7,7 @@
.TH "Tcl_DumpActiveMemory" 3 8.1 Tcl "Tcl Library Procedures"
.BS
.SH NAME
-Tcl_DumpActiveMemory, Tcl_InitMemory, Tcl_ValidateAllMemory \- Validated memory allocation interface.
+Tcl_DumpActiveMemory, Tcl_InitMemory, Tcl_ValidateAllMemory \- Validated memory allocation interface
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -22,9 +22,10 @@ void
\fBTcl_ValidateAllMemory\fR(\fIfileName, line\fR)
.SH ARGUMENTS
+.AS Tcl_Interp *fileName
.AP Tcl_Interp *interp in
Tcl interpreter in which to add commands.
-.AP "CONST char" *fileName in
+.AP "const char" *fileName in
For \fBTcl_DumpActiveMemory\fR, name of the file to which memory
information will be written. For \fBTcl_ValidateAllMemory\fR, name of
the file from which the call is being made (normally \fB__FILE__\fR).
diff --git a/doc/Encoding.3 b/doc/Encoding.3
index 913d4fa..a940a5b 100644
--- a/doc/Encoding.3
+++ b/doc/Encoding.3
@@ -8,7 +8,7 @@
.TH Tcl_GetEncoding 3 "8.1" Tcl "Tcl Library Procedures"
.BS
.SH NAME
-Tcl_GetEncoding, Tcl_FreeEncoding, Tcl_ExternalToUtfDString, Tcl_ExternalToUtf, Tcl_UtfToExternalDString, Tcl_UtfToExternal, Tcl_WinTCharToUtf, Tcl_WinUtfToTChar, Tcl_GetEncodingName, Tcl_SetSystemEncoding, Tcl_GetEncodingNames, Tcl_CreateEncoding, Tcl_GetDefaultEncodingDir, Tcl_SetDefaultEncodingDir \- procedures for creating and using encodings.
+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
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -19,19 +19,24 @@ Tcl_Encoding
void
\fBTcl_FreeEncoding\fR(\fIencoding\fR)
.sp
+.VS 8.5
+int
+\fBTcl_GetEncodingFromObj\fR(\fIinterp, objPtr, encodingPtr\fR)
+.VE 8.5
+.sp
char *
\fBTcl_ExternalToUtfDString\fR(\fIencoding, src, srcLen, dstPtr\fR)
.sp
-int
-\fBTcl_ExternalToUtf\fR(\fIinterp, encoding, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr,
- dstCharsPtr\fR)
-.sp
-char *
+char *
\fBTcl_UtfToExternalDString\fR(\fIencoding, src, srcLen, dstPtr\fR)
.sp
int
-\fBTcl_UtfToExternal\fR(\fIinterp, encoding, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr,
- dstCharsPtr\fR)
+\fBTcl_ExternalToUtf\fR(\fIinterp, encoding, src, srcLen, flags, statePtr,
+ dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr\fR)
+.sp
+int
+\fBTcl_UtfToExternal\fR(\fIinterp, encoding, src, srcLen, flags, statePtr,
+ dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr\fR)
.sp
char *
\fBTcl_WinTCharToUtf\fR(\fItsrc, srcLen, dstPtr\fR)
@@ -39,41 +44,60 @@ char *
TCHAR *
\fBTcl_WinUtfToTChar\fR(\fIsrc, srcLen, dstPtr\fR)
.sp
-CONST char *
+const char *
\fBTcl_GetEncodingName\fR(\fIencoding\fR)
.sp
int
\fBTcl_SetSystemEncoding\fR(\fIinterp, name\fR)
.sp
+.VS 8.5
+const char *
+\fBTcl_GetEncodingNameFromEnvironment\fR(\fIbufPtr\fR)
+.VE 8.5
+.sp
void
\fBTcl_GetEncodingNames\fR(\fIinterp\fR)
.sp
Tcl_Encoding
\fBTcl_CreateEncoding\fR(\fItypePtr\fR)
.sp
-CONST char *
+.VS 8.5
+Tcl_Obj *
+\fBTcl_GetEncodingSearchPath\fR()
+.sp
+int
+\fBTcl_SetEncodingSearchPath\fR(\fIsearchPath\fR)
+.VE 8.5
+.sp
+const char *
\fBTcl_GetDefaultEncodingDir\fR(\fIvoid\fR)
.sp
void
\fBTcl_SetDefaultEncodingDir\fR(\fIpath\fR)
-
-
.SH ARGUMENTS
-.AS Tcl_EncodingState *dstWrotePtr
+.AS "const Tcl_EncodingType" *dstWrotePtr in/out
.AP Tcl_Interp *interp in
Interpreter to use for error reporting, or NULL if no error reporting is
desired.
-.AP "CONST char" *name in
+.AP "const char" *name in
Name of encoding to load.
.AP Tcl_Encoding encoding in
The encoding to query, free, or use for converting text. If \fIencoding\fR is
NULL, the current system encoding is used.
-.AP "CONST char" *src in
+.AP Tcl_Obj *objPtr in
+.VS 8.5
+Name of encoding to get token for.
+.VE 8.5
+.AP Tcl_Encoding *encodingPtr out
+.VS 8.5
+Points to storage where encoding token is to be written.
+.VE 8.5
+.AP "const char" *src in
For the \fBTcl_ExternalToUtf\fR functions, an array of bytes in the
specified encoding that are to be converted to UTF-8. For the
\fBTcl_UtfToExternal\fR and \fBTcl_WinUtfToTChar\fR functions, an array of
UTF-8 characters to be converted to the specified encoding.
-.AP "CONST TCHAR" *tsrc in
+.AP "const TCHAR" *tsrc in
An array of Windows TCHAR characters to convert to UTF-8.
.AP int srcLen in
Length of \fIsrc\fR or \fItsrc\fR in bytes. If the length is negative, the
@@ -83,21 +107,21 @@ Pointer to an uninitialized or free \fBTcl_DString\fR in which the converted
result will be stored.
.AP int flags in
Various flag bits OR-ed together.
-TCL_ENCODING_START signifies that the
+\fBTCL_ENCODING_START\fR signifies that the
source buffer is the first block in a (potentially multi-block) input
stream, telling the conversion routine to reset to an initial state and
perform any initialization that needs to occur before the first byte is
-converted. TCL_ENCODING_END signifies that the source buffer is the last
+converted. \fBTCL_ENCODING_END\fR signifies that the source buffer is the last
block in a (potentially multi-block) input stream, telling the conversion
routine to perform any finalization that needs to occur after the last
byte is converted and then to reset to an initial state.
-TCL_ENCODING_STOPONERROR signifies that the conversion routine should
-return immediately upon reading a source character that doesn't exist in
+\fBTCL_ENCODING_STOPONERROR\fR signifies that the conversion routine should
+return immediately upon reading a source character that does not exist in
the target encoding; otherwise a default fallback character will
automatically be substituted.
.AP Tcl_EncodingState *statePtr in/out
Used when converting a (generally long or indefinite length) byte stream
-in a piece by piece fashion. The conversion routine stores its current
+in a piece-by-piece fashion. The conversion routine stores its current
state in \fI*statePtr\fR after \fIsrc\fR (the buffer containing the
current piece) has been converted; that state information must be passed
back when converting the next piece of the stream so the conversion
@@ -120,9 +144,17 @@ buffer as a result of the conversion. May be NULL.
.AP int *dstCharsPtr out
Filled with the number of characters that correspond to the number of bytes
stored in the output buffer. May be NULL.
-.AP Tcl_EncodingType *typePtr in
+.AP Tcl_DString *bufPtr out
+.VS 8.5
+Storage for the prescribed system encoding name.
+.VE 8.5
+.AP "const Tcl_EncodingType" *typePtr in
Structure that defines a new type of encoding.
-.AP "CONST char" *path in
+.AP Tcl_Obj *searchPath in
+.VS 8.5
+List of filesystem directories in which to search for encoding data files.
+.VE 8.5
+.AP "const char" *path in
A path to the location of the encoding file.
.BE
.SH INTRODUCTION
@@ -149,7 +181,7 @@ platform-independent manner.
.SH DESCRIPTION
.PP
\fBTcl_GetEncoding\fR finds an encoding given its \fIname\fR. The name may
-refer to a builtin Tcl encoding, a user-defined encoding registered by
+refer to a built-in Tcl encoding, a user-defined encoding registered by
calling \fBTcl_CreateEncoding\fR, or a dynamically-loadable encoding
file. The return value is a token that represents the encoding and can be
used in subsequent calls to procedures such as \fBTcl_GetEncodingName\fR,
@@ -170,6 +202,20 @@ anywhere (i.e., it has been freed as many times as it has been gotten)
\fBTcl_FreeEncoding\fR will release all storage the encoding was using
and delete it from the database.
.PP
+.VS 8.5
+\fBTcl_GetEncodingFromObj\fR treats the string representation of
+\fIobjPtr\fR as an encoding name, and finds an encoding with that
+name, just as \fBTcl_GetEncoding\fR does. When an encoding is found,
+it is cached within the \fBobjPtr\fR value for future reference, the
+\fBTcl_Encoding\fR token is written to the storage pointed to by
+\fIencodingPtr\fR, and the value \fBTCL_OK\fR is returned. If no such
+encoding is found, the value \fBTCL_ERROR\fR is returned, and no
+writing to \fB*\fR\fIencodingPtr\fR takes place. Just as with
+\fBTcl_GetEncoding\fR, the caller should call \fBTcl_FreeEncoding\fR
+on the resulting encoding token when that token will no longer be
+used.
+.VE 8.5
+.PP
\fBTcl_ExternalToUtfDString\fR converts a source buffer \fIsrc\fR from the
specified \fIencoding\fR into UTF-8. The converted bytes are stored in
\fIdstPtr\fR, which is then null-terminated. The caller should eventually
@@ -192,7 +238,7 @@ All bytes of \fIsrc\fR were converted.
The destination buffer was not large enough for all of the converted data; as
many characters as could fit were converted though.
.IP \fBTCL_CONVERT_MULTIBYTE\fR 29
-The last fews bytes in the source buffer were the beginning of a multibyte
+The last few bytes in the source buffer were the beginning of a multibyte
sequence, but more bytes were needed to complete this sequence. A
subsequent call to the conversion routine should pass a buffer containing
the unconverted bytes that remained in \fIsrc\fR plus some further bytes
@@ -204,7 +250,7 @@ if the input stream has been damaged or if the input encoding method was
misidentified.
.IP \fBTCL_CONVERT_UNKNOWN\fR 29
The source buffer contained a character that could not be represented in
-the target encoding and TCL_ENCODING_STOPONERROR was specified.
+the target encoding and \fBTCL_ENCODING_STOPONERROR\fR was specified.
.RE
.LP
\fBTcl_UtfToExternalDString\fR converts a source buffer \fIsrc\fR from UTF-8
@@ -228,19 +274,26 @@ is filled with the corresponding number of bytes that were stored in
\fBTcl_WinUtfToTChar\fR and \fBTcl_WinTCharToUtf\fR are
Windows-only convenience
functions for converting between UTF-8 and Windows strings. On Windows 95
-(as with the Macintosh and Unix operating systems),
-all strings exchanged between Tcl and the operating system are "char"
+(as with the Unix operating system),
+all strings exchanged between Tcl and the operating system are
+.QW "char"
based. On Windows NT, some strings exchanged between Tcl and the
-operating system are "char" oriented while others are in Unicode. By
+operating system are
+.QW "char"
+oriented while others are in Unicode. By
convention, in Windows a TCHAR is a character in the ANSI code page
on Windows 95 and a Unicode character on Windows NT.
.PP
-If you planned to use the same "char" based interfaces on both Windows
+If you planned to use the same
+.QW "char"
+based interfaces on both Windows
95 and Windows NT, you could use \fBTcl_UtfToExternal\fR and
\fBTcl_ExternalToUtf\fR (or their \fBTcl_DString\fR equivalents) with an
encoding of NULL (the current system encoding). On the other hand,
if you planned to use the Unicode interface when running on Windows NT
-and the "char" interfaces when running on Windows 95, you would have
+and the
+.QW "char"
+interfaces when running on Windows 95, you would have
to perform the following type of test over and over in your program
(as represented in pseudo-code):
.CS
@@ -250,6 +303,7 @@ if (running NT) {
Tcl_FreeEncoding(encoding);
} else {
nativeBuffer <- Tcl_UtfToExternal(NULL, utfBuffer);
+}
.CE
\fBTcl_WinUtfToTChar\fR and \fBTcl_WinTCharToUtf\fR automatically
handle this test and use the proper encoding based on the current
@@ -269,11 +323,20 @@ was used to create the encoding. The string returned by
whenever the user passes a NULL value for the \fIencoding\fR argument to
any of the other encoding functions. If \fIname\fR is NULL, the system
encoding is reset to the default system encoding, \fBbinary\fR. If the
-name did not refer to any known or loadable encoding, TCL_ERROR is
+name did not refer to any known or loadable encoding, \fBTCL_ERROR\fR is
returned and an error message is left in \fIinterp\fR. Otherwise, this
procedure increments the reference count of the new system encoding,
decrements the reference count of the old system encoding, and returns
-TCL_OK.
+\fBTCL_OK\fR.
+.PP
+.VS 8.5
+\fBTcl_GetEncodingNameFromEnvironment\fR provides a means for the Tcl
+library to report the encoding name it believes to be the correct one
+to use as the system encoding, based on system calls and examination of
+the environment suitable for the platform. It accepts \fIbufPtr\fR,
+a pointer to an uninitialized or freed \fBTcl_DString\fR and writes
+the encoding name to it. The \fBTcl_DStringValue\fR is returned.
+.VE 8.5
.PP
\fBTcl_GetEncodingNames\fR sets the \fIinterp\fR result to a list
consisting of the names of all the encodings that are currently defined
@@ -301,12 +364,12 @@ convert between this encoding and UTF-8. It is defined as follows:
.PP
.CS
typedef struct Tcl_EncodingType {
- CONST char *\fIencodingName\fR;
- Tcl_EncodingConvertProc *\fItoUtfProc\fR;
- Tcl_EncodingConvertProc *\fIfromUtfProc\fR;
- Tcl_EncodingFreeProc *\fIfreeProc\fR;
- ClientData \fIclientData\fR;
- int \fInullSize\fR;
+ const char *\fIencodingName\fR;
+ Tcl_EncodingConvertProc *\fItoUtfProc\fR;
+ Tcl_EncodingConvertProc *\fIfromUtfProc\fR;
+ Tcl_EncodingFreeProc *\fIfreeProc\fR;
+ ClientData \fIclientData\fR;
+ int \fInullSize\fR;
} Tcl_EncodingType;
.CE
.PP
@@ -336,16 +399,16 @@ type \fBTcl_EncodingConvertProc\fR:
.PP
.CS
typedef int Tcl_EncodingConvertProc(
- ClientData \fIclientData\fR,
- CONST char *\fIsrc\fR,
- int \fIsrcLen\fR,
- int \fIflags\fR,
- Tcl_Encoding *\fIstatePtr\fR,
- char *\fIdst\fR,
- int \fIdstLen\fR,
- int *\fIsrcReadPtr\fR,
- int *\fIdstWrotePtr\fR,
- int *\fIdstCharsPtr\fR);
+ ClientData \fIclientData\fR,
+ const char *\fIsrc\fR,
+ int \fIsrcLen\fR,
+ int \fIflags\fR,
+ Tcl_EncodingState *\fIstatePtr\fR,
+ char *\fIdst\fR,
+ int \fIdstLen\fR,
+ int *\fIsrcReadPtr\fR,
+ int *\fIdstWrotePtr\fR,
+ int *\fIdstCharsPtr\fR);
.CE
.PP
The \fItoUtfProc\fR and \fIfromUtfProc\fR procedures are called by the
@@ -367,20 +430,42 @@ The callback procedure \fIfreeProc\fR, if non-NULL, should match the type
\fBTcl_EncodingFreeProc\fR:
.CS
typedef void Tcl_EncodingFreeProc(
- ClientData \fIclientData\fR);
+ ClientData \fIclientData\fR);
.CE
.PP
This \fIfreeProc\fR function is called when the encoding is deleted. The
\fIclientData\fR parameter is the same as the \fIclientData\fR field
specified to \fBTcl_CreateEncoding\fR when the encoding was created.
.PP
-
+.VS 8.5
+\fBTcl_GetEncodingSearchPath\fR and \fBTcl_SetEncodingSearchPath\fR
+are called to access and set the list of filesystem directories searched
+for encoding data files.
+.PP
+The value returned by \fBTcl_GetEncodingSearchPath\fR
+is the value stored by the last successful call to
+\fBTcl_SetEncodingSearchPath\fR. If no calls to
+\fBTcl_SetEncodingSearchPath\fR have occurred, Tcl will compute an initial
+value based on the environment. There is one encoding search path for the
+entire process, shared by all threads in the process.
+.PP
+\fBTcl_SetEncodingSearchPath\fR stores \fIsearchPath\fR and returns
+\fBTCL_OK\fR, unless \fIsearchPath\fR is not a valid Tcl list, which
+causes \fBTCL_ERROR\fR to be returned. The elements of \fIsearchPath\fR
+are not verified as existing readable filesystem directories. When
+searching for encoding data files takes place, and non-existent or
+non-readable filesystem directories on the \fIsearchPath\fR are silently
+ignored.
+.PP
\fBTcl_GetDefaultEncodingDir\fR and \fBTcl_SetDefaultEncodingDir\fR
-access and set the directory to use when locating the default encoding
-files. If this value is not NULL, the \fBTclpInitLibraryPath\fR routine
-appends the path to the head of the search path, and uses this path as
-the first place to look into when trying to locate the encoding file.
-
+are obsolete interfaces best replaced with calls to
+\fBTcl_GetEncodingSearchPath\fR and \fBTcl_SetEncodingSearchPath\fR.
+They are called to access and set the first element of the \fIsearchPath\fR
+list. Since Tcl searches \fIsearchPath\fR for encoding data files in
+list order, these routines establish the
+.QW default
+directory in which to find encoding data files.
+.VE 8.5
.SH "ENCODING FILES"
Space would prohibit precompiling into Tcl every possible encoding
algorithm, so many encodings are stored on disk as dynamically-loadable
@@ -392,23 +477,25 @@ external encoding may consist of single-byte, multi-byte, or double-byte
characters.
.PP
Each dynamically-loadable encoding is represented as a text file. The
-initial line of the file, beginning with a ``#'' symbol, is a comment
+initial line of the file, beginning with a
+.QW #
+symbol, is a comment
that provides a human-readable description of the file. The next line
identifies the type of encoding file. It can be one of the following
letters:
-.IP "[1] \fBS\fR"
+.IP "[1] \fBS\fR"
A single-byte encoding, where one character is always one byte long in the
encoding. An example is \fBiso8859-1\fR, used by many European languages.
-.IP "[2] \fBD\fR"
+.IP "[2] \fBD\fR"
A double-byte encoding, where one character is always two bytes long in the
encoding. An example is \fBbig5\fR, used for Chinese text.
-.IP "[3] \fBM\fR"
+.IP "[3] \fBM\fR"
A multi-byte encoding, where one character may be either one or two bytes long.
-Certain bytes are a lead bytes, indicating that another byte must follow
+Certain bytes are lead bytes, indicating that another byte must follow
and that together the two bytes represent one character. Other bytes are not
lead bytes and represent themselves. An example is \fBshiftjis\fR, used by
many Japanese computers.
-.IP "[4] \fBE\fR"
+.IP "[4] \fBE\fR"
An escape-sequence encoding, specifying that certain sequences of bytes
do not represent characters, but commands that describe how following bytes
should be interpreted.
@@ -478,7 +565,7 @@ and 0x8163 in \fBshiftjis\fR map to 203E and 2026 in Unicode, respectively.
Following the first page will be all the other pages, each in the same
format as the first: one number identifying the page followed by 256
double-byte Unicode characters. If a character in the encoding maps to the
-Unicode character 0000, it means that the character doesn't actually exist.
+Unicode character 0000, it means that the character does not actually exist.
If all characters on a page would map to 0000, that page can be omitted.
.PP
Case [4] is the escape-sequence encoding file. The lines in an this type of
@@ -490,13 +577,13 @@ encoding:
E
init {}
final {}
-iso8859-1 \\x1b(B
-jis0201 \\x1b(J
-jis0208 \\x1b$@
-jis0208 \\x1b$B
-jis0212 \\x1b$(D
-gb2312 \\x1b$A
-ksc5601 \\x1b$(C
+iso8859-1 \ex1b(B
+jis0201 \ex1b(J
+jis0208 \ex1b$@
+jis0208 \ex1b$B
+jis0212 \ex1b$(D
+gb2312 \ex1b$A
+ksc5601 \ex1b$(C
.CE
.PP
In the file, the first column represents an option and the second column
@@ -505,16 +592,16 @@ the first character is converted, while \fBfinal\fR is a string to emit
or expect after the last character. All other options are names of
table-based encodings; the associated value is the escape-sequence that
marks that encoding. Tcl syntax is used for the values; in the above
-example, for instance, ``\fB{}\fR'' represents the empty string and
-``\fB\\x1b\fR'' represents character 27.
+example, for instance,
+.QW \fB{}\fR
+represents the empty string and
+.QW \fB\ex1b\fR
+represents character 27.
.PP
When \fBTcl_GetEncoding\fR encounters an encoding \fIname\fR that has not
been loaded, it attempts to load an encoding file called \fIname\fB.enc\fR
-from the \fBencoding\fR subdirectory of each directory specified in the
-library path \fB$tcl_libPath\fR. If the encoding file exists, but is
+from the \fBencoding\fR subdirectory of each directory that Tcl searches
+for its script library. If the encoding file exists, but is
malformed, an error message will be left in \fIinterp\fR.
.SH KEYWORDS
utf, encoding, convert
-
-
-
diff --git a/doc/Ensemble.3 b/doc/Ensemble.3
new file mode 100644
index 0000000..5a5842d
--- /dev/null
+++ b/doc/Ensemble.3
@@ -0,0 +1,186 @@
+'\"
+'\" Copyright (c) 2005 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" This documents the C API introduced in TIP#235
+'\"
+.so man.macros
+.TH Tcl_Ensemble 3 8.5 Tcl "Tcl Library Procedures"
+.BS
+.SH NAME
+Tcl_CreateEnsemble, Tcl_FindEnsemble, Tcl_GetEnsembleFlags, Tcl_GetEnsembleMappingDict, Tcl_GetEnsembleNamespace, Tcl_GetEnsembleUnknownHandler, Tcl_GetEnsembleSubcommandList, Tcl_IsEnsemble, Tcl_SetEnsembleFlags, Tcl_SetEnsembleMappingDict, Tcl_SetEnsembleSubcommandList, Tcl_SetEnsembleUnknownHandler \- manipulate ensemble commands
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Command
+\fBTcl_CreateEnsemble\fR(\fIinterp, name, namespacePtr, ensFlags\fR)
+.sp
+Tcl_Command
+\fBTcl_FindEnsemble\fR(\fIinterp, cmdNameObj, flags\fR)
+.sp
+int
+\fBTcl_IsEnsemble\fR(\fItoken\fR)
+.sp
+int
+\fBTcl_GetEnsembleFlags\fR(\fIinterp, token, ensFlagsPtr\fR)
+.sp
+int
+\fBTcl_SetEnsembleFlags\fR(\fIinterp, token, ensFlags\fR)
+.sp
+int
+\fBTcl_GetEnsembleMappingDict\fR(\fIinterp, token, dictObjPtr\fR)
+.sp
+int
+\fBTcl_SetEnsembleMappingDict\fR(\fIinterp, token, dictObj\fR)
+.sp
+int
+\fBTcl_GetEnsembleSubcommandList\fR(\fIinterp, token, listObjPtr\fR)
+.sp
+int
+\fBTcl_SetEnsembleSubcommandList\fR(\fIinterp, token, listObj\fR)
+.sp
+int
+\fBTcl_GetEnsembleUnknownHandler\fR(\fIinterp, token, listObjPtr\fR)
+.sp
+int
+\fBTcl_SetEnsembleUnknownHandler\fR(\fIinterp, token, listObj\fR)
+.sp
+int
+\fBTcl_GetEnsembleNamespace\fR(\fIinterp, token, namespacePtrPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_Namespace **namespacePtrPtr in/out
+.AP Tcl_Interp *interp in/out
+The interpreter in which the ensemble is to be created or found. Also
+where error result messages are written. The functions whose names
+start with \fBTcl_GetEnsemble\fR may have a NULL for the \fIinterp\fR,
+but all other functions must not.
+.AP "const char" *name in
+The name of the ensemble command to be created.
+.AP Tcl_Namespace *namespacePtr in
+The namespace to which the ensemble command is to be bound, or NULL
+for the current namespace.
+.AP int ensFlags in
+An ORed set of flag bits describing the basic configuration of the
+ensemble. Currently only one bit has meaning, TCL_ENSEMBLE_PREFIX,
+which is present when the ensemble command should also match
+unambiguous prefixes of subcommands.
+.AP Tcl_Obj *cmdNameObj in
+A value holding the name of the ensemble command to look up.
+.AP int flags in
+An ORed set of flag bits controlling the behavior of
+\fBTcl_FindEnsemble\fR. Currently only TCL_LEAVE_ERR_MSG is supported.
+.AP Tcl_Command token in
+A normal command token that refers to an ensemble command, or which
+you wish to use for testing as an ensemble command in \fBTcl_IsEnsemble\fR.
+.AP int *ensFlagsPtr out
+Pointer to a variable into which to write the current ensemble flag
+bits; currently only the bit TCL_ENSEMBLE_PREFIX is defined.
+.AP Tcl_Obj *dictObj in
+A dictionary value to use for the subcommand to implementation command
+prefix mapping dictionary in the ensemble. May be NULL if the mapping
+dictionary is to be removed.
+.AP Tcl_Obj **dictObjPtr out
+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 defined list of subcommands in the
+dictionary or the unknown subcommmand handler command prefix. May be
+NULL if the subcommand list or unknown handler are to be removed.
+.AP Tcl_Obj **listObjPtr out
+Pointer to a variable into which to write the current defiend list of
+subcommands or the current unknown handler prefix.
+.AP Tcl_Namespace **namespacePtrPtr out
+Pointer to a variable into which to write the handle of the namespace
+to which the ensemble is bound.
+.BE
+
+.SH DESCRIPTION
+An ensemble is a command, bound to some namespace, which consists of a
+collection of subcommands implemented by other Tcl commands. The first
+argument to the ensemble command is always interpreted as a selector
+that states what subcommand to execute.
+.PP
+Ensembles are created using \fBTcl_CreateEnsemble\fR, which takes four
+arguments: the interpreter to work within, the name of the ensemble to
+create, the namespace within the interpreter to bind the ensemble to,
+and the default set of ensemble flags. The result of the function is
+the command token for the ensemble, which may be used to further
+configure the ensemble using the API described below in \fBENSEMBLE
+PROPERTIES\fR.
+.PP
+Given the name of an ensemble command, the token for that command may
+be retrieved using \fBTcl_FindEnsemble\fR. If the given command name
+(in \fIcmdNameObj\fR) does not refer to an ensemble command, the
+result of the function is NULL and (if the TCL_LEAVE_ERR_MSG bit is
+set in \fIflags\fR) an error message is left in the interpreter
+result.
+.PP
+A command token may be checked to see if it refers to an ensemble
+using \fBTcl_IsEnsemble\fR. This returns 1 if the token refers to an
+ensemble, or 0 otherwise.
+.SS "ENSEMBLE PROPERTIES"
+Every ensemble has four read-write properties and a read-only
+property. The properties are:
+.TP
+\fBflags\fR (read-write)
+The set of flags for the ensemble, expressed as a
+bit-field. Currently, the only public flag is TCL_ENSEMBLE_PREFIX
+which is set when unambiguous prefixes of subcommands are permitted to
+be resolved to implementations as well as exact matches. The flags may
+be read and written using \fBTcl_GetEnsembleFlags\fR and
+\fBTcl_SetEnsembleFlags\fR respectively. The result of both of those
+functions is a Tcl result code (TCL_OK, or TCL_ERROR if the token does
+not refer to an ensemble).
+.TP
+\fBmapping dictionary\fR (read-write)
+A dictionary containing a mapping from subcommand names to lists of
+words to use as a command prefix (replacing the first two words of the
+command which are the ensemble command itself and the subcommand
+name), or NULL if every subcommand is to be mapped to the command with
+the same unqualified name in the ensemble's bound namespace. Defaults
+to NULL. May be read and written using
+\fBTcl_GetEnsembleMappingDict\fR and \fBTcl_SetEnsembleMappingDict\fR
+respectively. The result of both of those functions is a Tcl result
+code (TCL_OK, or TCL_ERROR 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.
+.TP
+\fBsubcommand list\fR (read-write)
+A list of all the subcommand names for the ensemble, or NULL if this
+is to be derived from either the keys of the mapping dictionary (see
+above) or (if that is also NULL) from the set of commands exported by
+the bound namespace. May be read and written using
+\fBTcl_GetEnsembleSubcommandList\fR and
+\fBTcl_SetEnsembleSubcommandList\fR respectively. The result of both
+of those functions is a Tcl result code (TCL_OK, or TCL_ERROR if the
+token does not refer to an ensemble) and the list obtained from
+\fBTcl_GetEnsembleSubcommandList\fR should always be treated as
+immutable even if it is unshared.
+.TP
+\fBunknown subcommand handler command prefix\fR (read-write)
+A list of words to prepend on the front of any subcommand when the
+subcommand is unknown to the ensemble (according to the current prefix
+handling rule); see the \fBnamespace ensemble\fR command for more
+details. If NULL, the default behavior \- generate a suitable error
+message \- will be used when an unknown subcommand is encountered. May
+be read and written using \fBTcl_GetEnsembleUnknownHandler\fR and
+\fBTcl_SetEnsembleUnknownHandler\fR respectively. The result of both
+functions is a Tcl result code (TCL_OK, or TCL_ERROR if the token does
+not refer to an ensemble) and the list obtained from
+\fBTcl_GetEnsembleUnknownHandler\fR should always be treated as
+immutable even if it is unshared.
+.TP
+\fBbound namespace\fR (read-only)
+The namespace to which the ensemble is bound; when the namespace is
+deleted, so too will the ensemble, and this namespace is also the
+namespace whose list of exported commands is used if both the mapping
+dictionary and the subcommand list properties are NULL. May be read
+using \fBTcl_GetEnsembleNamespace\fR which returns a Tcl result code
+(TCL_OK, or TCL_ERROR if the token does not refer to an ensemble).
+
+.SH "SEE ALSO"
+namespace(n), Tcl_DeleteCommandFromToken(3)
diff --git a/doc/Environment.3 b/doc/Environment.3
index 7f92d48..3753f43 100644
--- a/doc/Environment.3
+++ b/doc/Environment.3
@@ -14,21 +14,25 @@ Tcl_PutEnv \- procedures to manipulate the environment
\fB#include <tcl.h>\fR
.sp
int
-\fBTcl_PutEnv\fR(\fIstring\fR)
+\fBTcl_PutEnv\fR(\fIassignment\fR)
.SH ARGUMENTS
-.AP "CONST char" *string in
-Info about environment variable in the form NAME=value.
-The \fIstring\fR argument is in the system encoding.
+.AS "const char" *assignment
+.AP "const char" *assignment in
+Info about environment variable in the format
+.QW \fINAME\fB=\fIvalue\fR .
+The \fIassignment\fR argument is in the system encoding.
.BE
-
.SH DESCRIPTION
.PP
\fBTcl_PutEnv\fR sets an environment variable. The information is
-passed in a single string of the form NAME=value. This procedure is
+passed in a single string of the form
+.QW \fINAME\fB=\fIvalue\fR .
+This procedure is
intended to be a stand-in for the UNIX \fBputenv\fR system call. All
-tcl-based applications using \fBputenv\fR should redefine it to
+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)
.SH KEYWORDS
environment, variable
diff --git a/doc/Eval.3 b/doc/Eval.3
index 1efe270..f232cad 100644
--- a/doc/Eval.3
+++ b/doc/Eval.3
@@ -15,7 +15,6 @@ Tcl_EvalObjEx, Tcl_EvalFile, Tcl_EvalObjv, Tcl_Eval, Tcl_EvalEx, Tcl_GlobalEval,
.nf
\fB#include <tcl.h>\fR
.sp
-.VS
int
\fBTcl_EvalObjEx\fR(\fIinterp, objPtr, flags\fR)
.sp
@@ -38,12 +37,12 @@ int
\fBTcl_GlobalEvalObj\fR(\fIinterp, objPtr\fR)
.sp
int
-\fBTcl_VarEval\fR(\fIinterp, string, string, ... \fB(char *) NULL\fR)
+\fBTcl_VarEval\fR(\fIinterp, part, part, ... \fB(char *) NULL\fR)
.sp
int
\fBTcl_VarEvalVA\fR(\fIinterp, argList\fR)
.SH ARGUMENTS
-.AS Tcl_Interp **termPtr;
+.AS Tcl_Interp **termPtr
.AP Tcl_Interp *interp in
Interpreter in which to execute the script. The interpreter's result is
modified to hold the result or error message from the script.
@@ -52,7 +51,7 @@ A Tcl object 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
+.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;
@@ -64,13 +63,13 @@ value of a single word in the command to execute.
The number of bytes in \fIscript\fR, not including any
null terminating character. If \-1, then all characters up to the
first null byte are used.
-.AP "CONST char" *script in
+.AP "const char" *script in
Points to first byte of script to execute (null-terminated and UTF-8).
-.AP char *string in
+.AP char *part in
String forming part of a Tcl script.
.AP va_list argList in
-An argument list which must have been initialised using
-\fBTCL_VARARGS_START\fR, and cleared using \fBva_end\fR.
+An argument list which must have been initialized using
+\fBva_start\fR, and cleared using \fBva_end\fR.
.BE
.SH DESCRIPTION
@@ -97,26 +96,33 @@ result; it can be retrieved using \fBTcl_GetObjResult\fR.
\fBTcl_EvalFile\fR reads the file given by \fIfileName\fR and evaluates
its contents as a Tcl script. It returns the same information as
\fBTcl_EvalObjEx\fR.
-If the file couldn't be read then a Tcl error is returned to describe
-why the file couldn't be read.
-.VS 8.4
-The eofchar for files is '\\32' (^Z) for all platforms.
-If you require a ``^Z'' in code for string comparison, you can use
-``\\032'' or ``\\u001a'', which will be safely substituted by the Tcl
-interpreter into ``^Z''.
-.VE 8.4
+If the file could not be read then a Tcl error is returned to describe
+why the file could not be read.
+The eofchar for files is
+.QW \e32
+(^Z) for all platforms. If you require a
+.QW ^Z
+in code for string comparison, you can use
+.QW \e032
+or
+.QW \eu001a ,
+which will be safely substituted by the Tcl interpreter into
+.QW ^Z .
.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
\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
+\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
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 who's possible combinations
+to possibly contain upper ASCII characters whose possible combinations
might be a UTF-8 special code. The string is parsed and executed directly
(using \fBTcl_EvalObjv\fR) instead of compiling it and executing the
bytecodes. In situations where it is known that the script will never be
@@ -126,7 +132,7 @@ executed again, \fBTcl_Eval\fR may be faster than \fBTcl_EvalObjEx\fR.
Tcl 8.0, \fBTcl_Eval\fR copies the object 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
-doesn't do the copy.
+does not do the copy.
.PP
\fBTcl_EvalEx\fR is an extended version of \fBTcl_Eval\fR that takes
additional arguments \fInumBytes\fR and \fIflags\fR. For the
@@ -163,8 +169,8 @@ 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
-bytecodes won't be reused in a future execution. In this case,
-it's faster to execute the script directly.
+bytecodes will not be reused in a future execution. In this case,
+it is faster to execute the script directly.
.TP 23
\fBTCL_EVAL_GLOBAL\fR
If this flag is set, the script is processed at global level. This
@@ -197,7 +203,6 @@ the \fBreturn\fR, \fBbreak\fR, or \fBcontinue\fR command was
invoked in an inappropriate place.
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.
-.VE
.SH KEYWORDS
execute, file, global, object, result, script
diff --git a/doc/Exit.3 b/doc/Exit.3
index a281829..aa69b47 100644
--- a/doc/Exit.3
+++ b/doc/Exit.3
@@ -5,10 +5,10 @@
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.so man.macros
-.TH Tcl_Exit 3 8.1 Tcl "Tcl Library Procedures"
+.TH Tcl_Exit 3 8.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
-Tcl_Exit, Tcl_Finalize, Tcl_CreateExitHandler, Tcl_DeleteExitHandler, Tcl_ExitThread, Tcl_FinalizeThread, Tcl_CreateThreadExitHandler, Tcl_DeleteThreadExitHandler \- end the application or thread (and invoke exit handlers)
+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)
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -28,6 +28,11 @@ Tcl_Exit, Tcl_Finalize, Tcl_CreateExitHandler, Tcl_DeleteExitHandler, Tcl_ExitTh
\fBTcl_CreateThreadExitHandler\fR(\fIproc, clientData\fR)
.sp
\fBTcl_DeleteThreadExitHandler\fR(\fIproc, clientData\fR)
+.sp
+.VS 8.5
+Tcl_ExitProc *
+\fBTcl_SetExitProc\fR(\fIproc\fR)
+.VE 8.5
.SH ARGUMENTS
.AS Tcl_ExitProc clientData
.AP int status in
@@ -36,7 +41,9 @@ Exact meaning may
be platform-specific. 0 usually means a normal exit, any nonzero value
usually means that an error occurred.
.AP Tcl_ExitProc *proc in
-Procedure to invoke before exiting application.
+Procedure to invoke before exiting application, or (for
+\fBTcl_SetExitProc\fR) NULL to uninstall the current application exit
+procedure.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIproc\fR.
.BE
@@ -57,6 +64,12 @@ otherwise causes the application to terminate without calling
\fBTcl_Exit\fR, the exit handlers will not be run.
\fBTcl_Exit\fR internally invokes the \fBexit\fR system call, thus it never
returns control to its caller.
+.VS 8.5
+If an application exit handler has been installed (see
+\fBTcl_SetExitProc\fR), that handler is invoked with an argument
+consisting of the exit status (cast to ClientData); the application
+exit handler should not return control to Tcl.
+.VE 8.5
.PP
\fBTcl_Finalize\fR is similar to \fBTcl_Exit\fR except that it does not
exit from the current process.
@@ -71,14 +84,12 @@ However, to ensure portability, your code should always invoke
code will work on all platforms. \fBTcl_Finalize\fR can be safely called
more than once.
.PP
-.VS
\fBTcl_ExitThread\fR is used to terminate the current thread and invoke
per-thread exit handlers. This finalization is done by
\fBTcl_FinalizeThread\fR, which you can call if you just want to clean
up per-thread state and invoke the thread exit handlers.
\fBTcl_Finalize\fR calls \fBTcl_FinalizeThread\fR for the current
thread automatically.
-.VE
.PP
\fBTcl_CreateExitHandler\fR arranges for \fIproc\fR to be invoked
by \fBTcl_Finalize\fR and \fBTcl_Exit\fR.
@@ -105,7 +116,6 @@ indicated by \fIproc\fR and \fIclientData\fR so that no call
to \fIproc\fR will be made. If no such handler exists then
\fBTcl_DeleteExitHandler\fR or \fBTcl_DeleteThreadExitHandler\fR does nothing.
.PP
-.VS
.PP
\fBTcl_Finalize\fR and \fBTcl_Exit\fR execute all registered exit handlers,
in reverse order from the order in which they were registered.
@@ -115,15 +125,23 @@ unloads \fBB\fR before it itself is unloaded.
If extension \fBA\fR registers its exit handlers before loading extension
\fBB\fR, this ensures that any exit handlers for \fBB\fR will be executed
before the exit handlers for \fBA\fR.
-.VE
-.VS
.PP
\fBTcl_Finalize\fR and \fBTcl_Exit\fR call \fBTcl_FinalizeThread\fR
and the thread exit handlers \fIafter\fR
the process-wide exit handlers. This is because thread finalization shuts
down the I/O channel system, so any attempt at I/O by the global exit
handlers will vanish into the bitbucket.
-.VE
+.PP
+.VS 8.5
+\fBTcl_SetExitProc\fR installs an application exit handler, returning
+the previously-installed application exit handler or NULL if no
+application handler was installed. If an application exit handler is
+installed, that exit handler takes over complete responsibility for
+finalization of Tcl's subsystems via \fBTcl_Finalize\fR at an
+appropriate time. The argument passed to \fIproc\fR when it is
+invoked will be the exit status code (as passed to \fBTcl_Exit\fR)
+cast to a ClientData value.
+.VE 8.5
.SH KEYWORDS
callback, cleanup, dynamic loading, end application, exit, unloading, thread
diff --git a/doc/ExprLong.3 b/doc/ExprLong.3
index ead98f5..ef93284 100644
--- a/doc/ExprLong.3
+++ b/doc/ExprLong.3
@@ -15,23 +15,21 @@ Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean, Tcl_ExprString \- evaluate an exp
\fB#include <tcl.h>\fR
.sp
int
-\fBTcl_ExprLong\fR(\fIinterp, string, longPtr\fR)
+\fBTcl_ExprLong\fR(\fIinterp, expr, longPtr\fR)
.sp
int
-\fBTcl_ExprDouble\fR(\fIinterp, string, doublePtr\fR)
+\fBTcl_ExprDouble\fR(\fIinterp, expr, doublePtr\fR)
.sp
int
-\fBTcl_ExprBoolean\fR(\fIinterp, string, booleanPtr\fR)
+\fBTcl_ExprBoolean\fR(\fIinterp, expr, booleanPtr\fR)
.sp
int
-\fBTcl_ExprString\fR(\fIinterp, string\fR)
+\fBTcl_ExprString\fR(\fIinterp, expr\fR)
.SH ARGUMENTS
-.AS Tcl_Interp *booleanPtr
+.AS Tcl_Interp *booleanPtr out
.AP Tcl_Interp *interp in
-Interpreter in whose context to evaluate \fIstring\fR.
-.VS 8.4
-.AP "CONST char" *string in
-.VE
+Interpreter in whose context to evaluate \fIexpr\fR.
+.AP "const char" *expr in
Expression to be evaluated.
.AP long *longPtr out
Pointer to location in which to store the integer value of the
@@ -47,7 +45,7 @@ expression.
.SH DESCRIPTION
.PP
These four procedures all evaluate the expression
-given by the \fIstring\fR argument
+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
@@ -92,7 +90,11 @@ number, then they store 0 at \fI*booleanPtr\fR if
the value was zero and 1 otherwise.
If the expression's actual value is a non-numeric string then
it must be one of the values accepted by \fBTcl_GetBoolean\fR
-such as ``yes'' or ``no'', or else an error occurs.
+such as
+.QW yes
+or
+.QW no ,
+or else an error occurs.
.PP
\fBTcl_ExprString\fR returns the value of the expression as a
string stored in the interpreter's result.
diff --git a/doc/ExprLongObj.3 b/doc/ExprLongObj.3
index c3e9697..c8a564d 100644
--- a/doc/ExprLongObj.3
+++ b/doc/ExprLongObj.3
@@ -86,7 +86,11 @@ number, then they store 0 at \fI*booleanPtr\fR if
the value was zero and 1 otherwise.
If the expression's actual value is a non-numeric string then
it must be one of the values accepted by \fBTcl_GetBoolean\fR
-such as ``yes'' or ``no'', or else an error occurs.
+such as
+.QW yes
+or
+.QW no ,
+or else an error occurs.
.PP
If \fBTcl_ExprObj\fR successfully evaluates the expression,
it stores a pointer to the Tcl object
diff --git a/doc/FileSystem.3 b/doc/FileSystem.3
index 7475989..32407d8 100644
--- a/doc/FileSystem.3
+++ b/doc/FileSystem.3
@@ -8,7 +8,7 @@
.TH Filesystem 3 8.4 Tcl "Tcl Library Procedures"
.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_FSLoadFile, 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_AllocStatBuf \- procedures to interact with any filesystem
+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_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_AllocStatBuf \- procedures to interact with any filesystem
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -26,10 +26,10 @@ void
\fBTcl_FSMountsChanged\fR(\fIfsPtr\fR)
.sp
Tcl_Filesystem*
-\fBTcl_FSGetFileSystemForPath\fR(\fIpathObjPtr\fR)
+\fBTcl_FSGetFileSystemForPath\fR(\fIpathPtr\fR)
.sp
Tcl_PathType
-\fBTcl_FSGetPathType\fR(\fIpathObjPtr\fR)
+\fBTcl_FSGetPathType\fR(\fIpathPtr\fR)
.sp
int
\fBTcl_FSCopyFile\fR(\fIsrcPathPtr, destPathPtr\fR)
@@ -52,6 +52,11 @@ int
Tcl_Obj*
\fBTcl_FSListVolumes\fR(\fIvoid\fR)
.sp
+.VS 8.5
+int
+\fBTcl_FSEvalFileEx\fR(\fIinterp, pathPtr, encodingName\fR)
+.VE 8.5
+.sp
int
\fBTcl_FSEvalFile\fR(\fIinterp, pathPtr\fR)
.sp
@@ -60,7 +65,7 @@ int
handlePtr, unloadProcPtr\fR)
.sp
int
-\fBTcl_FSMatchInDirectory\fR(\fIinterp, result, pathPtr, pattern, types\fR)
+\fBTcl_FSMatchInDirectory\fR(\fIinterp, resultPtr, pathPtr, pattern, types\fR)
.sp
Tcl_Obj*
\fBTcl_FSLink\fR(\fIlinkNamePtr, toPtr, linkAction\fR)
@@ -77,7 +82,7 @@ int
int
\fBTcl_FSFileAttrsSet\fR(\fIinterp, int index, pathPtr, Tcl_Obj *objPtr\fR)
.sp
-CONST char**
+const char**
\fBTcl_FSFileAttrStrings\fR(\fIpathPtr, objPtrRef\fR)
.sp
int
@@ -86,7 +91,7 @@ int
int
\fBTcl_FSAccess\fR(\fIpathPtr, mode\fR)
.sp
-Tcl_Channel
+Tcl_Channel
\fBTcl_FSOpenFileChannel\fR(\fIinterp, pathPtr, modeString, permissions\fR)
.sp
Tcl_Obj*
@@ -116,19 +121,19 @@ Tcl_Obj*
int
\fBTcl_FSConvertToPathType\fR(\fIinterp, pathPtr\fR)
.sp
-ClientData
+ClientData
\fBTcl_FSGetInternalRep\fR(\fIpathPtr, fsPtr\fR)
.sp
-Tcl_Obj*
+Tcl_Obj *
\fBTcl_FSGetTranslatedPath\fR(\fIinterp, pathPtr\fR)
.sp
-CONST char*
+const char *
\fBTcl_FSGetTranslatedStringPath\fR(\fIinterp, pathPtr\fR)
.sp
Tcl_Obj*
\fBTcl_FSNewNativePath\fR(\fIfsPtr, clientData\fR)
.sp
-CONST char*
+const char *
\fBTcl_FSGetNativePath\fR(\fIpathPtr\fR)
.sp
Tcl_Obj*
@@ -137,7 +142,7 @@ Tcl_Obj*
Tcl_StatBuf*
\fBTcl_AllocStatBuf\fR()
.SH ARGUMENTS
-.AS Tcl_Filesystem *fsPtr in
+.AS Tcl_FSUnloadFileProc **unloadProcPtr out
.AP Tcl_Filesystem *fsPtr in
Points to a structure containing the addresses of procedures that
can be called to perform the various filesystem operations.
@@ -146,21 +151,21 @@ The path represented by this object is used for the operation in
question. If the object does not already have an internal \fBpath\fR
representation, it will be converted to have one.
.AP Tcl_Obj *srcPathPtr in
-As for \fBpathPtr\fR, but used for the source file for a copy or
+As for \fIpathPtr\fR, but used for the source file for a copy or
rename operation.
.AP Tcl_Obj *destPathPtr in
-As for \fBpathPtr\fR, but used for the destination filename for a copy or
+As for \fIpathPtr\fR, but used for the destination filename for a copy or
rename operation.
-.AP "CONST char" *pattern in
-Only files or directories matching this pattern will be returned by
-\fBTcl_FSMatchInDirectory\fR.
-.AP GlobTypeData *types in
+.AP "const char" *encodingName in
+The encoding of the data stored in the
+file identified by \fIpathPtr\fR and to be evaluated.
+.AP "const char" *pattern in
+Only files or directories matching this pattern will be returned.
+.AP Tcl_GlobTypeData *types in
Only files or directories matching the type descriptions contained in
-this structure will be returned by \fBTcl_FSMatchInDirectory\fR. It
-is very important that the 'directory' flag is properly handled.
-This parameter may be NULL.
+this structure will be returned. This parameter may be NULL.
.AP Tcl_Interp *interp in
-Interpreter to use either for results, evaluation, or reporting error
+Interpreter to use either for results, evaluation, or reporting error
messages.
.AP ClientData clientData in
The native description of the path object to create.
@@ -173,17 +178,17 @@ to \fBpath\fR type.
.AP Tcl_Obj *listObj in
The list of path elements to operate on with a \fBjoin\fR operation.
.AP int elements in
-If non-negative, the number of elements in the listObj which should
+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
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.
-.AP Tcl_Obj *result out
-Pre-allocated object in which to store (by lappending) the list of
-files or directories which are successfully matched in
-\fBTcl_FSMatchInDirectory\fR.
+.AP Tcl_Obj *resultPtr out
+Pre-allocated object in which to store (using
+\fBTcl_ListObjAppendElement\fR) the list of
+files or directories which are successfully matched.
.AP int mode in
Mask consisting of one or more of R_OK, W_OK, X_OK and F_OK. R_OK,
W_OK and X_OK request checking whether the file exists and has read,
@@ -191,25 +196,25 @@ write and execute permissions, respectively. F_OK just requests
checking for the existence of the file.
.AP Tcl_StatBuf *statPtr out
The structure that contains the result of a stat or lstat operation.
-.AP "CONST char" *sym1 in
+.AP "const char" *sym1 in
Name of a procedure to look up in the file's symbol table
-.AP "CONST char" *sym2 in
+.AP "const char" *sym2 in
Name of a procedure to look up in the file's symbol table
.AP Tcl_PackageInitProc **proc1Ptr out
Filled with the init function for this code.
.AP Tcl_PackageInitProc **proc2Ptr out
Filled with the safe-init function for this code.
-.AP Tcl_LoadHandle *handlePtr out
-Filled with an abstract token representing the loaded file.
.AP ClientData *clientDataPtr out
Filled with the clientData value to pass to this code's unload
function when it is called.
-.AP TclfsUnloadFileProc_ **unloadProcPtr out
+.AP Tcl_LoadHandle *handlePtr out
+Filled with an abstract token representing the loaded file.
+.AP Tcl_FSUnloadFileProc **unloadProcPtr out
Filled with the function to use to unload this piece of code.
.AP utimbuf *tval in
-The access and modification times in this structure are read and
+The access and modification times in this structure are read and
used to set those values for a given file.
-.AP "CONST char" *modeString in
+.AP "const char" *modeString in
Specifies how the file is to be accessed. May have any of the values
allowed for the \fImode\fR argument to the Tcl \fBopen\fR command.
.AP int permissions in
@@ -221,151 +226,215 @@ If non-NULL, filled with the number of elements in the split path.
The base path on to which to join the given elements. May be NULL.
.AP int objc in
The number of elements in \fIobjv\fR.
-.AP "Tcl_Obj *CONST" objv[] in
+.AP "Tcl_Obj *const" objv[] in
The elements to join to the given base path.
+.AP Tcl_Obj *linkNamePtr in
+The name of the link to be created or read.
+.AP Tcl_Obj *toPtr in
+What the link called \fIlinkNamePtr\fR should be linked to, or NULL if
+the symbolic link specified by \fIlinkNamePtr\fR is to be read.
+.AP int linkAction in
+OR-ed combination of flags indicating what kind of link should be
+created (will be ignored if \fItoPtr\fR is NULL). Valid bits to set
+are \fBTCL_CREATE_SYMBOLIC_LINK\fR and \fBTCL_CREATE_HARD_LINK\fR.
+When both flags are set and the underlying filesystem can do either,
+symbolic links are preferred.
.BE
.SH DESCRIPTION
.PP
-There are several reasons for calling the \fBTcl_FS...\fR functions
+There are several reasons for calling the \fBTcl_FS\fR API functions
+(e.g. \fBTcl_FSAccess\fR and \fBTcl_FSStat\fR)
rather than calling system level functions like \fBaccess\fR and
\fBstat\fR directly. First, they will work cross-platform, so an
-extension which calls them should work unmodified on Unix, MacOS and
+extension which calls them should work unmodified on Unix and
Windows. Second, the Windows implementation of some of these functions
fixes some bugs in the system level calls. Third, these function calls
-deal with any 'Utf to platform-native' path conversions which may be
+deal with any
+.QW "Utf to platform-native"
+path conversions which may be
required (and may cache the results of such conversions for greater
efficiency on subsequent calls). Fourth, and perhaps most importantly,
-all of these functions are 'virtual filesystem aware'. Any virtual
-filesystem which has been registered (through
+all of these functions are
+.QW "virtual filesystem aware" .
+Any virtual filesystem (VFS for short) which has been registered (through
\fBTcl_FSRegister\fR) may reroute file access to alternative
media or access methods. This means that all of these functions (and
therefore the corresponding \fBfile\fR, \fBglob\fR, \fBpwd\fR, \fBcd\fR,
-\fBopen\fR, etc. Tcl commands) may be operate on 'files' which are not
+\fBopen\fR, etc. Tcl commands) may be operate on
+.QW files
+which are not
native files in the native filesystem. This also means that any Tcl
-extension which accesses the filesystem through this API is
-automatically 'virtual filesystem aware'. Of course, if an extension
+extension which accesses the filesystem (FS for short) through this API is
+automatically
+.QW "virtual filesystem aware" .
+Of course, if an extension
accesses the native filesystem directly (through platform-specific
-APIs, for example), then Tcl cannot intercept such calls.
+APIs, for example), then Tcl cannot intercept such calls.
.PP
-If appropriate vfs's have been registered, the 'files' may, to give two
+If appropriate VFSes have been registered, the
+.QW files
+may, to give two
examples, be remote (e.g. situated on a remote ftp server) or archived
(e.g. lying inside a .zip archive). Such registered filesystems provide
a lookup table of functions to implement all or some of the functionality
listed here. Finally, the \fBTcl_FSStat\fR and \fBTcl_FSLstat\fR calls
-abstract away from what the 'struct stat' buffer buffer is actually
+abstract away from what the
+.QW "struct stat"
+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 are objectified and may cache internal
+The \fBTcl_FS\fR API is objectified 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
-with a refCount of zero to any of these functions. If such calls were
+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 refCount of
-zero - it may have been incremented), or in a direct segfault
+that after any of these calls return, the object 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
manipulation required to ensure that the path is fully normalized and
absolute for filesystem determination. The practical lesson to learn
-from this is that \fBTcl_Obj *path = Tcl_NewStringObj(...) ;
-Tcl_FS...(path) ; Tcl_DecrRefCount(path)\fR is wrong, and may segfault.
-The 'path' must have its refCount incremented before passing it in, or
-decrementing it. For this reason, objects with a refCount of zero are
+from this is that
+.CS
+Tcl_Obj *path = Tcl_NewStringObj(...);
+Tcl_FS\fIWhatever\fR(path);
+Tcl_DecrRefCount(path);
+.CE
+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
considered not to be valid filesystem paths and calling any Tcl_FS API
-with such an object will result in no action being taken.
-.PP
-\fBTcl_FSCopyFile\fR attempts to copy the file given by srcPathPtr to the
-path name given by destPathPtr. If the two paths given lie in the same
+function with such an object 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
filesystem (according to \fBTcl_FSGetFileSystemForPath\fR) then that
-filesystem's 'copy file' function is called (if it is non-NULL).
-Otherwise the function returns -1 and sets Tcl's errno to the 'EXDEV'
-posix error code (which signifies a 'cross-domain link').
-.PP
-\fBTcl_FSCopyDirectory\fR attempts to copy the directory given by srcPathPtr to the
-path name given by destPathPtr. If the two paths given lie in the same
+filesystem's
+.QW "copy file"
+function is called (if it is non-NULL).
+Otherwise the function returns -1 and sets the \fBerrno\fR global C
+variable to the
+.QW EXDEV
+POSIX error code (which signifies a
+.QW "cross-domain link" ).
+.PP
+\fBTcl_FSCopyDirectory\fR attempts to copy the directory given by \fIsrcPathPtr\fR to the
+path name given by \fIdestPathPtr\fR. If the two paths given lie in the same
filesystem (according to \fBTcl_FSGetFileSystemForPath\fR) then that
-filesystem's 'copy file' function is called (if it is non-NULL).
-Otherwise the function returns -1 and sets Tcl's errno to the 'EXDEV'
-posix error code (which signifies a 'cross-domain link').
+filesystem's
+.QW "copy file"
+function is called (if it is non-NULL).
+Otherwise the function returns -1 and sets the \fBerrno\fR global C
+variable to the
+.QW EXDEV
+POSIX error code (which signifies a
+.QW "cross-domain link" ).
.PP
\fBTcl_FSCreateDirectory\fR attempts to create the directory given by
-pathPtr by calling the owning filesystem's 'create directory'
+\fIpathPtr\fR by calling the owning filesystem's
+.QW "create directory"
function.
.PP
\fBTcl_FSDeleteFile\fR attempts to delete the file given by
-pathPtr by calling the owning filesystem's 'delete file'
+\fIpathPtr\fR by calling the owning filesystem's
+.QW "delete file"
function.
.PP
\fBTcl_FSRemoveDirectory\fR attempts to remove the directory given by
-pathPtr by calling the owning filesystem's 'remove directory'
+\fIpathPtr\fR by calling the owning filesystem's
+.QW "remove directory"
function.
.PP
\fBTcl_FSRenameFile\fR attempts to rename the file or directory given by
-srcPathPtr to the path name given by destPathPtr. If the two paths
+\fIsrcPathPtr\fR to the path name given by \fIdestPathPtr\fR. If the two paths
given lie in the same filesystem (according to
-\fBTcl_FSGetFileSystemForPath\fR) then that filesystem's 'rename file'
+\fBTcl_FSGetFileSystemForPath\fR) then that filesystem's
+.QW "rename file"
function is called (if it is non-NULL). Otherwise the function returns -1
-and sets Tcl's errno to the 'EXDEV' posix error code (which signifies
-a ``cross-domain link'').
-.PP
-\fBTcl_FSListVolumes\fR calls each filesystem which has a non-NULL 'list
-volumes' function and asks them to return their list of root volumes. It
+and sets the \fBerrno\fR global C variable to the
+.QW EXDEV
+POSIX error code (which signifies a
+.QW "cross-domain link" ).
+.PP
+\fBTcl_FSListVolumes\fR calls each filesystem which has a non-NULL
+.QW "list volumes"
+function and asks them to return their list of root volumes. It
accumulates the return values in a list which is returned to the
-caller (with a refCount of 0).
+caller (with a reference count of 0).
.PP
-\fBTcl_FSEvalFile\fR reads the file given by \fIpathPtr\fR and evaluates
+.VS 8.5
+\fBTcl_FSEvalFileEx\fR reads the file given by \fIpathPtr\fR using
+the encoding identified by \fIencodingName\fR and evaluates
its contents as a Tcl script. It returns the same information as
\fBTcl_EvalObjEx\fR.
-If the file couldn't be read then a Tcl error is returned to describe
-why the file couldn't be read.
-The eofchar for files is '\\32' (^Z) for all platforms.
-If you require a ``^Z'' in code for string comparison, you can use
-``\\032'' or ``\\u001a'', which will be safely substituted by the Tcl
-interpreter into ``^Z''.
+If \fIencodingName\fR is NULL, the system encoding is used for
+reading the file contents.
+If the file could not be read then a Tcl error is returned to describe
+why the file could not be read.
+The eofchar for files is
+.QW \e32
+(^Z) for all platforms.
+If you require a
+.QW ^Z
+in code for string comparison, you can use
+.QW \e032
+or
+.QW \eu001a ,
+which will be safely substituted by the Tcl interpreter into
+.QW ^Z .
+\fBTcl_FSEvalFile\fR is a simpler version of
+\fBTcl_FSEvalFileEx\fR that always uses the system encoding
+when reading the file.
+.VE 8.5
.PP
\fBTcl_FSLoadFile\fR dynamically loads a binary code file into memory and
returns the addresses of two procedures within that file, if they are
-defined. The appropriate function for the filesystem to which pathPtr
+defined. The appropriate function for the filesystem to which \fIpathPtr\fR
belongs will be called. If that filesystem does not implement this
function (most virtual filesystems will not, because of OS limitations
in dynamically loading binary code), Tcl will attempt to copy the file
to a temporary directory and load that temporary file.
.PP
Returns a standard Tcl completion code. If an error occurs, an error
-message is left in the interp's result.
+message is left in the \fIinterp\fR's result.
.PP
\fBTcl_FSMatchInDirectory\fR is used by the globbing code to search a
directory for all files which match a given pattern. The appropriate
-function for the filesystem to which pathPtr belongs will be called.
+function for the filesystem to which \fIpathPtr\fR belongs will be called.
.PP
The return value is a standard Tcl result indicating whether an error
-occurred in globbing. Error messages are placed in interp, but good
-results are placed in the resultPtr given.
-
-Note that the 'glob' code implements recursive patterns internally, so
+occurred in globbing. Error messages are placed in interp (unless
+interp is NULL, which is allowed), but good results are placed in the
+resultPtr given.
+.PP
+Note that the \fBglob\fR code implements recursive patterns internally, so
this function will only ever be passed simple patterns, which can be
-matched using the logic of 'string match'. To handle recursion, Tcl
+matched using the logic of \fBstring match\fR. To handle recursion, Tcl
will call this function frequently asking only for directories to be
-returned.
+returned. A special case of being called with a NULL pattern indicates
+that the path needs to be checked only for the correct type.
.PP
-\fBTcl_FSLink\fR replaces the library version of readlink(), and
-extends it to support the creation of links. The appropriate function
-for the filesystem to which linkNamePtr belongs will be called.
+\fBTcl_FSLink\fR replaces the library version of \fBreadlink\fR, and
+extends it to support the creation of links. The appropriate function
+for the filesystem to which \fIlinkNamePtr\fR belongs will be called.
.PP
-If the \fItoPtr\fR is NULL, a readlink action is performed. The result
+If the \fItoPtr\fR is NULL, a
+.QW "read link"
+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
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 or'd combination of TCL_CREATE_SYMBOLIC_LINK and TCL_CREATE_HARD_LINK.
+an ORed combination of \fBTCL_CREATE_SYMBOLIC_LINK\fR and \fBTCL_CREATE_HARD_LINK\fR.
Where a choice exists (i.e. more than one flag is passed in), the Tcl
convention is to prefer symbolic links. When a link is successfully
created, the return value should be \fItoPtr\fR (which is therefore
-already owned by the caller). If unsuccessful, NULL should be
-returned.
+already owned by the caller). If unsuccessful, NULL is returned.
.PP
\fBTcl_FSLstat\fR fills the stat structure \fIstatPtr\fR with information
about the specified file. You do not need any access rights to the
@@ -381,43 +450,49 @@ If \fIpath\fR exists, \fBTcl_FSLstat\fR returns 0 and the stat structure
is filled with data. Otherwise, -1 is returned, and no stat info is
given.
.PP
-\fBTcl_FSUtime\fR replaces the library version of utime.
+\fBTcl_FSUtime\fR replaces the library version of utime.
+.PP
+This returns 0 on success and -1 on error (as per the \fButime\fR
+documentation). If successful, the function
+will update the
+.QW atime
+and
+.QW mtime
+values of the file given.
.PP
-For results see 'utime' documentation. If successful, the function
-will update the 'atime' and 'mtime' values of the file given.
+\fBTcl_FSFileAttrsGet\fR implements read access for the hookable \fBfile
+attributes\fR subcommand. The appropriate function for the filesystem to
+which \fIpathPtr\fR belongs will be called.
.PP
-\fBTcl_FSFileAttrsGet\fR implements read access for the hookable 'file
-attributes' subcommand. The appropriate function for the filesystem to
-which pathPtr belongs will be called.
+If the result is \fBTCL_OK\fR, then an object was placed in
+\fIobjPtrRef\fR, which
+will only be temporarily valid (unless \fBTcl_IncrRefCount\fR is called).
.PP
-If the result is TCL_OK, then an object was placed in objPtrRef, which
-will only be temporarily valid (unless Tcl_IncrRefCount is called).
+\fBTcl_FSFileAttrsSet\fR implements write access for the hookable \fBfile
+attributes\fR subcommand. The appropriate function for the filesystem to
+which \fIpathPtr\fR belongs will be called.
.PP
-\fBTcl_FSFileAttrsSet\fR implements write access for the hookable 'file
-attributes' subcommand. The appropriate function for the filesystem to
-which pathPtr belongs will be called.
+\fBTcl_FSFileAttrStrings\fR implements part of the hookable \fBfile
+attributes\fR subcommand. The appropriate function for the filesystem
+to which \fIpathPtr\fR belongs will be called.
.PP
-\fBTcl_FSFileAttrStrings\fR implements part of the hookable 'file attributes'
-subcommand. The appropriate function for the filesystem to which
-pathPtr belongs will be called.
-.PP
The called procedure may either return an array of strings, or may
-instead return NULL and place a Tcl list into the given objPtrRef. Tcl
-will take that list and first increment its refCount before using it.
-On completion of that use, Tcl will decrement its refCount. Hence if
+instead return NULL and place a Tcl list into the given \fIobjPtrRef\fR. Tcl
+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
-refCount of zero, and if the list should not be disposed of, the
-filesystem should ensure it retains a refCount on the object.
+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.
.PP
\fBTcl_FSAccess\fR checks whether the process would be allowed to read,
-write or test for existence of the file (or other file system object)
-whose name is pathname. If pathname is a symbolic link on Unix,
+write or test for existence of the file (or other filesystem object)
+whose name is \fIpathname\fR. If \fIpathname\fR is a symbolic link on Unix,
then permissions of the file referred by this symbolic link are
tested.
.PP
On success (all requested permissions granted), zero is returned. On
error (at least one bit in mode asked for a permission that is denied,
-or some other error occurred), -1 is returned.
+or some other error occurred), -1 is returned.
.PP
\fBTcl_FSStat\fR fills the stat structure \fIstatPtr\fR with information
about the specified file. You do not need any access rights to the
@@ -451,87 +526,110 @@ If one of the standard channels, \fBstdin, stdout\fR or \fBstderr\fR was
previously closed, the act of creating the new channel also assigns it as a
replacement for the standard channel.
.PP
-\fBTcl_FSGetCwd\fR replaces the library version of getcwd().
+\fBTcl_FSGetCwd\fR replaces the library version of \fBgetcwd\fR.
.PP
It returns the Tcl library's current working directory. This may be
-different to the native platform's working directory, in the case for
-which the cwd is not in the native filesystem.
+different to the native platform's working directory, which happens when
+the current working directory is not in the native filesystem.
.PP
The result is a pointer to a Tcl_Obj specifying the current directory,
or NULL if the current directory could not be determined. If NULL is
-returned, an error message is left in the interp's result.
-
-The result already has its refCount incremented for the caller. When
-it is no longer needed, that refCount should be decremented. This is
+returned, an error message is left in the \fIinterp\fR's result.
+.PP
+The result already has its reference count incremented for the caller. When
+it is no longer needed, that reference count should be decremented. This is
needed for thread-safety purposes, to allow multiple threads to access
this and related functions, while ensuring the results are always
valid.
.PP
-\fBTcl_FSChdir\fR replaces the library version of chdir(). The path is
+\fBTcl_FSChdir\fR replaces the library version of \fBchdir\fR. The path is
normalized and then passed to the filesystem which claims it. If that
-filesystem does not implement this function, Tcl will fallback to a
-combination of stat and access to check whether the directory exists
-and has appropriate permissions.
-.PP
-For results, see chdir() documentation. If successful, we keep a
-record of the successful path in cwdPathPtr for subsequent calls to
-getcwd.
-.PP
-\fBTcl_FSPathSeparator\fR returns the separator character to be used for
-most specific element of the path specified by pathPtr (i.e. the last
+filesystem does not implement this function, Tcl will fallback to a
+combination of \fBstat\fR and \fBaccess\fR to check whether the directory
+exists and has appropriate permissions.
+.PP
+For results, see \fBchdir\fR documentation. If successful, we keep a
+record of the successful path in \fIcwdPathPtr\fR for subsequent calls to
+\fBTcl_FSGetCwd\fR.
+.PP
+\fBTcl_FSPathSeparator\fR returns the separator character to be used for
+most specific element of the path specified by \fIpathPtr\fR (i.e. the last
part of the path).
.PP
The separator is returned as a Tcl_Obj containing a string of length
1. If the path is invalid, NULL is returned.
.PP
-\fBTcl_FSJoinPath\fR takes the given Tcl_Obj, which should be a valid list,
-and returns the path object given by considering the first 'elements'
-elements as valid path segments. If elements < 0, we use the entire
-list.
-.PP
-Returns object with refCount of zero, containing the joined path.
+\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
+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
+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
+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
+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 object containing each segment of that path as
an element.
-.PP
-Returns list object with refCount of zero. If the passed in lenPtr is
-non-NULL, we use it to return the number of elements in the returned
-list.
+It returns a list object 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
-It returns 1 if the paths are equal, and 0 if they are different. If
+It returns 1 if the paths are equal, and 0 if they are different. If
either path is NULL, 0 is always returned.
.PP
\fBTcl_FSGetNormalizedPath\fR this important function attempts to extract
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, with refCount of zero, 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 result when the filesystem contains
-numerous symbolic links may not be the most user-friendly
-version of a path.
+It returns the normalized path object, 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
+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.
.PP
\fBTcl_FSJoinToPath\fR takes the given object, which should usually be a
valid path or NULL, and joins onto it the array of paths segments
given.
.PP
-Returns object with refCount of zero, containing the joined path.
+Returns object, typically with refCount 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
+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.
-The filename may begin with "~" (to indicate current user's home
-directory) or "~<user>" (to indicate any user's home directory).
-.PP
-If the conversion succeeds (i.e. the object is a valid path in one of
-the current filesystems), then TCL_OK is returned. Otherwise
-TCL_ERROR is returned, and an error message may
+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
+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
@@ -545,12 +643,17 @@ representation is cached, so that repeated calls to this function will
not require additional conversions.
.PP
\fBTcl_FSGetTranslatedPath\fR attempts to extract the translated path
-from the given Tcl_Obj.
+from the given Tcl_Obj.
.PP
If the translation succeeds (i.e. the object is a valid path), then it is
returned. Otherwise NULL will be returned, and an error message may be
-left in the interpreter. A "translated" path is one which contains no
-"~" or "~user" sequences (these have been expanded to their current
+left in the interpreter. A
+.QW translated
+path is one which contains no
+.QW ~
+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
freed. This function is of little practical use, and
@@ -560,37 +663,53 @@ better functions to use for most purposes.
\fBTcl_FSGetTranslatedStringPath\fR does the same as
\fBTcl_FSGetTranslatedPath\fR, but returns a character string or NULL.
The string returned is dynamically allocated and owned by the caller,
-which must store it or call ckfree to ensure it is freed. Again,
+which must store it or call \fBckfree\fR to ensure it is freed. Again,
\fBTcl_FSGetNormalizedPath\fR or \fBTcl_GetNativePath\fR are usually
better functions to use for most purposes.
.PP
-\fBTcl_FSNewNativePath\fR performs something like that reverse of the
+\fBTcl_FSNewNativePath\fR performs something like the reverse of the
usual obj->path->nativerep conversions. If some code retrieves a path
-in native form (from, e.g. readlink or a native dialog), and that 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.
.PP
-The resulting object is a pure 'path' object, which will only receive
-a Utf-8 string representation if that is required by some Tcl code.
+The resulting object is a pure
+.QW path
+object, 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/MacOS native
+\fBTcl_FSGetNativePath\fR is for use by the Win/Unix native
filesystems, so that they can easily retrieve the native (char* or
TCHAR*) representation of a path. This function is a convenience
wrapper around \fBTcl_FSGetInternalRep\fR, and assumes the native
-representation is string-based. It may be desirable in the future
-to have non-string-based native representations (for example, on
-MacOS, a representation using a fileSpec of FSRef structure would
-probably be more efficient). On Windows a full Unicode
-representation would allow for paths of unlimited length. Currently
-the representation is simply a character string containing the
-complete, absolute path in the native encoding.
+representation is string-based. It may be desirable in the future to
+have non-string-based native representations (for example, on MacOSX, a
+representation using a fileSpec of FSRef structure would probably be
+more efficient). On Windows a full Unicode representation would allow
+for paths of unlimited length. Currently the representation is simply a
+character string which may contain either the relative path or a
+complete, absolute normalized path in the native encoding (complex
+conditions dictate which of these will be provided, so neither can be
+relied upon, unless the path is known to be absolute). If you need a
+native path which must be absolute, then you should ask for the native
+version of a normalized path. If for some reason a non-absolute,
+non-normalized version of the path is needed, that must be constructed
+separately (e.g. using \fBTcl_FSGetTranslatedPath\fR).
.PP
The native representation is cached so that repeated calls to this
-function will not require additional conversions.
+function will not require additional conversions. 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 native
+representation may be freed any time the cwd changes).
.PP
\fBTcl_FSFileSystemInfo\fR returns a list of two elements. The first
-element is the name of the filesystem (e.g. "native" or "vfs" or "zip"
-or "prowrap", perhaps), and the second is the particular type of the
+element is the name of the filesystem (e.g.
+.QW native ,
+.QW vfs ,
+.QW zip ,
+or
+.QW prowrap ,
+perhaps), and the second is the particular type of the
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.
@@ -603,25 +722,24 @@ recognized, when NULL will be returned.
.PP
If no filesystem will accept the path, NULL is returned.
.PP
-\fBTcl_FSGetPathType\fR determines whether the given path is relative
+\fBTcl_FSGetPathType\fR determines whether the given path is relative
to the current directory, relative to the current volume, or
absolute.
.PP
-It returns one of TCL_PATH_ABSOLUTE, TCL_PATH_RELATIVE, or
-TCL_PATH_VOLUME_RELATIVE
+It returns one of \fBTCL_PATH_ABSOLUTE\fR, \fBTCL_PATH_RELATIVE\fR, or
+\fBTCL_PATH_VOLUME_RELATIVE\fR
.PP
\fBTcl_AllocStatBuf\fR allocates a \fITcl_StatBuf\fR on the system
heap (which may be deallocated by being passed to \fBckfree\fR.) This
allows extensions to invoke \fBTcl_FSStat\fR and \fBTcl_FSLStat\fR
without being dependent on the size of the buffer. That in turn
depends on the flags used to build Tcl.
-.PP
-.SH TCL_FILESYSTEM
+.SH "THE VIRTUAL FILESYSTEM API"
.PP
A filesystem provides a \fBTcl_Filesystem\fR structure that contains
pointers to functions that implement the various operations on a
filesystem; these operations are invoked as needed by the generic
-layer, which generally occurs through the functions listed above.
+layer, which generally occurs through the functions listed above.
.PP
The \fBTcl_Filesystem\fR structures are manipulated using the following
methods.
@@ -631,13 +749,13 @@ optional piece of data to associated with that filesystem. On calling
this function, Tcl will attach the filesystem to the list of known
filesystems, and it will become fully functional immediately. Tcl does
not check if the same filesystem is registered multiple times (and in
-general that is not a good thing to do). TCL_OK will be returned.
+general that is not a good thing to do). \fBTCL_OK\fR will be returned.
.PP
\fBTcl_FSUnregister\fR removes the given filesystem structure from
-the list of known filesystems, if it is known, and returns TCL_OK. If
-the filesystem is not currently registered, TCL_ERROR is returned.
+the list of known filesystems, if it is known, and returns \fBTCL_OK\fR. If
+the filesystem is not currently registered, \fBTCL_ERROR\fR is returned.
.PP
-\fBTcl_FSData\fR will return the ClientData associated with the given
+\fBTcl_FSData\fR will return the ClientData associated with the given
filesystem, if that filesystem is registered. Otherwise it will
return NULL.
.PP
@@ -645,41 +763,42 @@ return NULL.
the set of mount points for the given (already registered) filesystem
have changed, and that cached file representations may therefore no
longer be correct.
+.SS "THE TCL_FILESYSTEM STRUCTURE"
.PP
The \fBTcl_Filesystem\fR structure contains the following fields:
.CS
typedef struct Tcl_Filesystem {
- CONST char *\fItypeName\fR;
- int \fIstructureLength\fR;
- Tcl_FSVersion \fIversion\fR;
+ const char *\fItypeName\fR;
+ int \fIstructureLength\fR;
+ Tcl_FSVersion \fIversion\fR;
Tcl_FSPathInFilesystemProc *\fIpathInFilesystemProc\fR;
Tcl_FSDupInternalRepProc *\fIdupInternalRepProc\fR;
Tcl_FSFreeInternalRepProc *\fIfreeInternalRepProc\fR;
Tcl_FSInternalToNormalizedProc *\fIinternalToNormalizedProc\fR;
Tcl_FSCreateInternalRepProc *\fIcreateInternalRepProc\fR;
- Tcl_FSNormalizePathProc *\fInormalizePathProc\fR;
+ Tcl_FSNormalizePathProc *\fInormalizePathProc\fR;
Tcl_FSFilesystemPathTypeProc *\fIfilesystemPathTypeProc\fR;
Tcl_FSFilesystemSeparatorProc *\fIfilesystemSeparatorProc\fR;
- Tcl_FSStatProc *\fIstatProc\fR;
- Tcl_FSAccessProc *\fIaccessProc\fR;
- Tcl_FSOpenFileChannelProc *\fIopenFileChannelProc\fR;
- Tcl_FSMatchInDirectoryProc *\fImatchInDirectoryProc\fR;
- Tcl_FSUtimeProc *\fIutimeProc\fR;
- Tcl_FSLinkProc *\fIlinkProc\fR;
- Tcl_FSListVolumesProc *\fIlistVolumesProc\fR;
+ Tcl_FSStatProc *\fIstatProc\fR;
+ Tcl_FSAccessProc *\fIaccessProc\fR;
+ Tcl_FSOpenFileChannelProc *\fIopenFileChannelProc\fR;
+ Tcl_FSMatchInDirectoryProc *\fImatchInDirectoryProc\fR;
+ Tcl_FSUtimeProc *\fIutimeProc\fR;
+ Tcl_FSLinkProc *\fIlinkProc\fR;
+ Tcl_FSListVolumesProc *\fIlistVolumesProc\fR;
Tcl_FSFileAttrStringsProc *\fIfileAttrStringsProc\fR;
Tcl_FSFileAttrsGetProc *\fIfileAttrsGetProc\fR;
Tcl_FSFileAttrsSetProc *\fIfileAttrsSetProc\fR;
- Tcl_FSCreateDirectoryProc *\fIcreateDirectoryProc\fR;
- Tcl_FSRemoveDirectoryProc *\fIremoveDirectoryProc\fR;
- Tcl_FSDeleteFileProc *\fIdeleteFileProc\fR;
- Tcl_FSCopyFileProc *\fIcopyFileProc\fR;
- Tcl_FSRenameFileProc *\fIrenameFileProc\fR;
- Tcl_FSCopyDirectoryProc *\fIcopyDirectoryProc\fR;
- Tcl_FSLstatProc *\fIlstatProc\fR;
- Tcl_FSLoadFileProc *\fIloadFileProc\fR;
- Tcl_FSGetCwdProc *\fIgetCwdProc\fR;
- Tcl_FSChdirProc *\fIchdirProc\fR;
+ Tcl_FSCreateDirectoryProc *\fIcreateDirectoryProc\fR;
+ Tcl_FSRemoveDirectoryProc *\fIremoveDirectoryProc\fR;
+ Tcl_FSDeleteFileProc *\fIdeleteFileProc\fR;
+ Tcl_FSCopyFileProc *\fIcopyFileProc\fR;
+ Tcl_FSRenameFileProc *\fIrenameFileProc\fR;
+ Tcl_FSCopyDirectoryProc *\fIcopyDirectoryProc\fR;
+ Tcl_FSLstatProc *\fIlstatProc\fR;
+ Tcl_FSLoadFileProc *\fIloadFileProc\fR;
+ Tcl_FSGetCwdProc *\fIgetCwdProc\fR;
+ Tcl_FSChdirProc *\fIchdirProc\fR;
} Tcl_Filesystem;
.CE
.PP
@@ -697,20 +816,26 @@ side-effects which are required by the filesystem; Tcl has less
efficient emulations it can fall back on). It is important to note
that, in the current version of Tcl, most of these fallbacks are only
used to handle commands initiated in Tcl, not in C. What this means is,
-that if a 'file rename' command is issued in Tcl, and the relevant
+that if a \fBfile rename\fR command is issued in Tcl, and the relevant
filesystem(s) do not implement their \fITcl_FSRenameFileProc\fR, Tcl's
core will instead fallback on a combination of other filesystem
functions (it will use \fITcl_FSCopyFileProc\fR followed by
\fITcl_FSDeleteFileProc\fR, and if \fITcl_FSCopyFileProc\fR is not
implemented there is a further fallback). However, if a
-\fITcl_FSRenameFile\fR command is issued at the C level, no such
+\fITcl_FSRenameFileProc\fR command is issued at the C level, no such
fallbacks occur. This is true except for the last four entries in the
-filesystem table (lstat, load, getcwd and chdir)
+filesystem table (\fBlstat\fR, \fBload\fR, \fBgetcwd\fR and \fBchdir\fR)
for which fallbacks do in fact occur at the C level.
.PP
-As an example, here is the filesystem lookup table used by the
-"vfs" extension which allows filesystem actions to be implemented
-in Tcl.
+Any functions which take path names in Tcl_Obj form take
+those names in UTF\-8 form. The filesystem infrastructure API is
+designed to support efficient, cached conversion of these UTF\-8 paths
+to other native representations.
+.SS "EXAMPLE FILESYSTEM DEFINITION"
+.PP
+Here is the filesystem lookup table used by the
+.QW vfs
+extension which allows filesystem actions to be implemented in Tcl.
.CS
static Tcl_Filesystem vfsFilesystem = {
"tclvfs",
@@ -719,14 +844,15 @@ static Tcl_Filesystem vfsFilesystem = {
&VfsPathInFilesystem,
&VfsDupInternalRep,
&VfsFreeInternalRep,
- /* No internal to normalized, since we don't create any
- * pure 'internal' Tcl_Obj path representations */
+ /* No internal to normalized, since we don't create
+ * any pure 'internal' Tcl_Obj path representations */
NULL,
- /* No create native rep function, since we don't use it
- * and don't choose to support uses of 'Tcl_FSNewNativePath' */
+ /* No create native rep function, since we don't use
+ * it and don't choose to support uses of
+ * Tcl_FSNewNativePath */
NULL,
- /* Normalize path isn't needed - we assume paths only have
- * one representation */
+ /* Normalize path isn't needed - we assume paths only
+ * have one representation */
NULL,
&VfsFilesystemPathType,
&VfsFilesystemSeparator,
@@ -735,57 +861,57 @@ static Tcl_Filesystem vfsFilesystem = {
&VfsOpenFileChannel,
&VfsMatchInDirectory,
&VfsUtime,
- /* We choose not to support symbolic links inside our vfs's */
+ /* We choose not to support symbolic links inside our
+ * VFS's */
NULL,
&VfsListVolumes,
&VfsFileAttrStrings,
&VfsFileAttrsGet,
&VfsFileAttrsSet,
&VfsCreateDirectory,
- &VfsRemoveDirectory,
+ &VfsRemoveDirectory,
&VfsDeleteFile,
- /* No copy file - fallback will occur at Tcl level */
+ /* No copy file; use the core fallback mechanism */
NULL,
- /* No rename file - fallback will occur at Tcl level */
+ /* No rename file; use the core fallback mechanism */
+ NULL,
+ /* No copy directory; use the core fallback mechanism */
NULL,
- /* No copy directory - fallback will occur at Tcl level */
- NULL,
/* Core will use stat for lstat */
NULL,
- /* No load - fallback on core implementation */
+ /* No load; use the core fallback mechanism */
NULL,
- /* We don't need a getcwd or chdir - fallback on Tcl's versions */
+ /* We don't need a getcwd or chdir; the core's own
+ * internal value is suitable */
NULL,
NULL
};
.CE
+.SH "FILESYSTEM INFRASTRUCTURE"
.PP
-Any functions which take path names in Tcl_Obj form take
-those names in UTF\-8 form. The filesystem infrastructure API is
-designed to support efficient, cached conversion of these UTF\-8 paths
-to other native representations.
-.SH TYPENAME
+These fields contain basic information about the filesystem structure
+and addresses of functions which are used to associate
+a particular filesystem with a file path, and deal with the internal
+handling of path representations, for example copying and freeing such
+representations.
+.SS TYPENAME
.PP
The \fItypeName\fR field contains a null-terminated string that
identifies the type of the filesystem implemented, e.g.
-\fBnative\fR or \fBzip\fR or \fBvfs\fR.
-.PP
-.SH "STRUCTURE LENGTH"
+.QW native ,
+.QW zip
+or
+.QW vfs .
+.SS "STRUCTURE LENGTH"
.PP
The \fIstructureLength\fR field is generally implemented as
\fIsizeof(Tcl_Filesystem)\fR, and is there to allow easier
binary backwards compatibility if the size of the structure
changes in a future Tcl release.
-.SH VERSION
+.SS VERSION
.PP
The \fIversion\fR field should be set to \fBTCL_FILESYSTEM_VERSION_1\fR.
-.SH "FILESYSTEM INFRASTRUCTURE"
-.PP
-These fields contain addresses of functions which are used to associate
-a particular filesystem with a file path, and deal with the internal
-handling of path representations, for example copying and freeing such
-representations.
-.SH PATHINFILESYSTEMPROC
+.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
@@ -793,7 +919,7 @@ 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
for any other return value is not defined). If \fBTCL_OK\fR is returned,
-then the optional \fBclientDataPtr\fR output parameter can be used to
+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
efficiently by the other filesystem functions. Tcl will simultaneously
@@ -803,10 +929,10 @@ Tcl's internal list of known filesystems.
.PP
.CS
typedef int Tcl_FSPathInFilesystemProc(
- Tcl_Obj *\fIpathPtr\fR,
- ClientData *\fIclientDataPtr\fR);
+ Tcl_Obj *\fIpathPtr\fR,
+ ClientData *\fIclientDataPtr\fR);
.CE
-.SH DUPINTERNALREPPROC
+.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
@@ -815,18 +941,18 @@ regenerated later.
.PP
.CS
typedef ClientData Tcl_FSDupInternalRepProc(
- ClientData \fIclientData\fR);
+ ClientData \fIclientData\fR);
.CE
-.SH FREEINTERNALREPPROC
+.SS FREEINTERNALREPPROC
Free the internal representation. This must be implemented if internal
representations need freeing (i.e. if some memory is allocated when an
internal representation is generated), but may otherwise be NULL.
.PP
.CS
typedef void Tcl_FSFreeInternalRepProc(
- ClientData \fIclientData\fR);
+ ClientData \fIclientData\fR);
.CE
-.SH INTERNALTONORMALIZEDPROC
+.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
@@ -835,9 +961,9 @@ representation is the normalized path.
.PP
.CS
typedef Tcl_Obj* Tcl_FSInternalToNormalizedProc(
- ClientData \fIclientData\fR);
+ ClientData \fIclientData\fR);
.CE
-.SH CREATEINTERNALREPPROC
+.SS CREATEINTERNALREPPROC
.PP
Function to take a path object, and calculate an internal
representation for it, and store that native representation in the
@@ -847,36 +973,41 @@ immediately creates an internal representation for paths it accepts.
.PP
.CS
typedef ClientData Tcl_FSCreateInternalRepProc(
- Tcl_Obj *\fIpathPtr\fR);
+ Tcl_Obj *\fIpathPtr\fR);
.CE
-.SH NORMALIZEPATHPROC
+.SS NORMALIZEPATHPROC
.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' must have a single unique 'normalized'
+path object. In Tcl, every
+.QW path
+must have a single unique
+.QW normalized
string representation. Depending on the filesystem,
there may be more than one unnormalized string representation which
refers to that path (e.g. a relative path, a path with different
character case if the filesystem is case insensitive, a path contain a
-reference to a home directory such as '~', a path containing symbolic
+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
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 'file
-delete', 'file rename', 'file copy' operating on symbolic links.
-This function may be called with 'nextCheckpoint' either
+exception is required to agree with Tcl's semantics with \fBfile
+delete\fR, \fBfile rename\fR, \fBfile copy\fR operating on symbolic links.
+This function may be called with \fInextCheckpoint\fR either
at the beginning of the path (i.e. zero), at the end of the path, or
at any intermediate file separator in the path. It will never
point to any other arbitrary position in the path. In the last of
-the three valid cases, the implementation can assume that the path
+the three valid cases, the implementation can assume that the path
up to and including the file separator is known and normalized.
.PP
.CS
typedef int Tcl_FSNormalizePathProc(
- Tcl_Interp *\fIinterp\fR,
- Tcl_Obj *\fIpathPtr\fR,
- int \fInextCheckpoint\fR);
+ Tcl_Interp *\fIinterp\fR,
+ Tcl_Obj *\fIpathPtr\fR,
+ int \fInextCheckpoint\fR);
.CE
.SH "FILESYSTEM OPERATIONS"
.PP
@@ -890,43 +1021,52 @@ this may be desirable (for example, a read-only filesystem should not
implement the last four functions, and a filesystem which does not
support symbolic links need not implement the \fBreadlink\fR function,
etc. The Tcl core expects filesystems to behave in this way).
-.SH FILESYSTEMPATHTYPEPROC
+.SS FILESYSTEMPATHTYPEPROC
.PP
Function to determine the type of a path in this filesystem. May be
NULL, in which case no type information will be available to users of
-the filesystem. The 'type' is used only for informational purposes,
+the filesystem. The
+.QW type
+is used only for informational purposes,
and should be returned as the string representation of the Tcl_Obj
-which is returned. A typical return value might be "networked", "zip"
-or "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
+which is returned. A typical return value might be
+.QW networked ,
+.QW zip
+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
to it.
.PP
.CS
typedef Tcl_Obj* Tcl_FSFilesystemPathTypeProc(
- Tcl_Obj *\fIpathPtr\fR);
+ Tcl_Obj *\fIpathPtr\fR);
.CE
-.SH FILESYSTEMSEPARATORPROC
+.SS FILESYSTEMSEPARATORPROC
.PP
Function to return the separator character(s) for this filesystem.
-Must be implemented, otherwise the \fBfile separator\fR command will not
-function correctly. The usual return value will be a Tcl_Obj
-containing the string "/".
+This need only be implemented if the filesystem wishes to use a
+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.
.PP
.CS
typedef Tcl_Obj* Tcl_FSFilesystemSeparatorProc(
- Tcl_Obj *\fIpathPtr\fR);
+ Tcl_Obj *\fIpathPtr\fR);
.CE
-.SH STATPROC
+.SS STATPROC
.PP
-Function to process a \fBTcl_FSStat()\fR call. Must be implemented for any
-reasonable filesystem, since many Tcl level commands depend crucially
+Function to process a \fBTcl_FSStat\fR call. Must be implemented for any
+reasonable filesystem, since many Tcl level commands depend crucially
upon it (e.g. \fBfile atime\fR, \fBfile isdirectory\fR, \fBfile size\fR,
\fBglob\fR).
.PP
.CS
typedef int Tcl_FSStatProc(
- Tcl_Obj *\fIpathPtr\fR,
- Tcl_StatBuf *\fIstatPtr\fR);
+ Tcl_Obj *\fIpathPtr\fR,
+ Tcl_StatBuf *\fIstatPtr\fR);
.CE
.PP
The \fBTcl_FSStatProc\fR fills the stat structure \fIstatPtr\fR with
@@ -942,40 +1082,40 @@ last metadata change time.
If the file represented by \fIpathPtr\fR exists, the
\fBTcl_FSStatProc\fR returns 0 and the stat structure is filled with
data. Otherwise, -1 is returned, and no stat info is given.
-.SH ACCESSPROC
+.SS ACCESSPROC
.PP
-Function to process a \fBTcl_FSAccess()\fR call. Must be implemented for
-any reasonable filesystem, since many Tcl level commands depend crucially
+Function to process a \fBTcl_FSAccess\fR call. Must be implemented for
+any reasonable filesystem, since many Tcl level commands depend crucially
upon it (e.g. \fBfile exists\fR, \fBfile readable\fR).
.PP
.CS
typedef int Tcl_FSAccessProc(
- Tcl_Obj *\fIpathPtr\fR,
- int \fImode\fR);
+ Tcl_Obj *\fIpathPtr\fR,
+ int \fImode\fR);
.CE
.PP
The \fBTcl_FSAccessProc\fR checks whether the process would be allowed
-to read, write or test for existence of the file (or other file system
-object) whose name is pathname. If pathname is a symbolic link, then
+to read, write or test for existence of the file (or other filesystem
+object) whose name is in \fIpathPtr\fR. If the pathname refers to a
+symbolic link, then the
permissions of the file referred by this symbolic link should be tested.
.PP
On success (all requested permissions granted), zero is returned. On
error (at least one bit in mode asked for a permission that is denied,
or some other error occurred), -1 is returned.
+.SS OPENFILECHANNELPROC
.PP
-.SH OPENFILECHANNELPROC
-.PP
-Function to process a \fBTcl_FSOpenFileChannel()\fR call. Must be
+Function to process a \fBTcl_FSOpenFileChannel\fR call. Must be
implemented for any reasonable filesystem, since any operations
-which require open or accessing a file's contents will use it
+which require open or accessing a file's contents will use it
(e.g. \fBopen\fR, \fBencoding\fR, and many Tk commands).
.PP
.CS
typedef Tcl_Channel Tcl_FSOpenFileChannelProc(
- Tcl_Interp *\fIinterp\fR,
- Tcl_Obj *\fIpathPtr\fR,
- int \fImode\fR,
- int \fIpermissions\fR);
+ Tcl_Interp *\fIinterp\fR,
+ Tcl_Obj *\fIpathPtr\fR,
+ int \fImode\fR,
+ int \fIpermissions\fR);
.CE
.PP
The \fBTcl_FSOpenFileChannelProc\fR opens a file specified by
@@ -996,20 +1136,20 @@ interpreter; to register it, use \fBTcl_RegisterChannel\fR. If one of
the standard channels, \fBstdin, stdout\fR or \fBstderr\fR was
previously closed, the act of creating the new channel also assigns it
as a replacement for the standard channel.
-.SH MATCHINDIRECTORYPROC
+.SS MATCHINDIRECTORYPROC
.PP
-Function to process a \fBTcl_FSMatchInDirectory()\fR call. If not
+Function to process a \fBTcl_FSMatchInDirectory\fR call. If not
implemented, then glob and recursive copy functionality will be lacking
-in the filesystem (and this may impact commands like 'encoding names'
+in the filesystem (and this may impact commands like \fBencoding names\fR
which use glob functionality internally).
.PP
.CS
typedef int Tcl_FSMatchInDirectoryProc(
- Tcl_Interp* \fIinterp\fR,
- Tcl_Obj *\fIresult\fR,
- Tcl_Obj *\fIpathPtr\fR,
- CONST char *\fIpattern\fR,
- Tcl_GlobTypeData * \fItypes\fR);
+ Tcl_Interp* \fIinterp\fR,
+ Tcl_Obj *\fIresultPtr\fR,
+ Tcl_Obj *\fIpathPtr\fR,
+ const char *\fIpattern\fR,
+ Tcl_GlobTypeData *\fItypes\fR);
.CE
.PP
The function should return all files or directories (or other filesystem
@@ -1026,12 +1166,13 @@ not, so code should be flexible to both possibilities.
.PP
The return value is a standard Tcl result indicating whether an error
occurred in the matching process. Error messages are placed in
-\fIinterp\fR; on a \fBTCL_OK\fR result, results should be added to the
-\fIresult\fR object given (which can be assumed to be a valid
-unshared Tcl list). The matches added
-to \fIresult\fR should include any path prefix given in \fIpathPtr\fR
-(this usually means they will be absolute path specifications).
-Note that if no matches are found, that simply leads to an empty
+\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
+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).
+Note that if no matches are found, that simply leads to an empty
result; errors are only signaled for actual file or filesystem
problems which may occur during the matching process.
.PP
@@ -1039,14 +1180,14 @@ The \fBTcl_GlobTypeData\fR structure passed in the \fItypes\fR
parameter contains the following fields:
.CS
typedef struct Tcl_GlobTypeData {
- /* Corresponds to bcdpfls as in 'find -t' */
- int \fItype\fR;
- /* Corresponds to file permissions */
- int \fIperm\fR;
- /* Acceptable mac type */
- Tcl_Obj *\fImacType\fR;
- /* Acceptable mac creator */
- Tcl_Obj *\fImacCreator\fR;
+ /* Corresponds to bcdpfls as in 'find -t' */
+ int \fItype\fR;
+ /* Corresponds to file permissions */
+ int \fIperm\fR;
+ /* Acceptable mac type */
+ Tcl_Obj *\fImacType\fR;
+ /* Acceptable mac creator */
+ Tcl_Obj *\fImacCreator\fR;
} Tcl_GlobTypeData;
.CE
.PP
@@ -1062,50 +1203,52 @@ which lie within the given \fIpathPtr\fR (and in this case, \fIpathPtr\fR
need not lie within the same filesystem - different to all other cases in
which this function is called). Support for this is critical if Tcl is
to have seamless transitions between from one filesystem to another.
-.SH UTIMEPROC
+.SS UTIMEPROC
.PP
-Function to process a \fBTcl_FSUtime()\fR call. Required to allow setting
-(not reading) of times with 'file mtime', 'file atime' and the
-open-r/open-w/fcopy implementation of 'file copy'.
+Function to process a \fBTcl_FSUtime\fR call. Required to allow setting
+(not reading) of times with \fBfile mtime\fR, \fBfile atime\fR and the
+open-r/open-w/fcopy implementation of \fBfile copy\fR.
.PP
.CS
typedef int Tcl_FSUtimeProc(
- Tcl_Obj *\fIpathPtr\fR,
- struct utimbuf *\fItval\fR);
+ Tcl_Obj *\fIpathPtr\fR,
+ struct utimbuf *\fItval\fR);
.CE
.PP
The access and modification times of the file specified by \fIpathPtr\fR
should be changed to the values given in the \fItval\fR structure.
.PP
-The return value is a standard Tcl result indicating whether an error
-occurred in the process.
-.SH LINKPROC
+The return value should be 0 on success and -1 on an error, as
+with the system \fButime\fR.
+.SS LINKPROC
.PP
-Function to process a \fBTcl_FSLink()\fR call. Should be implemented
+Function to process a \fBTcl_FSLink\fR call. Should be implemented
only if the filesystem supports links, and may otherwise be NULL.
.PP
.CS
typedef Tcl_Obj* Tcl_FSLinkProc(
- Tcl_Obj *\fIlinkNamePtr\fR,
- Tcl_Obj *\fItoPtr\fR,
- int \fIlinkAction\fR);
+ Tcl_Obj *\fIlinkNamePtr\fR,
+ Tcl_Obj *\fItoPtr\fR,
+ int \fIlinkAction\fR);
.CE
.PP
If \fItoPtr\fR is NULL, the function is being asked to read the
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, which should call
-Tcl_DecrRefCount when the result 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. See
+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.
+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
+(i.e. no ref count manipulation on either end is needed). See
the documentation for \fBTcl_FSLink\fR for the correct interpretation
of the \fIlinkAction\fR flags.
-.SH LISTVOLUMESPROC
+.SS LISTVOLUMESPROC
.PP
Function to list any filesystem volumes added by this filesystem.
Should be implemented only if the filesystem adds volumes at the head
-of the filesystem, so that they can be returned by 'file volumes'.
+of the filesystem, so that they can be returned by \fBfile volumes\fR.
.PP
.CS
typedef Tcl_Obj* Tcl_FSListVolumesProc(void);
@@ -1116,7 +1259,9 @@ NULL (or an empty list) if no volumes are provided. The result object
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
-choose whether they actually want to retain a 'master list' of volumes
+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
@@ -1124,8 +1269,7 @@ to Tcl which will copy the contents and then decrement the count back
to where it was).
.PP
Therefore, Tcl considers return values from this proc to be read-only.
-.PP
-.SH FILEATTRSTRINGSPROC
+.SS FILEATTRSTRINGSPROC
.PP
Function to list all attribute strings which are valid for this
filesystem. If not implemented the filesystem will not support
@@ -1135,94 +1279,98 @@ not implemented, there is no need to implement the \fBget\fR and \fBset\fR
methods.
.PP
.CS
-typedef CONST char** Tcl_FSFileAttrStringsProc(
- Tcl_Obj *\fIpathPtr\fR,
- Tcl_Obj** \fIobjPtrRef\fR);
+typedef const char** Tcl_FSFileAttrStringsProc(
+ Tcl_Obj *\fIpathPtr\fR,
+ Tcl_Obj** \fIobjPtrRef\fR);
.CE
.PP
The called function may either return an array of strings, or may
-instead return NULL and place a Tcl list into the given objPtrRef. Tcl
-will take that list and first increment its refCount before using it.
-On completion of that use, Tcl will decrement its refCount. Hence if
+instead return NULL and place a Tcl list into the given \fIobjPtrRef\fR. Tcl
+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
-refCount of zero, and if the list should not be disposed of, the
-filesystem should ensure it retains a refCount on the object.
-.SH FILEATTRSGETPROC
+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
+of at least one.
+.SS FILEATTRSGETPROC
.PP
-Function to process a \fBTcl_FSFileAttrsGet()\fR call, used by 'file
-attributes'.
+Function to process a \fBTcl_FSFileAttrsGet\fR call, used by \fBfile
+attributes\fR.
.PP
.CS
typedef int Tcl_FSFileAttrsGetProc(
- Tcl_Interp *\fIinterp\fR,
- int \fIindex\fR,
- Tcl_Obj *\fIpathPtr\fR,
- Tcl_Obj **\fIobjPtrRef\fR);
+ Tcl_Interp *\fIinterp\fR,
+ int \fIindex\fR,
+ Tcl_Obj *\fIpathPtr\fR,
+ Tcl_Obj **\fIobjPtrRef\fR);
.CE
.PP
Returns a standard Tcl return code. The attribute value retrieved,
which corresponds to the \fIindex\fR'th element in the list returned by
-the Tcl_FSFileAttrStringsProc, is a Tcl_Obj placed in objPtrRef (if
-TCL_OK was returned) and is likely to have a refCount of zero. Either
+the \fBTcl_FSFileAttrStringsProc\fR, is a Tcl_Obj placed in \fIobjPtrRef\fR (if
+\fBTCL_OK\fR was returned) and is likely to have a reference count of zero. Either
way we must either store it somewhere (e.g. the Tcl result), or
-Incr/Decr its refCount to ensure it is properly freed.
-.SH FILEATTRSSETPROC
+Incr/Decr its reference count to ensure it is properly freed.
+.SS FILEATTRSSETPROC
.PP
-Function to process a \fBTcl_FSFileAttrsSet()\fR call, used by 'file
-attributes'. If the filesystem is read-only, there is no need
+Function to process a \fBTcl_FSFileAttrsSet\fR call, used by \fBfile
+attributes\fR. If the filesystem is read-only, there is no need
to implement this.
.PP
.CS
typedef int Tcl_FSFileAttrsSetProc(
- Tcl_Interp *\fIinterp\fR,
- int \fIindex\fR,
- Tcl_Obj *\fIpathPtr\fR,
- Tcl_Obj *\fIobjPtr\fR);
+ Tcl_Interp *\fIinterp\fR,
+ int \fIindex\fR,
+ Tcl_Obj *\fIpathPtr\fR,
+ Tcl_Obj *\fIobjPtr\fR);
.CE
.PP
The attribute value of the \fIindex\fR'th element in the list returned by
the Tcl_FSFileAttrStringsProc should be set to the \fIobjPtr\fR given.
-.SH CREATEDIRECTORYPROC
+.SS CREATEDIRECTORYPROC
.PP
-Function to process a \fBTcl_FSCreateDirectory()\fR call. Should be
+Function to process a \fBTcl_FSCreateDirectory\fR call. Should be
implemented unless the FS is read-only.
.PP
.CS
typedef int Tcl_FSCreateDirectoryProc(
- Tcl_Obj *\fIpathPtr\fR);
+ Tcl_Obj *\fIpathPtr\fR);
.CE
.PP
The return value is a standard Tcl result indicating whether an error
occurred in the process. If successful, a new directory should have
been added to the filesystem in the location specified by
\fIpathPtr\fR.
-.SH REMOVEDIRECTORYPROC
+.SS REMOVEDIRECTORYPROC
.PP
-Function to process a 'Tcl_FSRemoveDirectory()' call. Should be
+Function to process a \fBTcl_FSRemoveDirectory\fR call. Should be
implemented unless the FS is read-only.
.PP
.CS
typedef int Tcl_FSRemoveDirectoryProc(
- Tcl_Obj *\fIpathPtr\fR,
- int \fIrecursive\fR,
- Tcl_Obj **\fIerrorPtr\fR);
+ Tcl_Obj *\fIpathPtr\fR,
+ int \fIrecursive\fR,
+ Tcl_Obj **\fIerrorPtr\fR);
.CE
.PP
The return value is a standard Tcl result indicating whether an error
occurred in the process. If successful, the directory specified by
\fIpathPtr\fR should have been removed from the filesystem. If the
-\fIrecursive\fR flag is given, then a non-empty directory should
-be deleted without error. If an error does occur, the name of
-the file or directory which caused the error should be placed in
-\fIerrorPtr\fR.
-.SH DELETEFILEPROC
-.PP
-Function to process a \fBTcl_FSDeleteFile()\fR call. Should be implemented
+\fIrecursive\fR flag is given, then a non-empty directory should be
+deleted without error. If this flag is not given, then and the
+directory is non-empty a POSIX
+.QW EEXIST
+error should be signaled. If an
+error does occur, the name of the file or directory which caused the
+error should be placed in \fIerrorPtr\fR.
+.SS DELETEFILEPROC
+.PP
+Function to process a \fBTcl_FSDeleteFile\fR call. Should be implemented
unless the FS is read-only.
.PP
.CS
typedef int Tcl_FSDeleteFileProc(
- Tcl_Obj *\fIpathPtr\fR);
+ Tcl_Obj *\fIpathPtr\fR);
.CE
.PP
The return value is a standard Tcl result indicating whether an error
@@ -1233,73 +1381,82 @@ function and not Tcl_FSRemoveDirectoryProc when needed to delete them
(even if they are symbolic links to directories).
.SH "FILESYSTEM EFFICIENCY"
.PP
-.SH LSTATPROC
+These functions need not be implemented for a particular filesystem
+because the core has a fallback implementation available. See each
+individual description for the consequences of leaving the field NULL.
+.SS LSTATPROC
.PP
-Function to process a \fBTcl_FSLstat()\fR call. If not implemented, Tcl
+Function to process a \fBTcl_FSLstat\fR call. If not implemented, Tcl
will attempt to use the \fIstatProc\fR defined above instead. Therefore
it need only be implemented if a filesystem can differentiate between
\fBstat\fR and \fBlstat\fR calls.
.PP
.CS
typedef int Tcl_FSLstatProc(
- Tcl_Obj *\fIpathPtr\fR,
- Tcl_StatBuf *\fIstatPtr\fR);
+ Tcl_Obj *\fIpathPtr\fR,
+ Tcl_StatBuf *\fIstatPtr\fR);
.CE
.PP
-The behavior of this function is very similar to that of the
-Tcl_FSStatProc defined above, except that if it is applied
+The behavior of this function is very similar to that of the
+\fBTcl_FSStatProc\fR defined above, except that if it is applied
to a symbolic link, it returns information about the link, not
about the target file.
+.SS COPYFILEPROC
.PP
-.SH COPYFILEPROC
-.PP
-Function to process a \fBTcl_FSCopyFile()\fR call. If not implemented Tcl
-will fall back on open-r, open-w and fcopy as a copying mechanism.
+Function to process a \fBTcl_FSCopyFile\fR call. If not implemented Tcl
+will fall back on \fBopen\fR-r, \fBopen\fR-w and \fBfcopy\fR as a
+copying mechanism.
Therefore it need only be implemented if the filesystem can perform
that action more efficiently.
.PP
.CS
typedef int Tcl_FSCopyFileProc(
- Tcl_Obj *\fIsrcPathPtr\fR,
- Tcl_Obj *\fIdestPathPtr\fR);
+ Tcl_Obj *\fIsrcPathPtr\fR,
+ Tcl_Obj *\fIdestPathPtr\fR);
.CE
.PP
The return value is a standard Tcl result indicating whether an error
occurred in the copying process. Note that, \fIdestPathPtr\fR is the
name of the file which should become the copy of \fIsrcPathPtr\fR. It
is never the name of a directory into which \fIsrcPathPtr\fR could be
-copied (i.e. the function is much simpler than the Tcl level 'file
-copy' subcommand). Note that,
+copied (i.e. the function is much simpler than the Tcl level \fBfile
+copy\fR subcommand). Note that,
if the filesystem supports symbolic links, Tcl will always call this
-function and not Tcl_FSCopyDirectoryProc when needed to copy them
-(even if they are symbolic links to directories).
-.SH RENAMEFILEPROC
-.PP
-Function to process a \fBTcl_FSRenameFile()\fR call. If not implemented,
+function and not \fIcopyDirectoryProc\fR when needed to copy them
+(even if they are symbolic links to directories). Finally, if the
+filesystem determines it cannot support the \fBfile copy\fR action,
+calling \fBTcl_SetErrno(EXDEV)\fR and returning a non-\fBTCL_OK\fR
+result will tell Tcl to use its standard fallback mechanisms.
+.SS RENAMEFILEPROC
+.PP
+Function to process a \fBTcl_FSRenameFile\fR call. If not implemented,
Tcl will fall back on a copy and delete mechanism. Therefore it need
only be implemented if the filesystem can perform that action more
efficiently.
.PP
.CS
typedef int Tcl_FSRenameFileProc(
- Tcl_Obj *\fIsrcPathPtr\fR,
- Tcl_Obj *\fIdestPathPtr\fR);
+ Tcl_Obj *\fIsrcPathPtr\fR,
+ Tcl_Obj *\fIdestPathPtr\fR);
.CE
.PP
The return value is a standard Tcl result indicating whether an error
-occurred in the renaming process.
-.SH COPYDIRECTORYPROC
-.PP
-Function to process a \fBTcl_FSCopyDirectory()\fR call. If not
-implemented, Tcl will fall back on a recursive create-dir, file copy
+occurred in the renaming process. If the
+filesystem determines it cannot support the \fBfile rename\fR action,
+calling \fBTcl_SetErrno(EXDEV)\fR and returning a non-\fBTCL_OK\fR
+result will tell Tcl to use its standard fallback mechanisms.
+.SS COPYDIRECTORYPROC
+.PP
+Function to process a \fBTcl_FSCopyDirectory\fR call. If not
+implemented, Tcl will fall back on a recursive \fBfile mkdir\fR, \fBfile copy\fR
mechanism. Therefore it need only be implemented if the filesystem can
perform that action more efficiently.
.PP
.CS
typedef int Tcl_FSCopyDirectoryProc(
- Tcl_Obj *\fIsrcPathPtr\fR,
- Tcl_Obj *\fIdestPathPtr\fR,
- Tcl_Obj **\fIerrorPtr\fR);
+ Tcl_Obj *\fIsrcPathPtr\fR,
+ Tcl_Obj *\fIdestPathPtr\fR,
+ Tcl_Obj **\fIerrorPtr\fR);
.CE
.PP
The return value is a standard Tcl result indicating whether an error
@@ -1309,33 +1466,42 @@ the file or directory which caused the error should be placed in
directory-name which should become the mirror-image of
\fIsrcPathPtr\fR. It is not the name of a directory into which
\fIsrcPathPtr\fR should be copied (i.e. the function is much simpler
-than the Tcl level 'file copy' subcommand).
-.SH LOADFILEPROC
-.PP
-Function to process a \fBTcl_FSLoadFile()\fR call. If not implemented, Tcl
-will fall back on a copy to native-temp followed by a Tcl_FSLoadFile on
+than the Tcl level \fBfile copy\fR subcommand). Finally, if the
+filesystem determines it cannot support the directory copy action,
+calling \fBTcl_SetErrno(EXDEV)\fR and returning a non-\fBTCL_OK\fR
+result will tell Tcl to use its standard fallback mechanisms.
+.SS LOADFILEPROC
+.PP
+Function to process a \fBTcl_FSLoadFile\fR call. If not implemented, Tcl
+will fall back on a copy to native-temp followed by a \fBTcl_FSLoadFile\fR on
that temporary copy. Therefore it need only be implemented if the
filesystem can load code directly, or it can be implemented simply to
-return TCL_ERROR to disable load functionality in this filesystem
+return \fBTCL_ERROR\fR to disable load functionality in this filesystem
entirely.
.PP
.CS
typedef int Tcl_FSLoadFileProc(
- Tcl_Interp * \fIinterp\fR,
- Tcl_Obj *\fIpathPtr\fR,
- Tcl_LoadHandle * \fIhandlePtr\fR,
- Tcl_FSUnloadFileProc * \fIunloadProcPtr\fR);
+ Tcl_Interp *\fIinterp\fR,
+ Tcl_Obj *\fIpathPtr\fR,
+ Tcl_LoadHandle *\fIhandlePtr\fR,
+ Tcl_FSUnloadFileProc *\fIunloadProcPtr\fR);
.CE
.PP
Returns a standard Tcl completion code. If an error occurs, an error
-message is left in the interp's result. The function dynamically loads
-a binary code file into memory. On a successful
-load, the \fIhandlePtr\fR should be filled with a token for
-the dynamically loaded file, and the \fIunloadProcPtr\fR should be
-filled in with the address of a procedure. The procedure will be
-called with the given Tcl_LoadHandle as its only parameter when Tcl
-needs to unload the file.
-.SH UNLOADFILEPROC
+message is left in the \fIinterp\fR's result. The function dynamically loads a
+binary code file into memory. On a successful load, the \fIhandlePtr\fR
+should be filled with a token for the dynamically loaded file, and the
+\fIunloadProcPtr\fR should be filled in with the address of a procedure.
+The unload procedure will be called with the given \fBTcl_LoadHandle\fR as its
+only parameter when Tcl needs to unload the file. For example, for the
+native filesystem, the \fBTcl_LoadHandle\fR returned is currently a token
+which can be used in the private \fBTclpFindSymbol\fR to access functions
+in the new code. Each filesystem is free to define the
+\fBTcl_LoadHandle\fR as it requires. Finally, if the
+filesystem determines it cannot support the file load action,
+calling \fBTcl_SetErrno(EXDEV)\fR and returning a non-\fBTCL_OK\fR
+result will tell Tcl to use its standard fallback mechanisms.
+.SS UNLOADFILEPROC
.PP
Function to unload a previously successfully loaded file. If load was
implemented, then this should also be implemented, if there is any
@@ -1343,17 +1509,17 @@ cleanup action required.
.PP
.CS
typedef void Tcl_FSUnloadFileProc(
- Tcl_LoadHandle \fIloadHandle\fR);
+ Tcl_LoadHandle \fIloadHandle\fR);
.CE
-.SH GETCWDPROC
+.SS GETCWDPROC
.PP
-Function to process a \fBTcl_FSGetCwd()\fR call. Most filesystems need not
-implement this. It will usually only be called once, if 'getcwd' is
-called before 'chdir'. May be NULL.
+Function to process a \fBTcl_FSGetCwd\fR call. Most filesystems need not
+implement this. It will usually only be called once, if \fBgetcwd\fR is
+called before \fBchdir\fR. May be NULL.
.PP
.CS
typedef Tcl_Obj* Tcl_FSGetCwdProc(
- Tcl_Interp *\fIinterp\fR);
+ Tcl_Interp *\fIinterp\fR);
.CE
.PP
If the filesystem supports a native notion of a current working
@@ -1361,26 +1527,28 @@ directory (which might perhaps change independent of Tcl), this
function should return that cwd as the result, or NULL if the current
directory could not be determined (e.g. the user does not have
appropriate permissions on the cwd directory). If NULL is returned, an
-error message is left in the interp's result.
-.PP
-.SH CHDIRPROC
+error message is left in the \fIinterp\fR's result.
+.SS CHDIRPROC
.PP
-Function to process a \fBTcl_FSChdir()\fR call. If filesystems do not
+Function to process a \fBTcl_FSChdir\fR call. If filesystems do not
implement this, it will be emulated by a series of directory access
checks. Otherwise, virtual filesystems which do implement it need only
-respond with a positive return result if the dirName is a valid,
+respond with a positive return result if the \fIpathPtr\fR is a valid,
accessible directory in their filesystem. They need not remember the
-result, since that will be automatically remembered for use by GetCwd.
+result, since that will be automatically remembered for use by
+\fBTcl_FSGetCwd\fR.
Real filesystems should carry out the correct action (i.e. call the
-correct system 'chdir' api).
+correct system \fBchdir\fR API).
.PP
.CS
typedef int Tcl_FSChdirProc(
- Tcl_Obj *\fIpathPtr\fR);
+ Tcl_Obj *\fIpathPtr\fR);
.CE
.PP
The \fBTcl_FSChdirProc\fR changes the applications current working
directory to the value specified in \fIpathPtr\fR. The function returns
-1 on error or 0 on success.
+.SH "SEE ALSO"
+cd(n), file(n), load(n), open(n), pwd(n), unload(n)
.SH KEYWORDS
-stat access filesystem vfs
+stat, access, filesystem, vfs, virtual
diff --git a/doc/FindExec.3 b/doc/FindExec.3
index 9c42f9a..0e225e9 100644
--- a/doc/FindExec.3
+++ b/doc/FindExec.3
@@ -16,10 +16,10 @@ Tcl_FindExecutable, Tcl_GetNameOfExecutable \- identify or return the name of th
void
\fBTcl_FindExecutable\fR(\fIargv0\fR)
.sp
-CONST char *
+const char *
\fBTcl_GetNameOfExecutable\fR()
.SH ARGUMENTS
-.AS char *argv0 in
+.AS char *argv0
.AP char *argv0 in
The first command-line argument to the program, which gives the
application's name.
diff --git a/doc/GetCwd.3 b/doc/GetCwd.3
index f8fce52..964e237 100755..100644
--- a/doc/GetCwd.3
+++ b/doc/GetCwd.3
@@ -19,7 +19,7 @@ char *
int
\fBTcl_Chdir\fR(\fIpath\fR)
.SH ARGUMENTS
-.AS Tcl_DString *bufferPtr
+.AS Tcl_DString *bufferPtr in/out
.AP Tcl_Interp *interp in
Interpreter in which to report an error, if any.
.AP Tcl_DString *bufferPtr in/out
@@ -39,7 +39,7 @@ the same functionality as the Tcl \fBpwd\fR command.
.PP
\fBTcl_GetCwd\fR returns a pointer to a string specifying the current
directory, or NULL if the current directory could not be determined.
-If NULL is returned, an error message is left in the interp's result.
+If NULL is returned, an error message is left in the \fIinterp\fR's result.
Storage for the result string is allocated in bufferPtr; the caller
must call \fBTcl_DStringFree()\fR when the result is no longer needed.
The format of the path is UTF\-8.
diff --git a/doc/GetHostName.3 b/doc/GetHostName.3
index 694ac4a..28f3a4f 100644
--- a/doc/GetHostName.3
+++ b/doc/GetHostName.3
@@ -11,7 +11,7 @@ Tcl_GetHostName \- get the name of the local host
.nf
\fB#include <tcl.h>\fR
.sp
-CONST char *
+const char *
\fBTcl_GetHostName\fR()
.BE
diff --git a/doc/GetIndex.3 b/doc/GetIndex.3
index e47f89b..82590fb 100644
--- a/doc/GetIndex.3
+++ b/doc/GetIndex.3
@@ -16,14 +16,12 @@ Tcl_GetIndexFromObj, Tcl_GetIndexFromObjStruct \- lookup string in table of keyw
int
\fBTcl_GetIndexFromObj\fR(\fIinterp, objPtr, tablePtr, msg, flags,
indexPtr\fR)
-.VS
.sp
int
\fBTcl_GetIndexFromObjStruct\fR(\fIinterp, objPtr, structTablePtr, offset,
-msg, flags, indexPtr\fR)
-.VE
+ msg, flags, indexPtr\fR)
.SH ARGUMENTS
-.AS "CONST char" **tablePtr
+.AS "const char" *structTablePtr in/out
.AP Tcl_Interp *interp in
Interpreter to use for error reporting; if NULL, then no message is
provided on errors.
@@ -31,19 +29,17 @@ provided on errors.
The string value of this object is used to search through \fItablePtr\fR.
The internal representation is modified to hold the index of the matching
table entry.
-.AP "CONST char" **tablePtr in
+.AP "const char" **tablePtr in
An array of null-terminated strings. The end of the array is marked
by a NULL string pointer.
-.AP "CONST VOID" *structTablePtr in
-An array of arbitrary type, typically some \fBstruct\fP type.
+.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\fP.
-.VS
+The size of the structure is given by \fIoffset\fR.
.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.
-.VE
-.AP "CONST char" *msg in
+.AP "const char" *msg in
Null-terminated string describing what is being looked up, such as
\fBoption\fR. This string is included in error messages.
.AP int flags in
@@ -66,14 +62,14 @@ the strings in \fItablePtr\fR to find a match. A match occurs if
for exactly one of the strings in \fItablePtr\fR and the
\fBTCL_EXACT\fR flag was not specified; in either case
the index of the matching entry is stored at \fI*indexPtr\fR
-and TCL_OK is returned.
+and \fBTCL_OK\fR is returned.
.PP
If there is no matching entry,
-TCL_ERROR is returned and an error message is left in \fIinterp\fR's
-result if \fIinterp\fR isn't NULL. \fIMsg\fR is included in the
+\fBTCL_ERROR\fR is returned and an error message is left in \fIinterp\fR's
+result if \fIinterp\fR is not NULL. \fIMsg\fR is included in the
error message to indicate what was being looked up. For example,
if \fImsg\fR is \fBoption\fR the error message will have a form like
-\fBbad option "firt": must be first, second, or third\fR.
+.QW "\fBbad option \N'34'firt\N'34': must be first, second, or third\fR" .
.PP
If \fBTcl_GetIndexFromObj\fR completes successfully it modifies the
internal representation of \fIobjPtr\fR to hold the address of
@@ -85,17 +81,18 @@ operation. Note: \fBTcl_GetIndexFromObj\fR assumes that the entries
in \fItablePtr\fR are static: they must not change between
invocations. If the value of \fIobjPtr\fR is the empty string,
\fBTcl_GetIndexFromObj\fR will treat it as a non-matching value
-and return TCL_ERROR.
-.VS
+and return \fBTCL_ERROR\fR.
.PP
\fBTcl_GetIndexFromObjStruct\fR works just like
\fBTcl_GetIndexFromObj\fR, except that instead of treating
-\fItablePtr\fR as an array of string pointers, it treats it as the
-first in a series of string ptrs that are spaced apart by \fIoffset\fR
-bytes. This is particularly useful when processing things like
+\fItablePtr\fR as an array of string pointers, it treats it as a
+pointer to the first string in a series of strings that have
+\fIoffset\fR bytes between them (i.e. that there is a pointer to the
+first array of characters at \fItablePtr\fR, a pointer to the second
+array of characters at \fItablePtr\fR+\fIoffset\fR bytes, etc.)
+This is particularly useful when processing things like
\fBTk_ConfigurationSpec\fR, whose string keys are in the same place in
each of several array elements.
-.VE
.SH "SEE ALSO"
Tcl_WrongNumArgs
diff --git a/doc/GetInt.3 b/doc/GetInt.3
index 677527a..f77d337 100644
--- a/doc/GetInt.3
+++ b/doc/GetInt.3
@@ -15,62 +15,69 @@ Tcl_GetInt, Tcl_GetDouble, Tcl_GetBoolean \- convert from string to integer, dou
\fB#include <tcl.h>\fR
.sp
int
-\fBTcl_GetInt\fR(\fIinterp, string, intPtr\fR)
+\fBTcl_GetInt\fR(\fIinterp, src, intPtr\fR)
.sp
int
-\fBTcl_GetDouble\fR(\fIinterp, string, doublePtr\fR)
+\fBTcl_GetDouble\fR(\fIinterp, src, doublePtr\fR)
.sp
int
-\fBTcl_GetBoolean\fR(\fIinterp, string, boolPtr\fR)
+\fBTcl_GetBoolean\fR(\fIinterp, src, boolPtr\fR)
.SH ARGUMENTS
-.AS Tcl_Interp *doublePtr
+.AS Tcl_Interp *doublePtr out
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
-.AP "CONST char" *string in
+.AP "const char" *src in
Textual value to be converted.
.AP int *intPtr out
-Points to place to store integer value converted from \fIstring\fR.
+Points to place to store integer value converted from \fIsrc\fR.
.AP double *doublePtr out
Points to place to store double-precision floating-point
-value converted from \fIstring\fR.
+value converted from \fIsrc\fR.
.AP int *boolPtr out
-Points to place to store boolean value (0 or 1) converted from \fIstring\fR.
+Points to place to store boolean value (0 or 1) converted from \fIsrc\fR.
.BE
.SH DESCRIPTION
.PP
These procedures convert from strings to integers or double-precision
floating-point values or booleans (represented as 0- or 1-valued
-integers). Each of the procedures takes a \fIstring\fR argument,
+integers). Each of the procedures takes a \fIsrc\fR argument,
converts it to an internal form of a particular type, and stores
the converted value at the location indicated by the procedure's
third argument. If all goes well, each of the procedures returns
-TCL_OK. If \fIstring\fR doesn't have the proper syntax for the
-desired type then TCL_ERROR is returned, an error message is left
+\fBTCL_OK\fR. If \fIsrc\fR does not have the proper syntax for the
+desired type then \fBTCL_ERROR\fR is returned, an error message is left
in the interpreter's result, and nothing is stored at *\fIintPtr\fR
or *\fIdoublePtr\fR or *\fIboolPtr\fR.
.PP
-\fBTcl_GetInt\fR expects \fIstring\fR to consist of a collection
+\fBTcl_GetInt\fR expects \fIsrc\fR to consist of a collection
of integer digits, optionally signed and optionally preceded by
-white space. If the first two characters of \fIstring\fR are ``0x''
-then \fIstring\fR is expected to be in hexadecimal form; otherwise,
-if the first character of \fIstring\fR is ``0'' then \fIstring\fR
-is expected to be in octal form; otherwise, \fIstring\fR is
+white space. If the first two characters of \fIsrc\fR
+after the optional white space and sign are
+.QW 0x
+then \fIsrc\fR is expected to be in hexadecimal form; otherwise,
+if the first such character is
+.QW 0
+then \fIsrc\fR
+is expected to be in octal form; otherwise, \fIsrc\fR is
expected to be in decimal form.
.PP
-\fBTcl_GetDouble\fR expects \fIstring\fR to consist of a floating-point
+\fBTcl_GetDouble\fR expects \fIsrc\fR to consist of a floating-point
number, which is: white space; a sign; a sequence of digits; a
-decimal point; a sequence of digits; the letter ``e''; and a
-signed decimal exponent. Any of the fields may be omitted, except that
+decimal point; a sequence of digits; the letter
+.QW e ;
+a signed decimal exponent; and more white space.
+Any of the fields may be omitted, except that
the digits either before or after the decimal point must be present
-and if the ``e'' is present then it must be followed by the
-exponent number.
+and if the
+.QW e
+is present then it must be followed by the exponent number.
.PP
-\fBTcl_GetBoolean\fR expects \fIstring\fR to specify a boolean
-value. If \fIstring\fR is any of \fB0\fR, \fBfalse\fR,
+\fBTcl_GetBoolean\fR expects \fIsrc\fR to specify a boolean
+value. If \fIsrc\fR is any of \fB0\fR, \fBfalse\fR,
\fBno\fR, or \fBoff\fR, then \fBTcl_GetBoolean\fR stores a zero
value at \fI*boolPtr\fR.
-If \fIstring\fR is any of \fB1\fR, \fBtrue\fR, \fByes\fR, or \fBon\fR,
+If \fIsrc\fR is any of \fB1\fR, \fBtrue\fR, \fByes\fR, or \fBon\fR,
then 1 is stored at \fI*boolPtr\fR.
Any of these values may be abbreviated, and upper-case spellings
are also acceptable.
diff --git a/doc/GetOpnFl.3 b/doc/GetOpnFl.3
index e914b8f..38aa976 100644
--- a/doc/GetOpnFl.3
+++ b/doc/GetOpnFl.3
@@ -8,29 +8,29 @@
.TH Tcl_GetOpenFile 3 8.0 Tcl "Tcl Library Procedures"
.BS
.SH NAME
-Tcl_GetOpenFile \- Get a standard IO File * handle from a channel. (Unix only)
+Tcl_GetOpenFile \- Return a FILE* for a channel registered in the given interpreter (Unix only)
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
int
-\fBTcl_GetOpenFile\fR(\fIinterp, string, write, checkUsage, filePtr\fR)
+\fBTcl_GetOpenFile\fR(\fIinterp, chanID, write, checkUsage, filePtr\fR)
.sp
.SH ARGUMENTS
-.AS Tcl_Interp checkUsage
+.AS Tcl_Interp checkUsage out
.AP Tcl_Interp *interp in
Tcl interpreter from which file handle is to be obtained.
-.AP "CONST char" *string in
+.AP "const char" *chanID in
String identifying channel, such as \fBstdin\fR or \fBfile4\fR.
.AP int write in
Non-zero means the file will be used for writing, zero means it will
be used for reading.
.AP int checkUsage in
-If non-zero, then an error will be generated if the file wasn't opened
+If non-zero, then an error will be generated if the file was not opened
for the access indicated by \fIwrite\fR.
.AP ClientData *filePtr out
Points to word in which to store pointer to FILE structure for
-the file given by \fIstring\fR.
+the file given by \fIchanID\fR.
.BE
.SH DESCRIPTION
@@ -44,17 +44,15 @@ be used for reading or writing.
In some cases, such as a channel that connects to a pipeline of
subprocesses, different FILE pointers will be returned for reading
and writing.
-\fBTcl_GetOpenFile\fR normally returns TCL_OK.
-If an error occurs in \fBTcl_GetOpenFile\fR (e.g. \fIstring\fR didn't
-make any sense or \fIcheckUsage\fR was set and the file wasn't opened
-for the access specified by \fIwrite\fR) then TCL_ERROR is returned
+\fBTcl_GetOpenFile\fR normally returns \fBTCL_OK\fR.
+If an error occurs in \fBTcl_GetOpenFile\fR (e.g. \fIchanID\fR did not
+make any sense or \fIcheckUsage\fR was set and the file was not opened
+for the access specified by \fIwrite\fR) then \fBTCL_ERROR\fR is returned
and the interpreter's result will contain an error message.
In the current implementation \fIcheckUsage\fR is ignored and consistency
checks are always performed.
-.VS
.PP
Note that this interface is only supported on the Unix platform.
-.VE
.SH KEYWORDS
channel, file handle, permissions, pipeline, read, write
diff --git a/doc/GetStdChan.3 b/doc/GetStdChan.3
index e0f754a..045d15a 100644
--- a/doc/GetStdChan.3
+++ b/doc/GetStdChan.3
@@ -20,7 +20,7 @@ Tcl_Channel
\fBTcl_SetStdChannel\fR(\fIchannel, type\fR)
.sp
.SH ARGUMENTS
-.AS Tcl_Channel channel in
+.AS Tcl_Channel channel
.AP int type in
The identifier for the standard channel to retrieve or modify. Must be one of
\fBTCL_STDIN\fR, \fBTCL_STDOUT\fR, or \fBTCL_STDERR\fR.
@@ -76,7 +76,6 @@ 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.
-.PP
.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 92457bd..14a9e8c 100644
--- a/doc/GetTime.3
+++ b/doc/GetTime.3
@@ -1,5 +1,5 @@
'\"
-'\" Copyright (c) 2001 by Kevin B. Kenny.
+'\" Copyright (c) 2001 by Kevin B. Kenny <kennykb@acm.org>.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -8,16 +8,39 @@
.TH Tcl_GetTime 3 8.4 Tcl "Tcl Library Procedures"
.BS
.SH NAME
-Tcl_GetTime \- get date and time
+Tcl_GetTime, Tcl_SetTimeProc, Tcl_QueryTimeProc \- get date and time
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
-\fBTcl_GetTime\fR(\fI timePtr \fR)
+\fBTcl_GetTime\fR(\fItimePtr\fR)
+.sp
+\fBTcl_SetTimeProc\fR(\fIgetProc, scaleProc, clientData\fR)
+.sp
+\fBTcl_QueryTimeProc\fR(\fIgetProcPtr, scaleProcPtr, clientDataPtr\fR)
.SH ARGUMENTS
-.AS "Tcl_Time *" timePtr
+.AS "Tcl_Time *" timePtr out
.AP "Tcl_Time *" timePtr out
Points to memory in which to store the date and time information.
+.AS "Tcl_GetTimeProc *" getProc in
+.AP "Tcl_GetTimeProc *" getProc in
+Pointer to handler function replacing \fBTcl_GetTime\fR's access to the OS.
+.AS "Tcl_ScaleTimeProc *" scaleProc in
+.AP "Tcl_ScaleTimeProc *" scaleProc in
+Pointer to handler function for the conversion of time delays in the
+virtual domain to real-time.
+.AS "ClientData *" clientData in
+.AP "ClientData *" clientData in
+Value passed through to the two handler functions.
+.AS "Tcl_GetTimeProc **" getProcPtr inout
+.AP "Tcl_GetTimeProc **" getProcPtr inout
+Pointer to place the currently registered get handler function into.
+.AS "Tcl_ScaleTimeProc **" scaleProcPtr inout
+.AP "Tcl_ScaleTimeProc **" scaleProcPtr inout
+Pointer to place the currently registered scale handler function into.
+.AS "ClientData **" clientDataPtr inout
+.AP "ClientData **" clientDataPtr inout
+Pointer to place the currently registered pass-through value into.
.BE
.SH DESCRIPTION
.PP
@@ -45,6 +68,32 @@ computer system. On multiprocessor variants of Windows, this number
may be limited to the 10- or 20-ms granularity of the system clock.
(On single-processor Windows systems, the \fIusec\fR field is derived
from a performance counter and is highly precise.)
+.PP
+The \fBTcl_SetTime\fR function registers two related handler functions
+with the core. The first handler function is a replacement for
+\fBTcl_GetTime\fR, or rather the OS access made by
+\fBTcl_GetTime\fR. The other handler function is used by the Tcl
+notifier to convert wait/block times from the virtual domain into real
+time.
+.PP
+The \fBTcl_QueryTime\fR function returns the currently registered
+handler functions. If no external handlers were set then this will
+return the standard handlers accessing and processing the native time
+of the OS. The arguments to the function are allowed to be NULL; and
+any argument which is NULL is ignored and not set.
+.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.
+.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.
.SH "SEE ALSO"
clock
.SH KEYWORDS
diff --git a/doc/GetVersion.3 b/doc/GetVersion.3
index 4fa26f4..47034d0 100755..100644
--- a/doc/GetVersion.3
+++ b/doc/GetVersion.3
@@ -15,6 +15,7 @@ Tcl_GetVersion \- get the version of the library at runtime
.sp
\fBTcl_GetVersion\fR(\fImajor, minor, patchLevel, type\fR)
.SH ARGUMENTS
+.AS Tcl_ReleaseType *patchLevel out
.AP int *major out
Major version number of the Tcl library.
.AP int *minor out
diff --git a/doc/Hash.3 b/doc/Hash.3
index 1f6040a..78b8459 100644
--- a/doc/Hash.3
+++ b/doc/Hash.3
@@ -44,21 +44,21 @@ Tcl_HashEntry *
Tcl_HashEntry *
\fBTcl_NextHashEntry\fR(\fIsearchPtr\fR)
.sp
-CONST char *
+char *
\fBTcl_HashStats\fR(\fItablePtr\fR)
.SH ARGUMENTS
-.AS Tcl_HashSearch *searchPtr
+.AS Tcl_HashKeyType *searchPtr out
.AP Tcl_HashTable *tablePtr in
Address of hash table structure (for all procedures but
\fBTcl_InitHashTable\fR, this must have been initialized by
previous call to \fBTcl_InitHashTable\fR).
.AP int keyType in
Kind of keys to use for new hash table. Must be either
-TCL_STRING_KEYS, TCL_ONE_WORD_KEYS, TCL_CUSTOM_TYPE_KEYS,
-TCL_CUSTOM_PTR_KEYS, or an integer value greater than 1.
+\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.
-.AP "CONST char" *key in
+.AP "const char" *key in
Key to use for probe into table. Exact form depends on
\fIkeyType\fR used to create table.
.AP int *newPtr out
@@ -86,7 +86,9 @@ STRUCTURE\fR below). All of the keys in a given table have the same
form, which is specified when the table is initialized.
.PP
The value of a hash table entry can be anything that fits in the same
-space as a ``char *'' pointer. Values for hash table entries are
+space as a
+.QW "char *"
+pointer. Values for hash table entries are
managed entirely by clients, not by the hash module itself. Typically
each entry's value is a pointer to a data structure managed by client
code.
@@ -122,8 +124,10 @@ They are passed to hashing routines using the address of the
first character of the string.
.IP \fBTCL_ONE_WORD_KEYS\fR 25
Keys are single-word values; they are passed to hashing routines
-and stored in hash table entries as ``char *'' values.
-The pointer value is the key; it need not (and usually doesn't)
+and stored in hash table entries as
+.QW "char *"
+values.
+The pointer value is the key; it need not (and usually does not)
actually point to a string.
.IP \fBTCL_CUSTOM_TYPE_KEYS\fR 25
Keys are of arbitrary type, and are stored in the entry. Hashing
@@ -138,7 +142,9 @@ structure is described in the section
.IP \fIother\fR 25
If \fIkeyType\fR is not one of the above,
then it must be an integer value greater than 1.
-In this case the keys will be arrays of ``int'' values, where
+In this case the keys will be arrays of
+.QW int
+values, where
\fIkeyType\fR gives the number of ints in each key.
This allows structures to be used as keys.
All keys must have the same size.
@@ -159,7 +165,7 @@ before deleting the table.
.PP
\fBTcl_CreateHashEntry\fR locates the entry corresponding to a
particular key, creating a new entry in the table if there
-wasn't already one with the given key.
+was not already one with the given key.
If an entry already existed with the given key then \fI*newPtr\fR
is set to zero.
If a new entry was created, then \fI*newPtr\fR is set to a non-zero
@@ -175,28 +181,34 @@ the client is responsible for any cleanup associated with the
entry's value, such as freeing a structure that it points to.
.PP
\fBTcl_FindHashEntry\fR is similar to \fBTcl_CreateHashEntry\fR
-except that it doesn't create a new entry if the key doesn't exist;
+except that it does not create a new entry if the key doesn't exist;
instead, it returns NULL as result.
.PP
\fBTcl_GetHashValue\fR and \fBTcl_SetHashValue\fR are used to
read and write an entry's value, respectively.
-Values are stored and retrieved as type ``ClientData'', which is
+Values are stored and retrieved as type
+.QW ClientData ,
+which is
large enough to hold a pointer value. On almost all machines this is
large enough to hold an integer value too.
.PP
\fBTcl_GetHashKey\fR returns the key for a given hash table entry,
-either as a pointer to a string, a one-word (``char *'') key, or
+either as a pointer to a string, a one-word
+.PQ "char *"
+key, or
as a pointer to the first word of an array of integers, depending
on the \fIkeyType\fR used to create a hash table.
In all cases \fBTcl_GetHashKey\fR returns a result with type
-``char *''.
+.QW "char *" .
When the key is a string or array, the result of \fBTcl_GetHashKey\fR
points to information in the table entry; this information will
remain valid until the entry is deleted or its table is deleted.
.PP
\fBTcl_FirstHashEntry\fR and \fBTcl_NextHashEntry\fR may be used
to scan all of the entries in a hash table.
-A structure of type ``Tcl_HashSearch'', provided by the client,
+A structure of type
+.QW Tcl_HashSearch ,
+provided by the client,
is used to keep track of progress through the table.
\fBTcl_FirstHashEntry\fR initializes the search record and
returns the first entry in the table (or NULL if the table is
@@ -207,9 +219,10 @@ NULL if the end of the table has been reached.
A call to \fBTcl_FirstHashEntry\fR followed by calls to
\fBTcl_NextHashEntry\fR will return each of the entries in
the table exactly once, in an arbitrary order.
-It is unadvisable to modify the structure of the table, e.g.
-by creating or deleting entries, while the search is in
-progress.
+It is inadvisable to modify the structure of the table, e.g.
+by creating or deleting entries, while the search is in progress,
+with the exception of deleting the entry returned by
+\fBTcl_FirstHashEntry\fR or \fBTcl_NextHashEntry\fR.
.PP
\fBTcl_HashStats\fR returns a dynamically-allocated string with
overall information about a hash table, such as the number of
@@ -228,10 +241,10 @@ to any of the fields of any of the hash-related data structures;
use the procedures and macros defined here.
.SH "THE TCL_HASHKEYTYPE STRUCTURE"
.PP
-Extension writers can define new hash key types by defining four
-procedures, initializing a Tcl_HashKeyType structure to describe
-the type, and calling \fBTcl_InitCustomHashTable\fR.
-The \fBTcl_HashKeyType\fR structure is defined as follows:
+Extension writers can define new hash key types by defining four procedures,
+initializing a \fBTcl_HashKeyType\fR structure to describe the type, and
+calling \fBTcl_InitCustomHashTable\fR. The \fBTcl_HashKeyType\fR structure is
+defined as follows:
.CS
typedef struct Tcl_HashKeyType {
int \fIversion\fR;
@@ -243,61 +256,71 @@ typedef struct Tcl_HashKeyType {
} Tcl_HashKeyType;
.CE
.PP
-The \fIversion\fR member is the version of the table. If this
-structure is extended in future then the version can be used
-to distinguish between different structures. It should be set
-to \fBTCL_HASH_KEY_TYPE_VERSION\fR.
+The \fIversion\fR member is the version of the table. If this structure is
+extended in future then the version can be used to distinguish between
+different structures. It should be set to \fBTCL_HASH_KEY_TYPE_VERSION\fR.
.PP
-The \fIflags\fR member is one or more of the following values OR'ed together:
+The \fIflags\fR member is 0 or one or more of the following values OR'ed
+together:
.IP \fBTCL_HASH_KEY_RANDOMIZE_HASH\fR 25
-There are some things, pointers for example which don't hash well
-because they do not use the lower bits. If this flag is set then the
-hash table will attempt to rectify this by randomising the bits and
-then using the upper N bits as the index into the table.
+There are some things, pointers for example which do not hash well because
+they do not use the lower bits. If this flag is set then the hash table will
+attempt to rectify this by randomizing the bits and then using the upper N
+bits as the index into the table.
+.IP \fBTCL_HASH_KEY_SYSTEM_HASH\fR 25
+.VS 8.5
+This flag forces Tcl to use the memory allocation procedures provided by the
+operating system when allocating and freeing memory used to store the hash
+table data structures, and not any of Tcl's own customized memory allocation
+routines. This is important if the hash table is to be used in the
+implementation of a custom set of allocation routines, or something that a
+custom set of allocation routines might depend on, in order to avoid any
+circular dependency.
+.VE 8.5
.PP
-The \fIhashKeyProc\fR member contains the address of a function
-called to calculate a hash value for the key.
+The \fIhashKeyProc\fR member contains the address of a function called to
+calculate a hash value for the key.
.CS
typedef unsigned int (Tcl_HashKeyProc) (
- Tcl_HashTable *\fItablePtr\fR,
- VOID *\fIkeyPtr\fR);
+ Tcl_HashTable *\fItablePtr\fR,
+ void *\fIkeyPtr\fR);
.CE
-If this is NULL then \fIkeyPtr\fR is used and
+If this is NULL then \fIkeyPtr\fR is used and
\fBTCL_HASH_KEY_RANDOMIZE_HASH\fR is assumed.
.PP
-The \fIcompareKeysProc\fR member contains the address of a function
-called to compare two keys.
+The \fIcompareKeysProc\fR member contains the address of a function called to
+compare two keys.
.CS
-typedef int (Tcl_CompareHashKeysProc) (VOID *\fIkeyPtr\fR,
- Tcl_HashEntry *\fIhPtr\fR);
+typedef int (Tcl_CompareHashKeysProc) (
+ void *\fIkeyPtr\fR,
+ Tcl_HashEntry *\fIhPtr\fR);
.CE
-If this is NULL then the \fIkeyPtr\fR pointers are compared.
-If the keys don't match then the function returns 0, otherwise
-it returns 1.
+If this is NULL then the \fIkeyPtr\fR pointers are compared. If the keys do
+not match then the function returns 0, otherwise it returns 1.
.PP
-The \fIallocEntryProc\fR member contains the address of a function
-called to allocate space for an entry and initialise the key.
+The \fIallocEntryProc\fR member contains the address of a function called to
+allocate space for an entry and initialize the key and clientData.
.CS
typedef Tcl_HashEntry *(Tcl_AllocHashEntryProc) (
- Tcl_HashTable *\fItablePtr\fR, VOID *\fIkeyPtr\fR);
+ Tcl_HashTable *\fItablePtr\fR,
+ void *\fIkeyPtr\fR);
.CE
If this is NULL then Tcl_Alloc is used to allocate enough space for a
-Tcl_HashEntry and the key pointer is assigned to key.oneWordValue.
-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.
-If
+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.
.PP
-The \fIfreeEntryProc\fR member contains the address of a function
-called to free space for an entry.
+The \fIfreeEntryProc\fR member contains the address of a function called to
+free space for an entry.
.CS
typedef void (Tcl_FreeHashEntryProc) (Tcl_HashEntry *\fIhPtr\fR);
.CE
-If this is NULL then Tcl_Free is used to free the space for the
-entry. Tcl_Obj * keys use this function to decrement the
-reference count on the object.
+If this is NULL then Tcl_Free is used to free the space for the entry.
+Tcl_Obj* keys use this function to decrement the reference count on the
+object.
.SH KEYWORDS
hash table, key, lookup, search, value
diff --git a/doc/Init.3 b/doc/Init.3
index e78423e..f421479 100644
--- a/doc/Init.3
+++ b/doc/Init.3
@@ -14,17 +14,16 @@ Tcl_Init \- find and source initialization script
int
\fBTcl_Init\fR(\fIinterp\fR)
.SH ARGUMENTS
+.AS Tcl_Interp *interp
.AP Tcl_Interp *interp in
Interpreter to initialize.
.BE
.SH DESCRIPTION
.PP
-\fBTcl_Init\fR is a helper procedure that finds and \fBsource\fR's the
+\fBTcl_Init\fR is a helper procedure that finds and \fBsource\fRs the
\fBinit.tcl\fR script, which should exist somewhere on the Tcl library
-path. On Macintosh systems, it additionally checks for an \fBInit\fR
-resource and sources the contents of that resource if \fBinit.tcl\fR
-cannot be found.
+path.
.PP
\fBTcl_Init\fR is typically called from \fBTcl_AppInit\fR procedures.
diff --git a/doc/InitStubs.3 b/doc/InitStubs.3
index 2cfbb70..318c564 100644
--- a/doc/InitStubs.3
+++ b/doc/InitStubs.3
@@ -13,13 +13,13 @@ Tcl_InitStubs \- initialize the Tcl stubs mechanism
.nf
\fB#include <tcl.h>\fR
.sp
-CONST char *
+const char *
\fBTcl_InitStubs\fR(\fIinterp, version, exact\fR)
.SH ARGUMENTS
-.AS Tcl_Interp *interp in
+.AS Tcl_Interp *interp
.AP Tcl_Interp *interp in
Tcl interpreter handle.
-.AP "CONST char" *version in
+.AP "const char" *version in
A version string consisting of one or more decimal numbers
separated by dots.
.AP int exact in
@@ -59,8 +59,8 @@ steps:
Call \fBTcl_InitStubs\fR in the extension before calling any other
Tcl functions.
.IP 2) 5
-Define the USE_TCL_STUBS symbol. Typically, you would include the
--DUSE_TCL_STUBS flag when compiling the extension.
+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
diff --git a/doc/IntObj.3 b/doc/IntObj.3
index 15b6bd9..5cf677d 100644
--- a/doc/IntObj.3
+++ b/doc/IntObj.3
@@ -5,10 +5,10 @@
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.so man.macros
-.TH Tcl_IntObj 3 8.0 Tcl "Tcl Library Procedures"
+.TH Tcl_IntObj 3 8.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
-Tcl_NewIntObj, Tcl_NewLongObj, Tcl_NewWideIntObj, Tcl_SetIntObj, Tcl_SetLongObj, Tcl_SetWideIntObj, Tcl_GetIntFromObj, Tcl_GetLongFromObj, Tcl_GetWideIntFromObj \- manipulate Tcl objects as integers and wide integers
+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
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -19,18 +19,14 @@ Tcl_Obj *
Tcl_Obj *
\fBTcl_NewLongObj\fR(\fIlongValue\fR)
.sp
-.VS 8.4
Tcl_Obj *
\fBTcl_NewWideIntObj\fR(\fIwideValue\fR)
-.VE 8.4
.sp
\fBTcl_SetIntObj\fR(\fIobjPtr, intValue\fR)
.sp
\fBTcl_SetLongObj\fR(\fIobjPtr, longValue\fR)
.sp
-.VS 8.4
\fBTcl_SetWideIntObj\fR(\fIobjPtr, wideValue\fR)
-.VE 8.4
.sp
int
\fBTcl_GetIntFromObj\fR(\fIinterp, objPtr, intPtr\fR)
@@ -38,110 +34,127 @@ int
int
\fBTcl_GetLongFromObj\fR(\fIinterp, objPtr, longPtr\fR)
.sp
-.VS 8.4
int
\fBTcl_GetWideIntFromObj\fR(\fIinterp, objPtr, widePtr\fR)
-.VE 8.4
+.sp
+.sp
+.VS 8.5
+\fB#include <tclTomMath.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_NewBignumObj\fR(\fIbigValue\fR)
+.sp
+\fBTcl_SetBignumObj\fR(\fIobjPtr, bigValue\fR)
+.sp
+int
+\fBTcl_GetBignumFromObj\fR(\fIinterp, objPtr, bigValue\fR)
+.sp
+int
+\fBTcl_TakeBignumFromObj\fR(\fIinterp, objPtr, bigValue\fR)
+.sp
+int
+\fBTcl_InitBignumFromDouble\fR(\fIinterp, doubleValue, bigValue\fR)
+.VE 8.5
.SH ARGUMENTS
-.AS Tcl_WideInt *interp
+.AS Tcl_WideInt doubleValue in/out
.AP int intValue in
-Integer value used to initialize or set an integer object.
+Integer value used to initialize or set a Tcl object.
.AP long longValue in
-Long integer value used to initialize or set an integer object.
+Long integer value used to initialize or set a Tcl object.
.AP Tcl_WideInt wideValue in
-.VS 8.4
-Wide integer value (minimum 64-bits wide where supported by the
-compiler) used to initialize or set a wide integer object.
-.VE 8.4
+Wide integer value used to initialize or set a Tcl object.
.AP Tcl_Obj *objPtr in/out
-For \fBTcl_SetIntObj\fR, \fBTcl_SetLongObj\fR, and
-.VS 8.4
-\fBTcl_SetWideIntObj\fR, this points to the object to be converted to
-integer type. For \fBTcl_GetIntFromObj\fR, \fBTcl_GetLongFromObj\fR,
-and \fBTcl_GetWideIntFromObj\fR, this refers to the object from which
-to get an integer or long integer value; if \fIobjPtr\fR does not
-already point to an integer object (or a wide integer object in the
-case of \fBTcl_SetWideIntObj\fR and \fBTcl_GetWideIntFromObj\fR,) an
-.VE 8.4
-attempt will be made to convert it to one.
+For \fBTcl_SetIntObj\fR, \fBTcl_SetLongObj\fR, \fBTcl_SetWideIntObj\fR,
+and \fBTcl_SetBignumObj\fR, this points to the object 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
+to retrieve an integral value.
.AP Tcl_Interp *interp in/out
-If an error occurs during conversion,
-an error message is left in the interpreter's result object
-unless \fIinterp\fR is NULL.
+When non-NULL, an error message is left here when integral value
+retrieval fails.
.AP int *intPtr out
-Points to place to store the integer value
-obtained by \fBTcl_GetIntFromObj\fR from \fIobjPtr\fR.
+Points to place to store the integer value retrieved from \fIobjPtr\fR.
.AP long *longPtr out
-Points to place to store the long integer value
-obtained by \fBTcl_GetLongFromObj\fR from \fIobjPtr\fR.
+Points to place to store the long integer value retrieved from \fIobjPtr\fR.
.AP Tcl_WideInt *widePtr out
-.VS 8.4
-Points to place to store the wide integer value
-obtained by \fBTcl_GetWideIntFromObj\fR from \fIobjPtr\fR.
-.VE 8.4
+Points to place to store the wide integer value retrieved from \fIobjPtr\fR.
+.AP mp_int *bigValue in/out
+.VS 8.5
+Points to a multi-precision integer structure declared by the LibTomMath
+library.
+.VE 8.5
+.AP double doubleValue in
+.VS 8.5
+Double value from which the integer part is determined and
+used to initialize a multi-precision integer value.
+.VE 8.5
.BE
.SH DESCRIPTION
.PP
-These procedures are used to create, modify, and read
-integer and wide integer Tcl objects from C code.
-\fBTcl_NewIntObj\fR, \fBTcl_NewLongObj\fR,
-\fBTcl_SetIntObj\fR, and \fBTcl_SetLongObj\fR
-create a new object of integer type
-or modify an existing object to have integer type,
-.VS 8.4
-and \fBTcl_NewWideIntObj\fR and \fBTcl_SetWideIntObj\fR create a new
-object of wide integer type or modify an existing object to have wide
-integer type.
-.VE 8.4
-\fBTcl_NewIntObj\fR and \fBTcl_SetIntObj\fR set the object to have the
-integer value given by \fIintValue\fR,
-\fBTcl_NewLongObj\fR and \fBTcl_SetLongObj\fR
-set the object to have the
-long integer value given by \fIlongValue\fR,
-.VS 8.4
-and \fBTcl_NewWideIntObj\fR and \fBTcl_SetWideIntObj\fR set the object
-to have the wide integer value given by \fIwideValue\fR.
-\fBTcl_NewIntObj\fR, \fBTcl_NewLongObj\fR and \fBTcl_NewWideIntObj\fR
-return a pointer to a newly created object with reference count zero.
-These procedures set the object's type to be integer
-and assign the integer value to the object's internal representation
-\fIlongValue\fR or \fIwideValue\fR member (as appropriate).
-\fBTcl_SetIntObj\fR, \fBTcl_SetLongObj\fR
-and \fBTcl_SetWideIntObj\fR
-.VE 8.4
-invalidate any old string representation and,
-if the object is not already an integer object,
-free any old internal representation.
+.VS 8.5
+These procedures are used to create, modify, and read Tcl objects
+that hold integral values.
.PP
-\fBTcl_GetIntFromObj\fR and \fBTcl_GetLongFromObj\fR
-attempt to return an integer value from the Tcl object \fIobjPtr\fR,
-.VS 8.4
-and \fBTcl_GetWideIntFromObj\fR attempts to return a wide integer
-value from the Tcl object \fIobjPtr\fR.
-If the object is not already an integer object,
-or a wide integer object in the case of \fBTcl_GetWideIntFromObj\fR
-.VE 8.4
-they will attempt to convert it to one.
-If an error occurs during conversion, they return \fBTCL_ERROR\fR
-and leave an error message in the interpreter's result object
-unless \fIinterp\fR is NULL.
-Also, if the long integer held in the object's internal representation
-\fIlongValue\fR member can not be represented in a (non-long) integer,
-\fBTcl_GetIntFromObj\fR returns \fBTCL_ERROR\fR
-and leaves an error message in the interpreter's result object
-unless \fIinterp\fR is NULL.
-Otherwise, all three procedures return \fBTCL_OK\fR and
-store the integer, long integer value
-.VS 8.4
-or wide integer in the address given by \fIintPtr\fR, \fIlongPtr\fR
-and \fIwidePtr\fR
-.VE 8.4
-respectively. If the object is not already an integer or wide integer
-object, the conversion will free any old internal representation.
-
+The different routines exist to accommodate different integral types in C
+with which values might be exchanged. The C integral types for which Tcl
+provides value exchange routines are \fBint\fR, \fBlong int\fR,
+\fBTcl_WideInt\fR, and \fBmp_int\fR. The \fBint\fR and \fBlong int\fR types
+are provided by the C language standard. The \fBTcl_WideInt\fR type is a
+typedef defined to be whatever signed integral type covers at least the
+64-bit integer range (-9223372036854775808 to 9223372036854775807). Depending
+on the platform and the C compiler, the actual type might be
+\fBlong int\fR, \fBlong long int\fR, \fBint64\fR, or something else.
+The \fBmp_int\fR type is a multiple-precision integer type defined
+by the LibTomMath multiple-precision integer library.
+.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.
+.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
+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
+violates Tcl's copy-on-write policy. Any existing string representation
+or internal representation in the unshared Tcl object 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
+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
+value exceeds the range of the target type. If the attempt fails,
+then \fBTCL_ERROR\fR is returned, and if \fIinterp\fR is non-NULL,
+an error message is left in \fIinterp\fR. The \fBTcl_ObjType\fR
+of \fIobjPtr\fR may be changed to make subsequent calls to the
+same routine more efficient. Unlike the other functions,
+\fBTcl_TakeBignumFromObj\fR may set the content of the Tcl object
+\fIobjPtr\fR to an empty string in the process of retrieving the
+multiple-precision integer value.
+.PP
+The choice between \fBTcl_GetBignumFromObj\fR and
+\fBTcl_TakeBignumFromObj\fR is governed by how the caller will
+continue to use \fIobjPtr\fR. If after the \fBmp_int\fR value
+is retrieved from \fIobjPtr\fR, the caller will make no more
+use of \fIobjPtr\fR, then using \fBTcl_TakeBignumFromObj\fR
+permits Tcl to detect when an unshared \fIobjPtr\fR permits the
+value to be moved instead of copied, which should be more efficient.
+If anything later in the caller requires
+\fIobjPtr\fR to continue to hold the same value, then
+\fBTcl_GetBignumFromObj\fR must be chosen.
+.PP
+The \fBTcl_InitBignumFromDouble\fR routine is a utility procedure
+that extracts the integer part of \fIdoubleValue\fR and stores that
+integer value in the \fBmp_int\fR value \fIbigValue\fR.
+.VE 8.5
.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
diff --git a/doc/Interp.3 b/doc/Interp.3
index 7d1f515..0b1de03 100644
--- a/doc/Interp.3
+++ b/doc/Interp.3
@@ -15,9 +15,9 @@ Tcl_Interp \- client-visible fields of interpreter structures
\fB#include <tcl.h>\fR
.sp
typedef struct {
- char *\fIresult\fR;
- Tcl_FreeProc *\fIfreeProc\fR;
- int \fIerrorLine\fR;
+ char *\fIresult\fR;
+ Tcl_FreeProc *\fIfreeProc\fR;
+ int \fIerrorLine\fR;
} Tcl_Interp;
typedef void Tcl_FreeProc(char *\fIblockPtr\fR);
@@ -28,17 +28,23 @@ typedef void Tcl_FreeProc(char *\fIblockPtr\fR);
The \fBTcl_CreateInterp\fR procedure returns a pointer to a Tcl_Interp
structure. This pointer is then passed into other Tcl procedures
to process commands in the interpreter and perform other operations
-on the interpreter. Interpreter structures contain many many fields
+on the interpreter. Interpreter structures contain many fields
that are used by Tcl, but only three that may be accessed by
clients: \fIresult\fR, \fIfreeProc\fR, and \fIerrorLine\fR.
.PP
+.VS 8.5
+\fBNote that access to all three fields, \fIresult\fB, \fIfreeProc\fB and
+\fIerrorLine\fB is deprecated.\fR Use \fBTcl_SetResult\fR,
+\fBTcl_GetResult\fR, and \fBTcl_GetReturnOptions\fR instead.
+.VE 8.5
+.PP
The \fIresult\fR and \fIfreeProc\fR fields are used to return
results or error messages from commands.
This information is returned by command procedures back to \fBTcl_Eval\fR,
and by \fBTcl_Eval\fR back to its callers.
The \fIresult\fR field points to the string that represents the
result or error message, and the \fIfreeProc\fR field tells how
-to dispose of the storage for the string when it isn't needed anymore.
+to dispose of the storage for the string when it is not needed anymore.
The easiest way for command procedures to manipulate these
fields is to call procedures like \fBTcl_SetResult\fR
or \fBTcl_AppendResult\fR; they
@@ -55,7 +61,6 @@ should point to an empty string.
Normally, results are assumed to be statically allocated,
which means that the contents will not change before the next time
\fBTcl_Eval\fR is called or some other command procedure is invoked.
-.VS
In this case, the \fIfreeProc\fR field must be zero.
Alternatively, a command procedure may dynamically
allocate its return value (e.g. using \fBTcl_Alloc\fR)
@@ -64,7 +69,6 @@ In this case, the command procedure must also set \fIinterp->freeProc\fR
to the address of a procedure that can free the value, or \fBTCL_DYNAMIC\fR
if the storage was allocated directly by Tcl or by a call to
\fBTcl_Alloc\fR.
-.VE
If \fIinterp->freeProc\fR is non-zero, then Tcl will call \fIfreeProc\fR
to free the space pointed to by \fIinterp->result\fR before it
invokes the next command.
@@ -76,10 +80,8 @@ macro should be used for this purpose).
\fIFreeProc\fR should have arguments and result that match the
\fBTcl_FreeProc\fR declaration above: it receives a single
argument which is a pointer to the result value to free.
-.VS
In most applications \fBTCL_DYNAMIC\fR is the only non-zero value ever
used for \fIfreeProc\fR.
-.VE
However, an application may store a different procedure address
in \fIfreeProc\fR in order to use an alternate memory allocator
or in order to do other cleanup when the result memory is freed.
diff --git a/doc/Limit.3 b/doc/Limit.3
new file mode 100644
index 0000000..928ebe1
--- /dev/null
+++ b/doc/Limit.3
@@ -0,0 +1,194 @@
+'\"
+'\" Copyright (c) 2004 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 Tcl_LimitCheck 3 8.5 Tcl "Tcl Library Procedures"
+.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
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_LimitCheck\fR(\fIinterp\fR)
+.sp
+int
+\fBTcl_LimitReady\fR(\fIinterp\fR)
+.sp
+int
+\fBTcl_LimitExceeded\fR(\fIinterp\fR)
+.sp
+int
+\fBTcl_LimitTypeExceeded\fR(\fIinterp, type\fR)
+.sp
+int
+\fBTcl_LimitTypeEnabled\fR(\fIinterp, type\fR)
+.sp
+void
+\fBTcl_LimitTypeSet\fR(\fIinterp, type\fR)
+.sp
+void
+\fBTcl_LimitTypeReset\fR(\fIinterp, type\fR)
+.sp
+int
+\fBTcl_LimitGetCommands\fR(\fIinterp\fR)
+.sp
+void
+\fBTcl_LimitSetCommands\fR(\fIinterp, commandLimit\fR)
+.sp
+void
+\fBTcl_LimitGetTime\fR(\fIinterp, timeLimitPtr\fR)
+.sp
+void
+\fBTcl_LimitSetTime\fR(\fIinterp, timeLimitPtr\fR)
+.sp
+int
+\fBTcl_LimitGetGranularity\fR(\fIinterp, type\fR)
+.sp
+void
+\fBTcl_LimitSetGranularity\fR(\fIinterp, type, granularity\fR)
+.sp
+void
+\fBTcl_LimitAddHandler\fR(\fIinterp, type, handlerProc, clientData, deleteProc\fR)
+.sp
+void
+\fBTcl_LimitRemoveHandler\fR(\fIinterp, type, handlerProc, clientData\fR)
+.SH ARGUMENTS
+.AS Tcl_LimitHandlerDeleteProc commandLimit in/out
+.AP Tcl_Interp *interp in
+Interpreter that the limit being managed applies to or that will have
+its limits checked.
+.AP int type in
+The type of limit that the operation refers to. This must be either
+\fBTCL_LIMIT_COMMANDS\fR or \fBTCL_LIMIT_TIME\fR.
+.AP int commandLimit in
+The maximum number of commands (as reported by \fBinfo cmdcount\fR)
+that may be executed in the interpreter.
+.AP Tcl_Time *timeLimitPtr in/out
+A pointer to a structure that will either have the new time limit read
+from (\fBTcl_LimitSetTime\fR) or the current time limit written to
+(\fBTcl_LimitGetTime\fR).
+.AP int granularity in
+Divisor that indicates how often a particular limit should really be
+checked. Must be at least 1.
+.AP Tcl_LimitHandlerProc *handlerProc in
+Function to call when a particular limit is exceeded. If the
+\fIhandlerProc\fR removes or raises the limit during its processing,
+the limited interpreter will be permitted to continue to process after
+the handler returns. Many handlers may be attached to the same
+interpreter limit; their order of execution is not defined, and they
+must be identified by \fIhandlerProc\fR and \fIclientData\fR when they
+are deleted.
+.AP ClientData clientData in
+Arbitrary pointer-sized word used to pass some context to the
+\fIhandlerProc\fR function.
+.AP Tcl_LimitHandlerDeleteProc *deleteProc in
+Function to call whenever a handler is deleted. May be NULL if the
+\fIclientData\fR requires no deletion.
+.BE
+
+.SH DESCRIPTION
+.PP
+Tcl's interpreter resource limit subsystem allows for close control
+over how much computation time a script may use, and is useful for
+cases where a program is divided into multiple pieces where some parts
+are more trusted than others (e.g. web application servers).
+.PP
+Every interpreter may have a limit on the wall-time for execution, and
+a limit on the number of commands that the interpreter may execute.
+Since checking of these limits is potentially expensive (especially
+the time limit), each limit also has a checking granularity, which is
+a divisor for an internal count of the number of points in the core
+where a check may be performed (which is immediately before executing
+a command and at an unspecified frequency between running commands,
+which can happen in empty-bodied \fBwhile\fR loops).
+.PP
+The final component of the limit engine is a callback scheme which
+allows for notifications of when a limit has been exceeded. These
+callbacks can just provide logging, or may allocate more resources to
+the interpreter to permit it to continue processing longer.
+.PP
+When a limit is exceeded (and the callbacks have run; the order of
+execution of the callbacks is unspecified) execution in the limited
+interpreter is stopped by raising an error and setting a flag that
+prevents the \fBcatch\fR command in that interpreter from trapping
+that error. It is up to the context that started execution in that
+interpreter (typically a master interpreter) to handle the error.
+.SH "LIMIT CHECKING API"
+.PP
+To check the resource limits for an interpreter, call
+\fBTcl_LimitCheck\fR, which returns \fBTCL_OK\fR if the limit was not
+exceeded (after processing callbacks) and \fBTCL_ERROR\fR if the limit was
+exceeded (in which case an error message is also placed in the
+interpreter result). That function should only be called when
+\fBTcl_LimitReady\fR returns non-zero so that granularity policy is
+enforced. This API is designed to be similar in usage to
+\fBTcl_AsyncReady\fR and \fBTcl_AsyncInvoke\fR.
+.PP
+When writing code that may behave like \fBcatch\fR in respect of
+errors, you should only trap an error if \fBTcl_LimitExceeded\fR
+returns zero. If it returns non-zero, the interpreter is in a
+limit-exceeded state and errors should be allowed to propagate to the
+calling context. You can also check whether a particular type of
+limit has been exceeded using \fBTcl_LimitTypeExceeded\fR.
+.SH "LIMIT CONFIGURATION"
+.PP
+To check whether a limit has been set (but not whether it has actually
+been exceeded) on an interpreter, call \fBTcl_LimitTypeEnabled\fR with
+the type of limit you want to check. To enable a particular limit
+call \fBTcl_LimitTypeSet\fR, and to disable a limit call
+\fBTcl_LimitTypeReset\fR.
+.PP
+The level of a command limit may be set using
+\fBTcl_LimitSetCommands\fR, and retrieved using
+\fBTcl_LimitGetCommands\fR. Similarly for a time limit with
+\fBTcl_LimitSetTime\fR and \fBTcl_LimitGetTime\fR respectively, but
+with that API the time limit is copied from and to the Tcl_Time
+structure that the \fItimeLimitPtr\fR argument points to.
+.PP
+The checking granularity for a particular limit may be set using
+\fBTcl_LimitSetGranularity\fR and retrieved using
+\fBTcl_LimitGetGranularity\fR. Note that granularities must always be
+positive.
+.SS "LIMIT CALLBACKS"
+.PP
+To add a handler callback to be invoked when a limit is exceeded, call
+\fBTcl_LimitAddHandler\fR. The \fIhandlerProc\fR argument describes
+the function that will actually be called; it should have the
+following prototype:
+.PP
+.CS
+typedef void Tcl_LimitHandlerProc(
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+The \fIclientData\fR argument to the handler will be whatever is
+passed to the \fIclientData\fR argument to \fBTcl_LimitAddHandler\fR,
+and the \fIinterp\fR is the interpreter that had its limit exceeded.
+.PP
+The \fIdeleteProc\fR argument to \fBTcl_LimitAddHandler\fR is a
+function to call to delete the \fIclientData\fR value. It may be
+\fBTCL_STATIC\fR or NULL if no deletion action is necessary, or
+\fBTCL_DYNAMIC\fR if all that is necessary is to free the structure with
+\fBTcl_Free\fR. Otherwise, it should refer to a function with the
+following prototype:
+.PP
+.CS
+typedef void Tcl_LimitHandlerDeleteProc(
+ ClientData \fIclientData\fR);
+.CE
+.PP
+A limit handler may be deleted using \fBTcl_LimitRemoveHandler\fR; the
+handler removed will be the first one found (out of the handlers added
+with \fBTcl_LimitAddHandler\fR) with exactly matching \fItype\fR,
+\fIhandlerProc\fR and \fIclientData\fR arguments. This function
+always invokes the \fIdeleteProc\fR on the \fIclientData\fR (unless
+the \fIdeleteProc\fR was NULL or \fBTCL_STATIC\fR).
+
+.SH KEYWORDS
+interpreter, resource, limit, commands, time, callback
diff --git a/doc/LinkVar.3 b/doc/LinkVar.3
index a1dfcca..6361fb4 100644
--- a/doc/LinkVar.3
+++ b/doc/LinkVar.3
@@ -25,17 +25,24 @@ int
.AP Tcl_Interp *interp in
Interpreter that contains \fIvarName\fR.
Also used by \fBTcl_LinkVar\fR to return error messages.
-.AP "CONST char" *varName in
-Name of global variable.
+.AP "const char" *varName in
+Name of global variable.
.AP char *addr in
Address of C variable that is to be linked to \fIvarName\fR.
.AP int type in
-Type of C variable. Must be one of TCL_LINK_INT, TCL_LINK_DOUBLE,
-.VS 8.4
-TCL_LINK_WIDE_INT,
-.VE 8.4
-TCL_LINK_BOOLEAN, or TCL_LINK_STRING, optionally OR'ed with
-TCL_LINK_READ_ONLY to make Tcl variable read-only.
+Type of C variable. Must be one of \fBTCL_LINK_INT\fR,
+.VS 8.5
+\fBTCL_LINK_UINT\fR, \fBTCL_LINK_CHAR\fR, \fBTCL_LINK_UCHAR\fR,
+\fBTCL_LINK_SHORT\fR, \fBTCL_LINK_USHORT\fR, \fBTCL_LINK_LONG\fR,
+\fBTCL_LINK_ULONG\fR,
+.VE 8.5
+\fBTCL_LINK_WIDE_INT\fR,
+.VS 8.5
+\fBTCL_LINK_WIDE_UINT\fR, \fBTCL_LINK_FLOAT\fR,
+.VE 8.5
+\fBTCL_LINK_DOUBLE\fR, \fBTCL_LINK_BOOLEAN\fR, or
+\fBTCL_LINK_STRING\fR, optionally OR'ed with \fBTCL_LINK_READ_ONLY\fR
+to make Tcl variable read-only.
.BE
.SH DESCRIPTION
@@ -46,14 +53,14 @@ given by \fIaddr\fR.
Whenever the Tcl variable is read the value of the C variable will
be returned, and whenever the Tcl variable is written the C
variable will be updated to have the same value.
-\fBTcl_LinkVar\fR normally returns TCL_OK; if an error occurs
+\fBTcl_LinkVar\fR normally returns \fBTCL_OK\fR; if an error occurs
while setting up the link (e.g. because \fIvarName\fR is the
-name of array) then TCL_ERROR is returned and the interpreter's result
+name of array) then \fBTCL_ERROR\fR is returned and the interpreter's result
contains an error message.
.PP
The \fItype\fR argument specifies the type of the C variable,
and must have one of the following values, optionally OR'ed with
-TCL_LINK_READ_ONLY:
+\fBTCL_LINK_READ_ONLY\fR:
.TP
\fBTCL_LINK_INT\fR
The C variable is of type \fBint\fR.
@@ -61,6 +68,61 @@ Any value written into the Tcl variable must have a proper integer
form acceptable to \fBTcl_GetIntFromObj\fR; attempts to write
non-integer values into \fIvarName\fR will be rejected with
Tcl errors.
+.VS 8.5
+.TP
+\fBTCL_LINK_UINT\fR
+The C variable is of type \fBunsigned int\fR.
+Any value written into the Tcl variable must have a proper unsigned
+integer form acceptable to \fBTcl_GetWideIntFromObj\fR and in the
+platform's defined range for the \fBunsigned int\fR type; attempts to
+write non-integer values (or values outside the range) into
+\fIvarName\fR will be rejected with Tcl errors.
+.TP
+\fBTCL_LINK_CHAR\fR
+The C variable is of type \fBchar\fR.
+Any value written into the Tcl variable must have a proper integer
+form acceptable to \fBTcl_GetIntFromObj\fR and be in the range of the
+\fBchar\fR datatype; attempts to write non-integer or out-of-range
+values into \fIvarName\fR will be rejected with Tcl errors.
+.TP
+\fBTCL_LINK_UCHAR\fR
+The C variable is of type \fBunsigned char\fR.
+Any value written into the Tcl variable must have a proper unsigned
+integer form acceptable to \fBTcl_GetIntFromObj\fR and in the
+platform's defined range for the \fBunsigned char\fR type; attempts to
+write non-integer values (or values outside the range) into
+\fIvarName\fR will be rejected with Tcl errors.
+.TP
+\fBTCL_LINK_SHORT\fR
+The C variable is of type \fBshort\fR.
+Any value written into the Tcl variable must have a proper integer
+form acceptable to \fBTcl_GetIntFromObj\fR and be in the range of the
+\fBshort\fR datatype; attempts to write non-integer or out-of-range
+values into \fIvarName\fR will be rejected with Tcl errors.
+.TP
+\fBTCL_LINK_USHORT\fR
+The C variable is of type \fBunsigned short\fR.
+Any value written into the Tcl variable must have a proper unsigned
+integer form acceptable to \fBTcl_GetIntFromObj\fR and in the
+platform's defined range for the \fBunsigned short\fR type; attempts to
+write non-integer values (or values outside the range) into
+\fIvarName\fR will be rejected with Tcl errors.
+.TP
+\fBTCL_LINK_LONG\fR
+The C variable is of type \fBlong\fR.
+Any value written into the Tcl variable must have a proper integer
+form acceptable to \fBTcl_GetLongFromObj\fR; attempts to write
+non-integer or out-of-range
+values into \fIvarName\fR will be rejected with Tcl errors.
+.TP
+\fBTCL_LINK_ULONG\fR
+The C variable is of type \fBunsigned long\fR.
+Any value written into the Tcl variable must have a proper unsigned
+integer form acceptable to \fBTcl_GetWideIntFromObj\fR and in the
+platform's defined range for the \fBunsigned long\fR type; attempts to
+write non-integer values (or values outside the range) into
+\fIvarName\fR will be rejected with Tcl errors.
+.VE 8.5
.TP
\fBTCL_LINK_DOUBLE\fR
The C variable is of type \fBdouble\fR.
@@ -68,21 +130,44 @@ Any value written into the Tcl variable must have a proper real
form acceptable to \fBTcl_GetDoubleFromObj\fR; attempts to write
non-real values into \fIvarName\fR will be rejected with
Tcl errors.
+.VS 8.5
+.TP
+\fBTCL_LINK_FLOAT\fR
+The C variable is of type \fBfloat\fR.
+Any value written into the Tcl variable must have a proper real
+form acceptable to \fBTcl_GetDoubleFromObj\fR and must be within the
+range acceptable for a \fBfloat\fR; attempts to
+write non-real values (or values outside the range) into
+\fIvarName\fR will be rejected with Tcl errors.
+.VE 8.5
.TP
\fBTCL_LINK_WIDE_INT\fR
-.VS 8.4
The C variable is of type \fBTcl_WideInt\fR (which is an integer type
at least 64-bits wide on all platforms that can support it.)
Any value written into the Tcl variable must have a proper integer
form acceptable to \fBTcl_GetWideIntFromObj\fR; attempts to write
non-integer values into \fIvarName\fR will be rejected with
Tcl errors.
-.VE 8.4
+.VS 8.5
+.TP
+\fBTCL_LINK_WIDE_UINT\fR
+The C variable is of type \fBTcl_WideUInt\fR (which is an unsigned
+integer type at least 64-bits wide on all platforms that can support
+it.)
+Any value written into the Tcl variable must have a proper unsigned
+integer form acceptable to \fBTcl_GetWideIntFromObj\fR (it will be
+cast to unsigned);
+.\" FIXME! Use bignums instead.
+attempts to write non-integer values into \fIvarName\fR will be
+rejected with Tcl errors.
+.VE 8.5
.TP
\fBTCL_LINK_BOOLEAN\fR
The C variable is of type \fBint\fR.
-If its value is zero then it will read from Tcl as ``0'';
-otherwise it will read from Tcl as ``1''.
+If its value is zero then it will read from Tcl as
+.QW 0 ;
+otherwise it will read from Tcl as
+.QW 1 .
Whenever \fIvarName\fR is
modified, the C variable will be set to a 0 or 1 value.
Any value written into the Tcl variable must have a proper boolean
@@ -92,17 +177,16 @@ Tcl errors.
.TP
\fBTCL_LINK_STRING\fR
The C variable is of type \fBchar *\fR.
-.VS
If its value is not NULL then it must be a pointer to a string
allocated with \fBTcl_Alloc\fR or \fBckalloc\fR.
-.VE
Whenever the Tcl variable is modified the current C string will be
freed and new memory will be allocated to hold a copy of the variable's
new value.
If the C variable contains a NULL pointer then the Tcl variable
-will read as ``NULL''.
+will read as
+.QW NULL .
.PP
-If the TCL_LINK_READ_ONLY flag is present in \fItype\fR then the
+If the \fBTCL_LINK_READ_ONLY\fR flag is present in \fItype\fR then the
variable will be read-only from Tcl, so that its value can only be
changed by modifying the C variable.
Attempts to write the variable from Tcl will be rejected with errors.
diff --git a/doc/ListObj.3 b/doc/ListObj.3
index 2adea4e..443eafe 100644
--- a/doc/ListObj.3
+++ b/doc/ListObj.3
@@ -36,7 +36,7 @@ int
int
\fBTcl_ListObjReplace\fR(\fIinterp, listPtr, first, count, objc, objv\fR)
.SH ARGUMENTS
-.AS Tcl_Interp "*CONST objv[]" out
+.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
@@ -71,13 +71,11 @@ will insert into a new list object,
and \fBTcl_ListObjReplace\fR will insert into \fIlistPtr\fR.
For \fBTcl_SetListObj\fR,
the number of Tcl objects to insert into \fIobjPtr\fR.
-.VS
-.AP Tcl_Obj "*CONST\ objv[]" in
+.AP "Tcl_Obj *const" objv[] in
An array of pointers to objects.
\fBTcl_NewListObj\fR will insert these objects into a new list object
and \fBTcl_ListObjReplace\fR will insert them into an existing \fIlistPtr\fR.
Each object will become a separate list element.
-.VE
.AP int *intPtr out
Points to location where \fBTcl_ListObjLength\fR
stores the length of the list.
@@ -151,8 +149,9 @@ has reference count zero.
the elements in a list object. 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 by the
-caller.
+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
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
@@ -219,27 +218,33 @@ 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
just before the element \fIindex\fR of the list referenced by \fIlistPtr\fR:
+.PP
.CS
-result = Tcl_ListObjReplace(interp, listPtr, index, 0, objc, objv);
+result = Tcl_ListObjReplace(interp, listPtr, index, 0,
+ objc, objv);
.CE
+.PP
Similarly, the following code appends the \fIobjc\fR objects
referenced by the array \fIobjv\fR
to the end of the list \fIlistPtr\fR:
+.PP
.CS
result = Tcl_ListObjLength(interp, listPtr, &length);
if (result == TCL_OK) {
- result = Tcl_ListObjReplace(interp, listPtr, length, 0, objc, objv);
+ result = Tcl_ListObjReplace(interp, listPtr, length, 0,
+ objc, objv);
}
.CE
+.PP
The \fIcount\fR list elements starting at \fIfirst\fR can be deleted
by simply calling \fBTcl_ListObjReplace\fR
with a NULL \fIobjvPtr\fR:
+.PP
.CS
-result = Tcl_ListObjReplace(interp, listPtr, first, count, 0, NULL);
+result = Tcl_ListObjReplace(interp, listPtr, first, count,
+ 0, NULL);
.CE
-
.SH "SEE ALSO"
Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_GetObjResult
-
.SH KEYWORDS
append, index, insert, internal representation, length, list, list object, list type, object, object type, replace, string representation
diff --git a/doc/Macintosh.3 b/doc/Macintosh.3
deleted file mode 100644
index cd97578..0000000
--- a/doc/Macintosh.3
+++ /dev/null
@@ -1,109 +0,0 @@
-'\"
-'\" Copyright (c) 1997-1998 Sun Microsystems, Inc.
-'\"
-'\" 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_MacSetEventProc 3 "8.1" Tcl "Tcl Library Procedures"
-.BS
-.SH NAME
-Tcl_MacSetEventProc, Tcl_MacConvertTextResource, Tcl_MacEvalResource, Tcl_MacFindResource, Tcl_GetOSTypeFromObj, Tcl_SetOSTypeObj, Tcl_NewOSTypeObj \- procedures to handle Macintosh resources and other Macintosh specifics
-.SH SYNOPSIS
-.nf
-\fB#include <tcl.h>\fR
-.sp
-int
-\fBTcl_MacEvalResource\fR(\fIinterp, resourceName, resourceNumber, fileName\fR)
-.sp
-char*
-\fBTcl_MacConvertTextResource\fR(\fIresource\fR)
-.sp
-Handle
-\fBTcl_MacFindResource\fR(\fIinterp, resourceType, resourceName, resourceNumber, resFileRef, releaseIt\fR)
-.sp
-Tcl_Obj*
-\fBTcl_NewOSTypeObj\fR(\fInewOSType\fR)
-.sp
-void
-\fBTcl_SetOSTypeObj\fR(\fIobjPtr, newOSType\fR)
-.sp
-int
-\fBTcl_GetOSTypeFromObj\fR(\fIinterp, objPtr, osTypePtr\fR)
-.sp
-void
-\fBTcl_MacSetEventProc\fR(\fIprocPtr\fR)
-.SH ARGUMENTS
-.AP Tcl_Interp *interp in
-Interpreter to use for error reporting, or NULL if no error reporting is
-desired.
-.AP "CONST char" *resourceName in
-Name of TEXT resource to source, NULL if number should be used.
-.AP int resourceNumber in
-Resource id of source.
-.AP "CONST char" *fileName in
-Name of file to process. NULL if application resource.
-.AP Handle resource in
-Handle to TEXT resource.
-.AP long resourceType in
-Type of resource to load.
-.AP "CONST char" *resFileRef in
-Registered resource file reference, NULL if searching all open resource files.
-.AP int *releaseIt out
-Should we release this resource when done.
-.AP int newOSType in
-Int used to initialize the new object or set the object's value.
-.AP Tcl_Obj *objPtr in
-Object whose internal representation is to be set or retrieved.
-.AP osTypePtr out
-Place to store the resulting integer.
-.AP Tcl_MacConvertEventPtr procPtr in
-Reference to the new function to handle all incoming Mac events.
-
-.BE
-.SH INTRODUCTION
-.PP
-The described routines are used to implement the Macintosh specific
-\fBresource\fR command and the Mac specific notifier.. They manipulate
-or use Macintosh resources and provide administration for open
-resource file references.
-
-.SH DESCRIPTION
-.PP
-\fBTcl_MacEvalResource\fR extends the \fBsource\fR command to
-Macintosh resources. It sources Tcl code from a Text resource.
-Currently only sources the resource by name, file IDs may be supported
-at a later date.
-.PP
-\fBTcl_MacConvertTextResource\fR converts a TEXT resource into a Tcl
-suitable string. It mallocs the returned memory, converts ``\\r'' to
-``\\n'', and appends a null. The caller has the responsibility for
-freeing the memory.
-.PP
-\fBTcl_MacFindResource\fR provides a higher level interface for
-loading resources. It is used by \fBresource read\fR.
-.PP
-\fBTcl_NewOSTypeObj\fR is used to create a new resource name type
-object. The object type is "ostype".
-.PP
-\fBTcl_SetOSTypeObj\fR modifies an object to be a resource type and to
-have the specified long value.
-.PP
-\fBTcl_GetOSTypeFromObj\fR attempts to return an int from the Tcl
-object "objPtr". If the object is not already an int, an attempt will
-be made to convert it to one.
-.PP
-\fBTcl_MacSetEventProc\fR sets the event handling procedure for the
-application. This function will be passed all incoming Mac events.
-This function usually controls the console or some other entity like
-Tk.
-
-.SH RESOURCE TYPES
-.PP
-Resource types are 4-byte values used by the macintosh resource
-facility to tag parts of the resource fork in a file so that the OS
-knows how to handle them. As all 4 bytes are restricted to printable
-characters such a type can be interpreted as a 4 character string too.
-
-.SH KEYWORDS
-macintosh, mac, resource, notifier
diff --git a/doc/Namespace.3 b/doc/Namespace.3
new file mode 100644
index 0000000..5477329
--- /dev/null
+++ b/doc/Namespace.3
@@ -0,0 +1,165 @@
+'\"
+'\" Copyright (c) 2003 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" 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"
+.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
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Namespace *
+\fBTcl_CreateNamespace\fR(\fIinterp, name, clientData, deleteProc\fR)
+.sp
+\fBTcl_DeleteNamespace\fR(\fInsPtr\fR)
+.sp
+int
+\fBTcl_AppendExportList\fR(\fIinterp, nsPtr, objPtr\fR)
+.sp
+int
+\fBTcl_Export\fR(\fIinterp, nsPtr, pattern, resetListFirst\fR)
+.sp
+int
+\fBTcl_Import\fR(\fIinterp, nsPtr, pattern, allowOverwrite\fR)
+.sp
+int
+\fBTcl_ForgetImport\fR(\fIinterp, nsPtr, pattern\fR)
+.sp
+Tcl_Namespace *
+\fBTcl_GetCurrentNamespace\fR(\fIinterp\fR)
+.sp
+Tcl_Namespace *
+\fBTcl_GetGlobalNamespace\fR(\fIinterp\fR)
+.sp
+Tcl_Namespace *
+\fBTcl_FindNamespace\fR(\fIinterp, name, contextNsPtr, flags\fR)
+.sp
+Tcl_Command
+\fBTcl_FindCommand\fR(\fIinterp, name, contextNsPtr, flags\fR)
+.sp
+Tcl_Obj *
+\fBTcl_GetNamespaceUnknownHandler(\fIinterp, nsPtr\fR)
+.sp
+int
+\fBTcl_SetNamespaceUnknownHandler(\fIinterp, nsPtr, handlerPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_NamespaceDeleteProc allowOverwrite in/out
+.AP Tcl_Interp *interp in/out
+The interpreter in which the namespace exists and where name lookups
+are performed. Also where error result messages are written.
+.AP "const char" *name in
+The name of the namespace or command to be created or accessed.
+.AP ClientData clientData in
+A context pointer by the creator of the namespace. Not interpreted by
+Tcl at all.
+.AP Tcl_NamespaceDeleteProc *deleteProc in
+A pointer to function to call when the namespace is deleted, or NULL
+if no such callback is to be performed.
+.AP Tcl_Namespace *nsPtr in
+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
+written.
+.AP "const char" *pattern in
+The glob-style pattern (see \fBTcl_StringMatch\fR) that describes the
+commands to be imported or exported.
+.AP int resetListFirst in
+Whether the list of export patterns should be reset before adding the
+current pattern to it.
+.AP int allowOverwrite in
+Whether new commands created by this import action can overwrite
+existing commands.
+.AP Tcl_Namespace *contextNsPtr in
+The location in the namespace hierarchy where the search for a
+namespace or command should be conducted relative to when the search
+term is not rooted at the global namespace. NULL indicates the
+current namespace.
+.AP int flags in
+OR-ed combination of bits controlling how the search is to be
+performed. The following flags are supported: \fBTCL_GLOBAL_ONLY\fR
+(indicates that the search is always to be conducted relative to the
+global namespace), \fBTCL_NAMESPACE_ONLY\fR (just for \fBTcl_FindCommand\fR;
+indicates that the search is always to be conducted relative to the
+context namespace), and \fBTCL_LEAVE_ERR_MSG\fR (indicates that an error
+message should be left in the interpreter if the search fails.)
+.AP Tcl_Obj *handlerPtr in
+A script fragment to be installed as the unknown command handler for the
+namespace, or NULL to reset the handler to its default.
+.BE
+
+.SH DESCRIPTION
+.PP
+Namespaces are hierarchic naming contexts that can contain commands
+and variables. They also maintain a list of patterns that describes
+what commands are exported, and can import commands that have been
+exported by other namespaces. Namespaces can also be manipulated
+through the Tcl command \fBnamespace\fR.
+.PP
+The \fITcl_Namespace\fR structure encapsulates a namespace, and is
+guaranteed to have the following fields in it: \fIname\fR (the local
+name of the namespace, with no namespace separator characters in it,
+with empty denoting the global namespace), \fIfullName\fR (the fully
+specified name of the namespace), \fIclientData\fR, \fIdeleteProc\fR
+(the values specified in the call to \fBTcl_CreateNamespace\fR), and
+\fIparentPtr\fR (a pointer to the containing namespace, or NULL for
+the global namespace.)
+.PP
+\fBTcl_CreateNamespace\fR creates a new namespace. The
+\fIdeleteProc\fR will have the following type signature:
+.CS
+typedef void (Tcl_NamespaceDeleteProc) (ClientData clientData);
+.CE
+.PP
+\fBTcl_DeleteNamespace\fR deletes a namespace.
+.PP
+\fBTcl_AppendExportList\fR retrieves the export patterns for a
+namespace given namespace and appends them (as list items) to
+\fIobjPtr\fR.
+.PP
+\fBTcl_Export\fR sets and appends to the export patterns for a
+namespace. Patterns are appended unless the \fIresetListFirst\fR flag
+is true.
+.PP
+\fBTcl_Import\fR imports commands matching a pattern into a
+namespace. Note that the pattern must include the name of the
+namespace to import from. This function returns an error if
+an attempt to import a command over an existing command is made,
+unless the \fIallowOverwrite\fR flag has been set.
+.PP
+\fBTcl_ForgetImport\fR removes imports matching a pattern.
+.PP
+\fBTcl_GetCurrentNamespace\fR returns the current namespace for an
+interpreter.
+.PP
+\fBTcl_GetGlobalNamespace\fR returns the global namespace for an
+interpreter.
+.PP
+\fBTcl_FindNamespace\fR searches for a namespace named \fIname\fR
+within the context of the namespace \fIcontextNsPtr\fR. If the
+namespace cannot be found, NULL is returned.
+.PP
+\fBTcl_FindCommand\fR searches for a command named \fIname\fR within
+the context of the namespace \fIcontextNsPtr\fR. If the command
+cannot be found, NULL is returned.
+.PP
+\fBTcl_GetNamespaceUnknownHandler\fR returns the unknown command handler
+for the namespace, or NULL if none is set.
+.PP
+\fBTcl_SetNamespaceUnknownHandler\fR sets the unknown command handler for
+the namespace. If \fIhandlerPtr\fR is NULL, then the handler is reset to
+its default.
+
+.SH "SEE ALSO"
+Tcl_CreateCommand, Tcl_ListObjAppendElements, Tcl_SetVar
+
+.SH KEYWORDS
+namespace, command
diff --git a/doc/Notifier.3 b/doc/Notifier.3
index bb2fef4..7858a8c 100644
--- a/doc/Notifier.3
+++ b/doc/Notifier.3
@@ -25,7 +25,6 @@ void
.sp
void
\fBTcl_QueueEvent\fR(\fIevPtr, position\fR)
-.VS 8.1
.sp
void
\fBTcl_ThreadQueueEvent\fR(\fIthreadId, evPtr, position\fR)
@@ -63,12 +62,16 @@ int
int
\fBTcl_GetServiceMode\fR()
.sp
-int
+int
\fBTcl_SetServiceMode\fR(\fImode\fR)
-.VE
-
+.sp
+void
+\fBTcl_ServiceModeHook\fR(\fImode\fR)
+.sp
+void
+\fBTcl_SetNotifier\fR(\fInotifierProcPtr\fR)
.SH ARGUMENTS
-.AS Tcl_EventDeleteProc milliseconds
+.AS Tcl_EventDeleteProc *notifierProcPtr
.AP Tcl_EventSetupProc *setupProc in
Procedure to invoke to prepare for event wait in \fBTcl_DoOneEvent\fR.
.AP Tcl_EventCheckProc *checkProc in
@@ -97,11 +100,13 @@ Procedure to invoke for each queued event in \fBTcl_DeleteEvents\fR.
.AP int flags in
What types of events to service. These flags are the same as those
passed to \fBTcl_DoOneEvent\fR.
-.VS 8.1
.AP int mode in
Indicates whether events should be serviced by \fBTcl_ServiceAll\fR.
Must be one of \fBTCL_SERVICE_NONE\fR or \fBTCL_SERVICE_ALL\fR.
-.VE
+.AP Tcl_NotifierProcs* notifierProcPtr in
+Structure of function pointers describing notifier procedures that are
+to replace the ones installed in the executable. See
+\fBREPLACING THE NOTIFIER\fR for details.
.BE
.SH INTRODUCTION
@@ -135,9 +140,7 @@ sources place events onto the queue so that they may be processed in
order at appropriate times during the event loop. The event queue
guarantees a fair discipline of event handling, so that no event
source can starve the others. It also allows events to be saved for
-servicing at a future time.
-.VS 8.1
-Threaded applications work in a
+servicing at a future time. Threaded applications work in a
similar manner, except that there is a separate event queue for
each thread containing a Tcl interpreter.
\fBTcl_QueueEvent\fR is used (primarily
@@ -169,7 +172,6 @@ The procedures \fBTcl_ServiceAll\fR, \fBTcl_ServiceEvent\fR,
to help connect Tcl's event loop to an external event loop such as
Motif's.
.SH "NOTIFIER BASICS"
-.VE
.PP
The easiest way to understand how the notifier works is to consider
what happens when \fBTcl_DoOneEvent\fR is called.
@@ -180,17 +182,13 @@ things:
.IP [1]
Check the event queue to see if it contains any events that can
be serviced. If so, service the first possible event, remove it
-.VS 8.1
from the queue, and return. It does this by calling
\fBTcl_ServiceEvent\fR and passing in the \fIflags\fR argument.
-.VE
.IP [2]
Prepare to block for an event. To do this, \fBTcl_DoOneEvent\fR
invokes a \fIsetup procedure\fR in each event source.
The event source will perform event-source specific initialization and
-.VS 8.1
possibly call \fBTcl_SetMaxBlockTime\fR to limit how long
-.VE
\fBTcl_WaitForEvent\fR will block if no new events occur.
.IP [3]
Call \fBTcl_WaitForEvent\fR. This procedure is implemented differently
@@ -233,8 +231,8 @@ the event source.
\fISetupProc\fR should match the following prototype:
.CS
typedef void Tcl_EventSetupProc(
- ClientData \fIclientData\fR,
- int \fIflags\fR);
+ ClientData \fIclientData\fR,
+ int \fIflags\fR);
.CE
The \fIclientData\fR argument will be the same as the \fIclientData\fR
argument to \fBTcl_CreateEventSource\fR; it is typically used to
@@ -243,7 +241,7 @@ The \fIflags\fR argument will be the same as the \fIflags\fR
argument passed to \fBTcl_DoOneEvent\fR except that it will never
be 0 (\fBTcl_DoOneEvent\fR replaces 0 with \fBTCL_ALL_EVENTS\fR).
\fIFlags\fR indicates what kinds of events should be considered;
-if the bit corresponding to this event source isn't set, the event
+if the bit corresponding to this event source is not set, the event
source should return immediately without doing anything. For
example, the file event source checks for the \fBTCL_FILE_EVENTS\fR
bit.
@@ -256,7 +254,6 @@ request notification with a Windows event. For timer-driven event
sources such as timer events or any polled event, the event source
can call \fBTcl_SetMaxBlockTime\fR to force the application to wake
up after a specified time even if no events have occurred.
-.VS 8.1
If no event source calls \fBTcl_SetMaxBlockTime\fR
then \fBTcl_WaitForEvent\fR will wait as long as necessary for an
event to occur; otherwise, it will only wait as long as the shortest
@@ -268,28 +265,24 @@ events already queued. If there are, it calls
\fBTcl_SetMaxBlockTime\fR with a 0 block time so that
\fBTcl_WaitForEvent\fR does not block if there is no new data on the X
connection.
-.VE
The \fItimePtr\fR argument to \fBTcl_WaitForEvent\fR points to
a structure that describes a time interval in seconds and
microseconds:
.CS
typedef struct Tcl_Time {
- long \fIsec\fR;
- long \fIusec\fR;
+ long \fIsec\fR;
+ long \fIusec\fR;
} Tcl_Time;
.CE
The \fIusec\fR field should be less than 1000000.
.PP
-.VS 8.1
Information provided to \fBTcl_SetMaxBlockTime\fR
is only used for the next call to \fBTcl_WaitForEvent\fR; it is
discarded after \fBTcl_WaitForEvent\fR returns.
-.VE
The next time an event wait is done each of the event sources'
setup procedures will be called again, and they can specify new
information for that event wait.
.PP
-.VS 8.1
If the application uses an external event loop rather than
\fBTcl_DoOneEvent\fR, the event sources may need to call
\fBTcl_SetMaxBlockTime\fR at other times. For example, if a new event
@@ -305,7 +298,6 @@ platform-specific procedures may also be available for
\fIsetupProc\fR, if there is additional information needed by
\fBTcl_WaitForEvent\fR on that platform. For example, on Unix systems
the \fBTcl_CreateFileHandler\fR interface can be used to wait for file events.
-.VE
.PP
The second procedure provided by each event source is its check
procedure, indicated by the \fIcheckProc\fR argument to
@@ -313,8 +305,8 @@ procedure, indicated by the \fIcheckProc\fR argument to
following prototype:
.CS
typedef void Tcl_EventCheckProc(
- ClientData \fIclientData\fR,
- int \fIflags\fR);
+ ClientData \fIclientData\fR,
+ int \fIflags\fR);
.CE
The arguments to this procedure are the same as those for \fIsetupProc\fR.
\fBCheckProc\fR is invoked by \fBTcl_DoOneEvent\fR after it has waited
@@ -363,24 +355,20 @@ events at the front of the queue, such as a series of
Enter and Leave events synthesized during a grab or ungrab operation
in Tk.
.PP
-.VS 8.1
When it is time to handle an event from the queue (steps 1 and 4
above) \fBTcl_ServiceEvent\fR will invoke the \fIproc\fR specified
-.VE
in the first queued \fBTcl_Event\fR structure.
\fIProc\fR must match the following prototype:
.CS
typedef int Tcl_EventProc(
- Tcl_Event *\fIevPtr\fR,
- int \fIflags\fR);
+ Tcl_Event *\fIevPtr\fR,
+ int \fIflags\fR);
.CE
The first argument to \fIproc\fR is a pointer to the event, which will
be the same as the first argument to the \fBTcl_QueueEvent\fR call that
added the event to the queue.
The second argument to \fIproc\fR is the \fIflags\fR argument for the
-.VS 8.1
current call to \fBTcl_ServiceEvent\fR; this is used by the event source
-.VE
to return immediately if its events are not relevant.
.PP
It is up to \fIproc\fR to handle the event, typically by invoking
@@ -389,20 +377,17 @@ Once the event source has finished handling the event it returns 1
to indicate that the event can be removed from the queue.
If for some reason the event source decides that the event cannot
be handled at this time, it may return 0 to indicate that the event
-.VS 8.1
should be deferred for processing later; in this case \fBTcl_ServiceEvent\fR
-.VE
will go on to the next event in the queue and attempt to service it.
There are several reasons why an event source might defer an event.
One possibility is that events of this type are excluded by the
\fIflags\fR argument.
For example, the file event source will always return 0 if the
-\fBTCL_FILE_EVENTS\fR bit isn't set in \fIflags\fR.
+\fBTCL_FILE_EVENTS\fR bit is not set in \fIflags\fR.
Another example of deferring events happens in Tk if
\fBTk_RestrictEvents\fR has been invoked to defer certain kinds
of window events.
.PP
-.VS 8.1
When \fIproc\fR returns 1, \fBTcl_ServiceEvent\fR will remove the
event from the event queue and free its storage.
Note that the storage for an event must be allocated by
@@ -422,8 +407,9 @@ Tcl_ThreadID for the current thread, use the \fBTcl_GetCurrentThread\fR
procedure. (A thread would then need to pass this identifier to other
threads for those threads to be able to add events to its queue.)
After adding an event to another thread's queue, you then typically
-need to call \fBTcl_ThreadAlert\fR to "wake up" that thread's notifier to
-alert it to the new event.
+need to call \fBTcl_ThreadAlert\fR to
+.QW "wake up"
+that thread's notifier to alert it to the new event.
.PP
\fBTcl_DeleteEvents\fR can be used to explicitly remove one or more
events from the event queue. \fBTcl_DeleteEvents\fR calls \fIproc\fR
@@ -432,8 +418,8 @@ returns 1. Events for which the procedure returns 0 are left in the
queue. \fIProc\fR should match the following prototype:
.CS
typedef int Tcl_EventDeleteProc(
- Tcl_Event *\fIevPtr\fR,
- ClientData \fIclientData\fR);
+ Tcl_Event *\fIevPtr\fR,
+ ClientData \fIclientData\fR);
.CE
The \fIclientData\fR argument will be the same as the \fIclientData\fR
argument to \fBTcl_DeleteEvents\fR; it is typically used to point to
@@ -444,23 +430,21 @@ point to the next event in the queue.
\fIcheckProc\fR, and \fIclientData\fR arguments must exactly match those
provided to the \fBTcl_CreateEventSource\fR for the event source to be deleted.
If no such source exists, \fBTcl_DeleteEventSource\fR has no effect.
-.VE
.SH "CREATING A NEW NOTIFIER"
.PP
The notifier consists of all the procedures described in this manual
entry, plus \fBTcl_DoOneEvent\fR and \fBTcl_Sleep\fR, which are
-.VS 8.1
available on all platforms, and \fBTcl_CreateFileHandler\fR and
\fBTcl_DeleteFileHandler\fR, which are Unix-specific. Most of these
procedures are generic, in that they are the same for all notifiers.
-However, eight of the procedures are notifier-dependent:
-\fBTcl_InitNotifier\fR, \fBTcl_AlertNotifier\fR, \fBTcl_FinalizeNotifier\fR,
-\fBTcl_SetTimer\fR, \fBTcl_Sleep\fR, \fBTcl_WaitForEvent\fR,
-\fBTcl_CreateFileHandler\fR and \fBTcl_DeleteFileHandler\fR. To
-support a new platform or to integrate Tcl with an
-application-specific event loop, you must write new versions of these
-procedures.
+However, none of the procedures are notifier-dependent:
+\fBTcl_InitNotifier\fR, \fBTcl_AlertNotifier\fR,
+\fBTcl_FinalizeNotifier\fR, \fBTcl_SetTimer\fR, \fBTcl_Sleep\fR,
+\fBTcl_WaitForEvent\fR, \fBTcl_CreateFileHandler\fR,
+\fBTcl_DeleteFileHandler\fR and \fBTcl_ServiceModeHook\fR. To support a
+new platform or to integrate Tcl with an application-specific event loop,
+you must write new versions of these procedures.
.PP
\fBTcl_InitNotifier\fR initializes the notifier state and returns
a handle to the notifier state. Tcl calls this
@@ -469,7 +453,9 @@ procedure when initializing a Tcl interpreter. Similarly,
called by \fBTcl_Finalize\fR when shutting down a Tcl interpreter.
.PP
\fBTcl_WaitForEvent\fR is the lowest-level procedure in the notifier;
-it is responsible for waiting for an ``interesting'' event to occur or
+it is responsible for waiting for an
+.QW interesting
+event to occur or
for a given time to elapse. Before \fBTcl_WaitForEvent\fR is invoked,
each of the event sources' setup procedure will have been invoked.
The \fItimePtr\fR argument to
@@ -483,13 +469,13 @@ to occur; it should not actually process the event in any way.
Later on, the
event sources will process the raw events and create Tcl_Events on
the event queue in their \fIcheckProc\fR procedures.
-However, on some platforms (such as Windows) this isn't possible;
+However, on some platforms (such as Windows) this is not possible;
events may be processed in \fBTcl_WaitForEvent\fR, including queuing
Tcl_Events and more (for example, callbacks for native widgets may be
invoked). The return value from \fBTcl_WaitForEvent\fR must be either
0, 1, or \-1. On platforms such as Windows where events get processed in
\fBTcl_WaitForEvent\fR, a return value of 1 means that there may be more
-events still pending that haven't been processed. This is a sign to the
+events still pending that have not been processed. This is a sign to the
caller that it must call \fBTcl_WaitForEvent\fR again if it wants all
pending events to be processed. A 0 return value means that calling
\fBTcl_WaitForEvent\fR again will not have any effect: either this is a
@@ -504,7 +490,9 @@ forever because there were no active event sources and the timeout was
infinite.
.PP
\fBTcl_AlertNotifier\fR is used in multithreaded applications to allow
-any thread to "wake up" the notifier to alert it to new events on its
+any thread to
+.QW "wake up"
+the notifier to alert it to new events on its
queue. \fBTcl_AlertNotifier\fR requires as an argument the notifier
handle returned by \fBTcl_InitNotifier\fR.
.PP
@@ -514,11 +502,18 @@ invoked by \fBTcl_SetMaxBlockTime\fR whenever the maximum blocking
time has been reduced. \fBTcl_SetTimer\fR should arrange for the
external event loop to invoke \fBTcl_ServiceAll\fR after the specified
interval even if no events have occurred. This interface is needed
-because \fBTcl_WaitForEvent\fR isn't invoked when there is an external
+because \fBTcl_WaitForEvent\fR is not invoked when there is an external
event loop. If the
notifier will only be used from \fBTcl_DoOneEvent\fR, then
\fBTcl_SetTimer\fR need not do anything.
.PP
+\fBTcl_ServiceModeHook\fR is called by the platform-independent portion
+of the notifier when client code makes a call to
+\fBTcl_SetServiceMode\fR. This hook is provided to support operating
+systems that require special event handling when the application is in
+a modal loop (the Windows notifier, for instance, uses this hook to
+create a communication window).
+.PP
On Unix systems, the file event source also needs support from the
notifier. The file event source consists of the
\fBTcl_CreateFileHandler\fR and \fBTcl_DeleteFileHandler\fR
@@ -532,6 +527,38 @@ The easiest way to create a new notifier is to look at the code
for an existing notifier, such as the files \fBunix/tclUnixNotfy.c\fR
or \fBwin/tclWinNotify.c\fR in the Tcl source distribution.
+.SH "REPLACING THE NOTIFIER"
+.PP
+A notifier that has been written according to the conventions above
+can also be installed in a running process in place of the standard
+notifier. This mechanism is used so that a single executable can be
+used (with the standard notifier) as a stand-alone program and reused
+(with a replacement notifier in a loadable extension) as an extension
+to another program, such as a Web browser plugin.
+.PP
+To do this, the extension makes a call to \fBTcl_SetNotifier\fR
+passing a pointer to a \fBTcl_NotifierProcs\fR data structure. The
+structure has the following layout:
+.CS
+typedef struct Tcl_NotifierProcs {
+ Tcl_SetTimerProc *setTimerProc;
+ Tcl_WaitForEventProc *waitForEventProc;
+ Tcl_CreateFileHandlerProc *createFileHandlerProc;
+ Tcl_DeleteFileHandlerProc *deleteFileHandlerProc;
+ Tcl_InitNotifierProc *initNotifierProc;
+ Tcl_FinalizeNotifierProc *finalizeNotifierProc;
+ Tcl_AlertNotifierProc *alertNotifierProc;
+ Tcl_ServiceModeHookProc *serviceModeHookProc;
+} Tcl_NotifierProcs;
+.CE
+Following the call to \fBTcl_SetNotifier\fR, the pointers given in
+the \fBTcl_NotifierProcs\fR structure replace whatever notifier had
+been installed in the process.
+.PP
+It is extraordinarily unwise to replace a running notifier. Normally,
+\fBTcl_SetNotifier\fR should be called at process initialization time
+before the first call to \fBTcl_InitNotifier\fR.
+
.SH "EXTERNAL EVENT LOOPS"
.PP
The notifier interfaces are designed so that Tcl can be embedded into
@@ -592,7 +619,7 @@ then calls to \fBTcl_ServiceAll\fR will behave normally.
mode, which should be restored when the recursive loop exits.
\fBTcl_GetServiceMode\fR returns the current value of the service
mode.
-.VE
+
.SH "SEE ALSO"
\fBTcl_CreateFileHandler\fR, \fBTcl_DeleteFileHandler\fR, \fBTcl_Sleep\fR,
\fBTcl_DoOneEvent\fR, \fBThread(3)\fR
diff --git a/doc/Object.3 b/doc/Object.3
index 4e8fa6f..4817b9b 100644
--- a/doc/Object.3
+++ b/doc/Object.3
@@ -5,7 +5,7 @@
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.so man.macros
-.TH Tcl_Obj 3 8.1 Tcl "Tcl Library Procedures"
+.TH Tcl_Obj 3 8.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_NewObj, Tcl_DuplicateObj, Tcl_IncrRefCount, Tcl_DecrRefCount, Tcl_IsShared, Tcl_InvalidateStringRep \- manipulate Tcl objects
@@ -28,7 +28,7 @@ int
.sp
\fBTcl_InvalidateStringRep\fR(\fIobjPtr\fR)
.SH ARGUMENTS
-.AS Tcl_Obj *objPtr in
+.AS Tcl_Obj *objPtr
.AP Tcl_Obj *objPtr in
Points to an object;
must have been the result of a previous call to \fBTcl_NewObj\fR.
@@ -100,34 +100,37 @@ reclaim an object's storage.
.PP
Tcl objects are typed.
An object's internal representation is controlled by its type.
-Seven types are predefined in the Tcl core
+Several types are predefined in the Tcl core
including integer, double, list, and bytecode.
Extension writers can extend the set of types
-by using the procedure \fBTcl_RegisterObjType\fR .
-
+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
which is defined as follows.
.CS
typedef struct Tcl_Obj {
- int \fIrefCount\fR;
- char *\fIbytes\fR;
- int \fIlength\fR;
- Tcl_ObjType *\fItypePtr\fR;
- union {
- long \fIlongValue\fR;
- double \fIdoubleValue\fR;
- VOID *\fIotherValuePtr\fR;
- struct {
- VOID *\fIptr1\fR;
- VOID *\fIptr2\fR;
- } \fItwoPtrValue\fR;
- } \fIinternalRep\fR;
+ int \fIrefCount\fR;
+ char *\fIbytes\fR;
+ int \fIlength\fR;
+ Tcl_ObjType *\fItypePtr\fR;
+ union {
+ long \fIlongValue\fR;
+ double \fIdoubleValue\fR;
+ void *\fIotherValuePtr\fR;
+ Tcl_WideInt \fIwideValue\fR;
+ struct {
+ void *\fIptr1\fR;
+ void *\fIptr2\fR;
+ } \fItwoPtrValue\fR;
+ struct {
+ void *\fIptr\fR;
+ unsigned long \fIvalue\fR;
+ } \fIptrAndLongRep\fR;
+ } \fIinternalRep\fR;
} Tcl_Obj;
.CE
The \fIbytes\fR and the \fIlength\fR members together hold
-.VS 8.1
an object'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.)
@@ -137,7 +140,6 @@ The byte array must always have a null byte after the last data byte,
at offset \fIlength\fR;
this allows string representations
to be treated as conventional null-terminated C strings.
-.VE 8.1
C programs use \fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR to get
an object's string representation.
If \fIbytes\fR is NULL,
@@ -151,10 +153,11 @@ the internal representation is invalid.
.PP
The \fIinternalRep\fR union member holds
an object's internal representation.
-This is either a (long) integer, a double-precision floating point number,
+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,
-or two arbitrary pointers.
+needed by the object's type to represent the object, 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.
@@ -224,7 +227,6 @@ creates a new internal representation for an object
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"
.PP
As an example of the lifetime of an object,
@@ -262,9 +264,8 @@ no longer corresponds to the internal representation.
.CE
The string representation of \fIx\fR's object is needed
and is recomputed.
-The string representation is now \fB124\fR.
+The string representation is now \fB124\fR
and both representations are again valid.
-
.SH "STORAGE MANAGEMENT OF OBJECTS"
.PP
Tcl objects are allocated on the heap and are shared as much as possible
@@ -281,7 +282,7 @@ if the object's reference count drops to zero, frees its storage.
An object shared by different code or data structures has
\fIrefCount\fR greater than 1.
Incrementing an object's reference count ensures that
-it won't be freed too early or have its value change accidently.
+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.
@@ -297,7 +298,7 @@ When an object'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 don't retain a pointer to the object after they return.
+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,
they must be careful to increment its reference count
since the retained pointer is a new reference.
@@ -312,26 +313,29 @@ by using \fBTcl_DuplicateObj\fR;
this returns a new duplicate of the original object
that has \fIrefCount\fR 0.
If the object is not shared,
-the command procedure "owns" the object and can safely modify it directly.
+the command procedure
+.QW "owns"
+the object 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
by inserting \fIobjc-3\fR new elements before \fIindex\fR.
+.PP
.CS
listPtr = objv[1];
if (Tcl_IsShared(listPtr)) {
- listPtr = Tcl_DuplicateObj(listPtr);
+ listPtr = Tcl_DuplicateObj(listPtr);
}
-result = Tcl_ListObjReplace(interp, listPtr, index, 0, (objc-3), &(objv[3]));
+result = Tcl_ListObjReplace(interp, listPtr, index, 0,
+ (objc-3), &(objv[3]));
.CE
+.PP
As another example, \fBincr\fR's command procedure
must check whether the variable's object is shared before
incrementing the integer in its internal representation.
If it is shared, it needs to duplicate the object
-in order to avoid accidently changing values in other data structures.
-
+in order to avoid accidentally changing values in other data structures.
.SH "SEE ALSO"
-Tcl_ConvertToType, Tcl_GetIntFromObj, Tcl_ListObjAppendElement, Tcl_ListObjIndex, Tcl_ListObjReplace, Tcl_RegisterObjType
-
+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
diff --git a/doc/ObjectType.3 b/doc/ObjectType.3
index cc84fd1..974ea6c 100644
--- a/doc/ObjectType.3
+++ b/doc/ObjectType.3
@@ -24,12 +24,12 @@ int
int
\fBTcl_ConvertToType\fR(\fIinterp, objPtr, typePtr\fR)
.SH ARGUMENTS
-.AS Tcl_ObjType *typeName in
+.AS "const char" *typeName
.AP Tcl_ObjType *typePtr in
Points to the structure containing information about the Tcl object type.
This storage must live forever,
typically by being statically allocated.
-.AP "CONST char" *typeName in
+.AP "const char" *typeName in
The name of a Tcl object type that \fBTcl_GetObjType\fR should look up.
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
@@ -43,12 +43,14 @@ must have been the result of a previous call to \fBTcl_NewObj\fR.
.SH DESCRIPTION
.PP
The procedures in this man page manage Tcl object types.
-The are used to register new object types,
-look up types,
+They are used to register new object 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 supported by Tcl.
+in the table of all object types that \fBTcl_GetObjType\fR
+can look up by name. There are other object 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.
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
@@ -59,11 +61,11 @@ it is replaced with the new type.
The Tcl_ObjType structure is described
in the section \fBTHE TCL_OBJTYPE STRUCTURE\fR below.
.PP
-\fBTcl_GetObjType\fR returns a pointer to the Tcl_ObjType
+\fBTcl_GetObjType\fR returns a pointer to the registered Tcl_ObjType
with name \fItypeName\fR.
It returns NULL if no type with that name is registered.
.PP
-\fBTcl_AppendAllObjTypes\fR appends the name of each object type
+\fBTcl_AppendAllObjTypes\fR appends the name of each registered object type
as a list element onto the Tcl object referenced by \fIobjPtr\fR.
The return value is \fBTCL_OK\fR unless there was an error
converting \fIobjPtr\fR to a list object;
@@ -73,7 +75,8 @@ in that case \fBTCL_ERROR\fR is returned.
if possible.
It creates a new internal representation for \fIobjPtr\fR
appropriate for the target type \fItypePtr\fR
-and sets its \fItypePtr\fR member to that type.
+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
@@ -81,118 +84,168 @@ unless \fIinterp\fR is NULL.
Otherwise, it returns \fBTCL_OK\fR.
Passing a NULL \fIinterp\fR allows this procedure to be used
as a test whether the conversion can be done (and in fact was done).
-
+.VS 8.5
+.PP
+In many cases, the \fItypePtr->setFromAnyProc\fR routine will
+set \fIobjPtr->typePtr\fR to the argument value \fItypePtr\fR,
+but that is no longer guaranteed. The \fIsetFromAnyProc\fR is
+free to set the internal representation for \fIobjPtr\fR to make
+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
-procedures,
-initializing a Tcl_ObjType structure to describe the type,
-and calling \fBTcl_RegisterObjType\fR.
+procedures and
+initializing a Tcl_ObjType structure to describe the type.
+Extension writers may also pass a pointer to their Tcl_ObjType
+structure to \fBTcl_RegisterObjType\fR if they wish to permit
+other extensions to look up their Tcl_ObjType by name with
+the \fBTcl_GetObjType\fR routine.
The \fBTcl_ObjType\fR structure is defined as follows:
+.PP
.CS
typedef struct Tcl_ObjType {
- char *\fIname\fR;
- Tcl_FreeInternalRepProc *\fIfreeIntRepProc\fR;
- Tcl_DupInternalRepProc *\fIdupIntRepProc\fR;
- Tcl_UpdateStringProc *\fIupdateStringProc\fR;
- Tcl_SetFromAnyProc *\fIsetFromAnyProc\fR;
+ char *\fIname\fR;
+ Tcl_FreeInternalRepProc *\fIfreeIntRepProc\fR;
+ Tcl_DupInternalRepProc *\fIdupIntRepProc\fR;
+ Tcl_UpdateStringProc *\fIupdateStringProc\fR;
+ Tcl_SetFromAnyProc *\fIsetFromAnyProc\fR;
} Tcl_ObjType;
.CE
+.SS "THE NAME FIELD"
.PP
The \fIname\fR member describes the name of the type, e.g. \fBint\fR.
-Extension writers can look up an object type using its name
-with the \fBTcl_GetObjType\fR procedure.
+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:
+.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.
+.PP
.CS
-typedef int (Tcl_SetFromAnyProc) (Tcl_Interp *\fIinterp\fR, Tcl_Obj *\fIobjPtr\fR);
+typedef int (Tcl_SetFromAnyProc) (Tcl_Interp *\fIinterp\fR,
+ Tcl_Obj *\fIobjPtr\fR);
.CE
-If an internal representation can't be created from the string,
+.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
unless \fIinterp\fR is NULL.
If \fIsetFromAnyProc\fR is successful,
it stores the new internal representation,
sets \fIobjPtr\fR's \fItypePtr\fR member to point to
-\fIsetFromAnyProc\fR's \fBTcl_ObjType\fR, and returns \fBTCL_OK\fR.
+the \fBTcl_ObjType\fR struct corresponding to the new
+internal representation, and returns \fBTCL_OK\fR.
Before setting the new internal representation,
the \fIsetFromAnyProc\fR must free any internal representation
of \fIobjPtr\fR's old type;
it does this by calling the old type's \fIfreeIntRepProc\fR
if it is not NULL.
-As an example, the \fIsetFromAnyProc\fR for the builtin Tcl integer type
+.PP
+As an example, the \fIsetFromAnyProc\fR for the built-in Tcl list type
gets an up-to-date string representation for \fIobjPtr\fR
by calling \fBTcl_GetStringFromObj\fR.
-It parses the string to obtain an integer and,
-if this succeeds,
-stores the integer in \fIobjPtr\fR's internal representation
-and sets \fIobjPtr\fR's \fItypePtr\fR member to point to the integer type's
+It parses the string to verify it is in a valid list format and
+to obtain each element value in the list, and, if this succeeds,
+stores the list elements in \fIobjPtr\fR's internal representation
+and sets \fIobjPtr\fR's \fItypePtr\fR member to point to the list type's
Tcl_ObjType structure.
+.PP
Do not release \fIobjPtr\fR's old internal representation unless you
replace it with a new one or reset the \fItypePtr\fR member to NULL.
.PP
+The \fIsetFromAnyProc\fR member may be set to NULL, if the routines
+making use of the internal representation have no need to derive that
+internal representation from an arbitrary string value. However, in
+this case, passing a pointer to the type to Tcl_ConvertToType() will
+lead to a panic, so to avoid this possibility, the type
+should \fInot\fR be registered.
+.SS "THE UPDATESTRINGPROC FIELD"
+.PP
The \fIupdateStringProc\fR member contains the address of a function
called to create a valid string representation
from an object's internal representation.
+.PP
.CS
typedef void (Tcl_UpdateStringProc) (Tcl_Obj *\fIobjPtr\fR);
.CE
+.PP
\fIobjPtr\fR's \fIbytes\fR member is always NULL when it is called.
It must always set \fIbytes\fR non-NULL before returning.
We require the string representation's byte array
-to have a null after the last byte, at offset \fIlength\fR;
-this allows string representations that do not contain null bytes
+to have a null after the last byte, at offset \fIlength\fR,
+and to have no null bytes before that; this allows string representations
to be treated as conventional null character-terminated C strings.
+These restrictions are easily met by using Tcl's internal UTF encoding
+for the string representation, same as one would do for other
+Tcl routines accepting string values as arguments.
Storage for the byte array must be allocated in the heap by \fBTcl_Alloc\fR
or \fBckalloc\fR. Note that \fIupdateStringProc\fRs must allocate
enough storage for the string's bytes and the terminating null byte.
-The \fIupdateStringProc\fR for Tcl's builtin list type, for example,
-builds an array of strings for each element object
-and then calls \fBTcl_Merge\fR
-to construct a string with proper Tcl list structure.
-It stores this string as the list object's string representation.
+.PP
+The \fIupdateStringProc\fR for Tcl's built-in double type, for example,
+calls Tcl_PrintDouble to write to a buffer of size TCL_DOUBLE_SPACE,
+then allocates and copies the string representation to just enough
+space to hold it. A pointer to the allocated space is stored in
+the \fIbytes\fR member.
+.PP
+The \fIupdateStringProc\fR member may be set to NULL, if the routines
+making use of the internal representation are written so that the
+string representation is never invalidated. Failure to meet this
+obligation will lead to panics or crashes when \fBTcl_GetStringFromObj\fR
+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.
+.PP
.CS
-typedef void (Tcl_DupInternalRepProc) (Tcl_Obj *\fIsrcPtr\fR, Tcl_Obj *\fIdupPtr\fR);
+typedef void (Tcl_DupInternalRepProc) (Tcl_Obj *\fIsrcPtr\fR,
+ Tcl_Obj *\fIdupPtr\fR);
.CE
+.PP
\fIdupPtr\fR's internal representation is made a copy of \fIsrcPtr\fR's
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
copying its internal representation means.
+.PP
For example, the \fIdupIntRepProc\fR for the Tcl integer type
simply copies an integer.
-The builtin list type's \fIdupIntRepProc\fR
-allocates a new array that points at the original element objects;
-the elements are shared between the two lists
-(and their reference counts are incremented to reflect the new references).
+The built-in list type's \fIdupIntRepProc\fR uses a far more
+sophisticated scheme to continue sharing storage as much as it
+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.
+.PP
.CS
typedef void (Tcl_FreeInternalRepProc) (Tcl_Obj *\fIobjPtr\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 example, Tcl list objects have an \fIinternalRep.otherValuePtr\fR
-that points to an array of pointers to each element in the list.
-The list type's \fIfreeIntRepProc\fR decrements
-the reference count for each element object
-(since the list will no longer refer to those objects),
-then deallocates the storage for the array of pointers.
+.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
+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
+the \fIfreeIntRepProc\fR have no need to consult the \fIbytes\fR
+member.
.SH "SEE ALSO"
Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount
-
.SH KEYWORDS
internal representation, object, object type, string representation, type conversion
diff --git a/doc/OpenFileChnl.3 b/doc/OpenFileChnl.3
index 80596d7..0d722f6 100644
--- a/doc/OpenFileChnl.3
+++ b/doc/OpenFileChnl.3
@@ -9,7 +9,7 @@
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
-Tcl_OpenFileChannel, Tcl_OpenCommandChannel, Tcl_MakeFileChannel, Tcl_GetChannel, Tcl_GetChannelNames, Tcl_GetChannelNamesEx, Tcl_RegisterChannel, Tcl_UnregisterChannel, Tcl_DetachChannel, Tcl_IsStandardChannel, Tcl_Close, Tcl_ReadChars, Tcl_Read, Tcl_GetsObj, Tcl_Gets, Tcl_WriteObj, Tcl_WriteChars, Tcl_Write, Tcl_Flush, Tcl_Seek, Tcl_Tell, Tcl_GetChannelOption, Tcl_SetChannelOption, Tcl_Eof, Tcl_InputBlocked, Tcl_InputBuffered, Tcl_OutputBuffered, Tcl_Ungets, Tcl_ReadRaw, Tcl_WriteRaw \- buffered I/O facilities using channels
+Tcl_OpenFileChannel, Tcl_OpenCommandChannel, Tcl_MakeFileChannel, Tcl_GetChannel, Tcl_GetChannelNames, Tcl_GetChannelNamesEx, Tcl_RegisterChannel, Tcl_UnregisterChannel, Tcl_DetachChannel, Tcl_IsStandardChannel, Tcl_Close, Tcl_ReadChars, Tcl_Read, Tcl_GetsObj, Tcl_Gets, Tcl_WriteObj, Tcl_WriteChars, Tcl_Write, Tcl_Flush, Tcl_Seek, Tcl_Tell, Tcl_TruncateChannel, Tcl_GetChannelOption, Tcl_SetChannelOption, Tcl_Eof, Tcl_InputBlocked, Tcl_InputBuffered, Tcl_OutputBuffered, Tcl_Ungets, Tcl_ReadRaw, Tcl_WriteRaw \- buffered I/O facilities using channels
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -25,14 +25,12 @@ Tcl_Channel
.sp
Tcl_Channel
\fBTcl_GetChannel\fR(\fIinterp, channelName, modePtr\fR)
-.VS 8.3
.sp
int
\fBTcl_GetChannelNames\fR(\fIinterp\fR)
.sp
int
\fBTcl_GetChannelNamesEx\fR(\fIinterp, pattern\fR)
-.VE
.sp
void
\fBTcl_RegisterChannel\fR(\fIinterp, channel\fR)
@@ -49,7 +47,6 @@ int
int
\fBTcl_Close\fR(\fIinterp, channel\fR)
.sp
-.VS 8.1
int
\fBTcl_ReadChars\fR(\fIchannel, readObjPtr, charsToRead, appendFlag\fR)
.sp
@@ -73,15 +70,12 @@ int
.sp
int
\fBTcl_Write\fR(\fIchannel, byteBuf, bytesToWrite\fR)
-.VE
-.VS 8.3.2
.sp
int
\fBTcl_ReadRaw\fR(\fIchannel, readBuf, bytesToRead\fR)
.sp
int
\fBTcl_WriteRaw\fR(\fIchannel, byteBuf, bytesToWrite\fR)
-.VE
.sp
int
\fBTcl_Eof\fR(\fIchannel\fR)
@@ -94,19 +88,20 @@ int
.sp
int
\fBTcl_InputBuffered\fR(\fIchannel\fR)
-.VS 8.4
.sp
int
\fBTcl_OutputBuffered\fR(\fIchannel\fR)
-.VE
.sp
-.VS 8.4
Tcl_WideInt
\fBTcl_Seek\fR(\fIchannel, offset, seekMode\fR)
.sp
Tcl_WideInt
\fBTcl_Tell\fR(\fIchannel\fR)
-.VE 8.4
+.sp
+.VS 8.5
+int
+\fBTcl_TruncateChannel\fR(\fIchannel, length\fR)
+.VE 8.5
.sp
int
\fBTcl_GetChannelOption\fR(\fIinterp, channel, optionName, optionValue\fR)
@@ -115,12 +110,12 @@ int
\fBTcl_SetChannelOption\fR(\fIinterp, channel, optionName, newValue\fR)
.sp
.SH ARGUMENTS
-.AS Tcl_ChannelType newClientProcPtr in
+.AS Tcl_DString *channelName in/out
.AP Tcl_Interp *interp in
Used for error reporting and to look up a channel registered in it.
-.AP "CONST char" *fileName in
+.AP "const char" *fileName in
The name of a local or network file.
-.AP "CONST char" *mode in
+.AP "const char" *mode in
Specifies how the file is to be accessed. May have any of the values
allowed for the \fImode\fR argument to the Tcl \fBopen\fR command.
.AP int permissions in
@@ -128,7 +123,7 @@ POSIX-style permission flags such as 0644. If a new file is created, these
permissions will be set on the created file.
.AP int argc in
The number of elements in \fIargv\fR.
-.AP "CONST char" **argv in
+.AP "const char" **argv in
Arguments for constructing a command pipeline. These values have the same
meaning as the non-switch arguments to the Tcl \fBexec\fR command.
.AP int flags in
@@ -147,20 +142,17 @@ file descriptor, for Windows it is a HANDLE.
.AP int readOrWrite in
OR-ed combination of \fBTCL_READABLE\fR and \fBTCL_WRITABLE\fR to indicate
what operations are valid on \fIhandle\fR.
-.AP "CONST char" *channelName in
+.AP "const char" *channelName in
The name of the channel.
.AP int *modePtr out
Points at an integer variable that will receive an OR-ed combination of
\fBTCL_READABLE\fR and \fBTCL_WRITABLE\fR denoting whether the channel is
open for reading and writing.
-.VS 8.3
-.AP "CONST char" *pattern in
+.AP "const char" *pattern in
The pattern to match on, passed to Tcl_StringMatch, or NULL.
-.VE
.AP Tcl_Channel channel in
A Tcl channel for input or output. Must have been the return value
from a procedure such as \fBTcl_OpenFileChannel\fR.
-.VS 8.1 br
.AP Tcl_Obj *readObjPtr in/out
A pointer to a Tcl Object in which to store the characters read from the
channel.
@@ -184,25 +176,22 @@ object.
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
appended to any data already in the dynamic string.
-.VS 8.3
-.AP "CONST char" *input in
+.AP "const char" *input in
The input to add to a channel buffer.
.AP int inputLen in
Length of the input
.AP int addAtEnd in
Flag indicating whether the input should be added to the end or
beginning of the channel buffer.
-.VE
.AP Tcl_Obj *writeObjPtr in
A pointer to a Tcl Object whose contents will be output to the channel.
-.AP "CONST char" *charBuf in
+.AP "const char" *charBuf in
A buffer containing the characters to output to the channel.
-.AP "CONST char" *byteBuf in
+.AP "const char" *byteBuf in
A buffer containing the bytes to output to the channel.
.AP int bytesToWrite in
The number of bytes to consume from \fIcharBuf\fR or \fIbyteBuf\fR and
output to the channel.
-.VE
.AP Tcl_WideInt offset in
How far to move the access point in the channel at which the next input or
output operation will be applied, measured in bytes from the position
@@ -211,13 +200,15 @@ given by \fIseekMode\fR. May be either positive or negative.
Relative to which point to seek; used with \fIoffset\fR to calculate the new
access point for the channel. Legal values are \fBSEEK_SET\fR,
\fBSEEK_CUR\fR, and \fBSEEK_END\fR.
-.AP "CONST char" *optionName in
+.AP Tcl_WideInt length in
+The (non-negative) length to truncate the channel the channel to.
+.AP "const char" *optionName in
The name of an option applicable to this channel, such as \fB\-blocking\fR.
May have any of the values accepted by the \fBfconfigure\fR command.
.AP Tcl_DString *optionValue in
Where to store the value of an option or a list of all options and their
values. Must have been initialized by the caller.
-.AP "CONST char" *newValue in
+.AP "const char" *newValue in
New value for the option given by \fIoptionName\fR.
.BE
@@ -228,7 +219,7 @@ platform-independent mechanism for performing buffered input
and output operations on a variety of file, socket, and device
types.
The channel mechanism is extensible to new channel types, by
-providing a low level channel driver for the new type; the channel driver
+providing a low-level channel driver for the new type; the channel driver
interface is described in the manual entry for \fBTcl_CreateChannel\fR. The
channel mechanism provides a buffering scheme modeled after
Unix's standard I/O, and it also allows for nonblocking I/O on
@@ -255,8 +246,6 @@ 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
be used in preference to \fBTcl_OpenFileChannel\fR wherever possible.
.PP
-
-.PP
The newly created channel is not registered in the supplied interpreter; to
register it, use \fBTcl_RegisterChannel\fR, described below.
If one of the standard channels, \fBstdin, stdout\fR or \fBstderr\fR was
@@ -349,7 +338,7 @@ reference to a channel that is also registered in a Tcl interpreter.
.PP
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 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
them.
@@ -376,7 +365,7 @@ accessible in \fIinterp\fR. After this call, Tcl programs will no longer be
able to use the channel's name to refer to the channel in that interpreter.
Beyond that, this command has no further effect. It cannot be used on
the standard channels (stdout, stderr, stdin), and will return
-TCL_ERROR if passed one of those channels.
+\fBTCL_ERROR\fR if passed one of those channels.
.PP
Code not associated with a Tcl interpreter can call
\fBTcl_DetachChannel\fR with \fIinterp\fR as NULL, to indicate to Tcl
@@ -423,7 +412,6 @@ been given as the \fBchan\fR argument in a call to
when all calls to \fBTcl_RegisterChannel\fR have been matched by
corresponding calls to \fBTcl_UnregisterChannel\fR.
-.VS 8.1 br
.SH "TCL_READCHARS AND TCL_READ"
.PP
\fBTcl_ReadChars\fR consumes bytes from \fIchannel\fR, converting the bytes
@@ -434,7 +422,7 @@ that were stored in \fIreadObjPtr\fR. If an error occurs while reading, the
return value is \-1 and \fBTcl_ReadChars\fR records a POSIX error code that
can be retrieved with \fBTcl_GetErrno\fR.
.PP
-Setting \fIcharsToRead\fR to \fB-1\fR will cause the command to read
+Setting \fIcharsToRead\fR to \fB\-1\fR will cause the command to read
all characters currently available (non-blocking) or everything until
eof (blocking mode).
.PP
@@ -467,7 +455,7 @@ 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.
.PP
-\fBTcl_Read\fR is similar to \fBTcl_ReadChars\fR, except that it doesn't do
+\fBTcl_Read\fR is similar to \fBTcl_ReadChars\fR, except that it does not do
encoding conversions, regardless of the channel's encoding. It is deprecated
and exists for backwards compatibility with non-internationalized Tcl
extensions. It consumes bytes from \fIchannel\fR and stores them in
@@ -519,9 +507,11 @@ at either the head or tail of the queue. The pointer \fIinput\fR points
to the data that is to be added. The length of the input to add is given
by \fIinputLen\fR. A non-zero value of \fIaddAtEnd\fR indicates that the
data is to be added at the end of queue; otherwise it will be added at the
-head of the queue. If \fIchannel\fR has a "sticky" EOF set, no data will be
+head of the queue. If \fIchannel\fR has a
+.QW sticky
+EOF set, no data will be
added to the input queue. \fBTcl_Ungets\fR returns \fIinputLen\fR or
--1 if an error occurs.
+\-1 if an error occurs.
.SH "TCL_WRITECHARS, TCL_WRITEOBJ, AND TCL_WRITE"
.PP
@@ -561,7 +551,7 @@ 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.
.PP
-\fBTcl_Write\fR is similar to \fBTcl_WriteChars\fR except that it doesn't do
+\fBTcl_Write\fR is similar to \fBTcl_WriteChars\fR except that it does not do
encoding conversions, regardless of the channel's encoding. It is
deprecated and exists for backwards compatibility with non-internationalized
Tcl extensions. It accepts \fIbytesToWrite\fR bytes of data at
@@ -577,7 +567,6 @@ not. Thus this function is \fBonly\fR usable for transformational
channel drivers, i.e. drivers used in the middle of a stack of
channels, to move data from the transformation into the channel below
it.
-.VE
.SH TCL_FLUSH
.PP
@@ -609,6 +598,14 @@ After an error, the access point may or may not have been moved.
\fBTcl_Tell\fR returns the current access point for a channel. The returned
value is \-1 if the channel does not support seeking.
+.SH TCL_TRUNCATECHANNEL
+.PP
+.VS 8.5
+\fBTcl_TruncateChannel\fR truncates the file underlying \fIchannel\fR
+to a given \fIlength\fR of bytes. It returns \fBTCL_OK\fR if the
+operation succeeded, and \fBTCL_ERROR\fR otherwise.
+.VE 8.5
+
.SH TCL_GETCHANNELOPTION
.PP
\fBTcl_GetChannelOption\fR retrieves, in \fIoptionValue\fR, the value of one of
@@ -658,11 +655,9 @@ buffered in the internal buffers for a channel. If the channel is not open
for reading, this function always returns zero.
.SH TCL_OUTPUTBUFFERED
-.VS 8.4
\fBTcl_OutputBuffered\fR returns the number of bytes of output
currently buffered in the internal buffers for a channel. If the
channel is not open for writing, this function always returns zero.
-.VE
.SH "PLATFORM ISSUES"
.PP
@@ -673,8 +668,7 @@ call. On Windows platforms, the handle is a file \fBHANDLE\fR when
the channel was created with \fBTcl_OpenFileChannel\fR,
\fBTcl_OpenCommandChannel\fR, or \fBTcl_MakeFileChannel\fR. Other
channel types may return a different type of handle on Windows
-platforms. On the Macintosh platform, the handle is a file reference
-number as returned from \fBHOpenDF\fR.
+platforms.
.SH "SEE ALSO"
DString(3), fconfigure(n), filename(n), fopen(3), Tcl_CreateChannel(3)
diff --git a/doc/OpenTcp.3 b/doc/OpenTcp.3
index 4ddb8a7..98d8cb0 100644
--- a/doc/OpenTcp.3
+++ b/doc/OpenTcp.3
@@ -24,18 +24,18 @@ Tcl_Channel
\fBTcl_OpenTcpServer\fR(\fIinterp, port, myaddr, proc, clientData\fR)
.sp
.SH ARGUMENTS
-.AS Tcl_ChannelType newClientProcPtr in
+.AS Tcl_TcpAcceptProc clientData
.AP Tcl_Interp *interp in
Tcl interpreter to use for error reporting. If non-NULL and an
error occurs, an error message is left in the interpreter's result.
.AP int port in
A port number to connect to as a client or to listen on as a server.
-.AP "CONST char" *host in
+.AP "const char" *host in
A string specifying a host name or address for the remote end of the connection.
.AP int myport in
A port number for the client's end of the socket. If 0, a port number
is allocated at random.
-.AP "CONST char" *myaddr in
+.AP "const char" *myaddr in
A string specifying the host name or address for network interface to use
for the local end of the connection. If NULL, a default interface is
chosen.
@@ -113,24 +113,24 @@ replacement for the standard channel.
.PP
\fBTcl_OpenTcpServer\fR opens a TCP socket on the local host on a specified
\fIport\fR and uses the Tcl event mechanism to accept requests from clients
-to connect to it. The \fImyaddr\fP argument specifies the network interface.
-If \fImyaddr\fP is NULL the special address INADDR_ANY should be used to
+to connect to it. The \fImyaddr\fR argument specifies the network interface.
+If \fImyaddr\fR is NULL the special address INADDR_ANY should be used to
allow connections from any network interface.
Each time a client connects to this socket, Tcl creates a channel
for the new connection and invokes \fIproc\fR with information about
-the channel. \fIProc\fR must match the following prototype:
+the channel. \fIProc\fR must match the following prototype:
.CS
typedef void Tcl_TcpAcceptProc(
- ClientData \fIclientData\fR,
- Tcl_Channel \fIchannel\fR,
- char *\fIhostName\fR,
- int \fIport\fP);
+ ClientData \fIclientData\fR,
+ Tcl_Channel \fIchannel\fR,
+ char *\fIhostName\fR,
+ int \fIport\fR);
.CE
.PP
The \fIclientData\fR argument will be the same as the \fIclientData\fR
argument to \fBTcl_OpenTcpServer\fR, \fIchannel\fR will be the handle
for the new channel, \fIhostName\fR points to a string containing
-the name of the client host making the connection, and \fIport\fP
+the name of the client host making the connection, and \fIport\fR
will contain the client's port number.
The new channel
is opened for both input and output.
@@ -162,14 +162,11 @@ If one of the standard channels, \fBstdin, stdout\fR or \fBstderr\fR was
previously closed, the act of creating the new channel also assigns it as a
replacement for the standard channel.
-.VS
.SH "PLATFORM ISSUES"
.PP
On Unix platforms, the socket handle is a Unix file descriptor as
returned by the \fBsocket\fR system call. On the Windows platform, the
-socket handle is a \fBSOCKET\fR as defined in the WinSock API. On the
-Macintosh platform, the socket handle is a \fBStreamPtr\fR.
-.VE
+socket handle is a \fBSOCKET\fR as defined in the WinSock API.
.SH "SEE ALSO"
Tcl_OpenFileChannel(3), Tcl_RegisterChannel(3), vwait(n)
diff --git a/doc/Panic.3 b/doc/Panic.3
index 3fb0c83..b53ca11 100644
--- a/doc/Panic.3
+++ b/doc/Panic.3
@@ -7,7 +7,7 @@
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
-Tcl_Panic, Tcl_PanicVA, Tcl_SetPanicProc, panic, panicVA \- report fatal error and abort
+Tcl_Panic, Tcl_PanicVA, Tcl_SetPanicProc \- report fatal error and abort
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -21,21 +21,15 @@ void
void
\fBTcl_SetPanicProc\fR(\fIpanicProc\fR)
.sp
-void
-\fBpanic\fR(\fIformat\fR, \fIarg\fR, \fIarg\fR, \fI...\fR)
-.sp
-void
-\fBpanicVA\fR(\fIformat\fR, \fIargList\fR)
-.sp
.SH ARGUMENTS
.AS Tcl_PanicProc *panicProc
-.AP "CONST char*" format in
+.AP "const char*" format in
A printf-style format string.
.AP "" arg in
Arguments matching the format string.
.AP va_list argList in
An argument list of arguments matching the format string.
-Must have been initialized using \fBTCL_VARARGS_START\fR,
+Must have been initialized using \fBva_start\fR,
and cleared using \fBva_end\fR.
.AP Tcl_PanicProc *panicProc in
Procedure to report fatal error message and abort.
@@ -51,7 +45,7 @@ to display a message describing the error and abort the process. The
\fIformat\fR argument is a format string describing how to format the
remaining arguments \fIarg\fR into an error message, according to the
same formatting rules used by the \fBprintf\fR family of functions. The
-same formatting rules are also used by the builtin Tcl command
+same formatting rules are also used by the built-in Tcl command
\fBformat\fR.
.PP
In a freshly loaded Tcl library, \fBTcl_Panic\fR prints the formatted
@@ -65,8 +59,8 @@ type \fBTcl_PanicProc\fR:
.PP
.CS
typedef void Tcl_PanicProc(
- CONST char *\fBformat\fR,
- \fBarg\fR, \fBarg\fR,...);
+ const char *\fBformat\fR,
+ \fBarg\fR, \fBarg\fR,...);
.CE
.PP
After \fBTcl_SetPanicProc\fR returns, any future calls to
@@ -92,11 +86,7 @@ have a panic message displayed the same way that panic messages from Tcl
will be displayed.
.PP
\fBTcl_PanicVA\fR is the same as \fBTcl_Panic\fR except that instead of
-taking a variable number of arguments it takes an argument list. The
-procedures \fBpanic\fR and \fBpanicVA\fR are synonyms (implemented as
-macros) for \fBTcl_Panic\fR and \fBTcl_PanicVA\fR, respectively. They
-exist to support old code; new code should use direct calls to
-\fBTcl_Panic\fR or \fBTcl_PanicVA\fR.
+taking a variable number of arguments it takes an argument list.
.SH "SEE ALSO"
abort(3), printf(3), exec(n), format(n)
diff --git a/doc/ParseCmd.3 b/doc/ParseCmd.3
index af6b02e..b5fc6d0 100644
--- a/doc/ParseCmd.3
+++ b/doc/ParseCmd.3
@@ -14,22 +14,22 @@ Tcl_ParseCommand, Tcl_ParseExpr, Tcl_ParseBraces, Tcl_ParseQuotedString, Tcl_Par
\fB#include <tcl.h>\fR
.sp
int
-\fBTcl_ParseCommand\fR(\fIinterp, string, numBytes, nested, parsePtr\fR)
+\fBTcl_ParseCommand\fR(\fIinterp, start, numBytes, nested, parsePtr\fR)
.sp
int
-\fBTcl_ParseExpr\fR(\fIinterp, string, numBytes, parsePtr\fR)
+\fBTcl_ParseExpr\fR(\fIinterp, start, numBytes, parsePtr\fR)
.sp
int
-\fBTcl_ParseBraces\fR(\fIinterp, string, numBytes, parsePtr, append, termPtr\fR)
+\fBTcl_ParseBraces\fR(\fIinterp, start, numBytes, parsePtr, append, termPtr\fR)
.sp
int
-\fBTcl_ParseQuotedString\fR(\fIinterp, string, numBytes, parsePtr, append, termPtr\fR)
+\fBTcl_ParseQuotedString\fR(\fIinterp, start, numBytes, parsePtr, append, termPtr\fR)
.sp
int
-\fBTcl_ParseVarName\fR(\fIinterp, string, numBytes, parsePtr, append\fR)
+\fBTcl_ParseVarName\fR(\fIinterp, start, numBytes, parsePtr, append\fR)
.sp
-CONST char *
-\fBTcl_ParseVar\fR(\fIinterp, string, termPtr\fR)
+const char *
+\fBTcl_ParseVar\fR(\fIinterp, start, termPtr\fR)
.sp
\fBTcl_FreeParse\fR(\fIusedParsePtr\fR)
.sp
@@ -39,7 +39,7 @@ Tcl_Obj *
int
\fBTcl_EvalTokensStandard\fR(\fIinterp, tokenPtr, numTokens\fR)
.SH ARGUMENTS
-.AS Tcl_Interp *usedParsePtr
+.AS Tcl_Interp *usedParsePtr out
.AP Tcl_Interp *interp out
For procedures other than \fBTcl_FreeParse\fR, \fBTcl_EvalTokens\fR
and \fBTcl_EvalTokensStandard\fR, used only for error reporting;
@@ -47,12 +47,12 @@ if NULL, then no error messages are left after errors.
For \fBTcl_EvalTokens\fR and \fBTcl_EvalTokensStandard\fR,
determines the context for evaluating the
script and also is used for error reporting; must not be NULL.
-.AP "CONST char" *string in
+.AP "const char" *start in
Pointer to first character in string to parse.
.AP int numBytes in
-Number of bytes in \fIstring\fR, not including any terminating null
+Number of bytes in string to parse, not including any terminating null
character. If less than 0 then the script consists of all characters
-in \fIstring\fR up to the first null character.
+following \fIstart\fR up to the first null character.
.AP int nested in
Non-zero means that the script is part of a command substitution so an
unquoted close bracket should be treated as a command terminator. If zero,
@@ -69,7 +69,7 @@ Any previous information in this structure
is ignored, unless \fIappend\fR is non-zero in a call to
\fBTcl_ParseBraces\fR, \fBTcl_ParseQuotedString\fR,
or \fBTcl_ParseVarName\fR.
-.AP "CONST char" **termPtr out
+.AP "const char" **termPtr out
If not NULL, points to a location where
\fBTcl_ParseBraces\fR, \fBTcl_ParseQuotedString\fR, and
\fBTcl_ParseVar\fR will store a pointer to the character
@@ -90,7 +90,7 @@ and fills in the structure pointed to by \fIparsePtr\fR
with a collection of tokens describing the information that was parsed.
The procedures normally return \fBTCL_OK\fR.
However, if an error occurs then they return \fBTCL_ERROR\fR,
-leave an error message in \fIinterp's\fR result
+leave an error message in \fIinterp\fR's result
(if \fIinterp\fR is not NULL),
and leave nothing in \fIparsePtr\fR.
.PP
@@ -117,9 +117,9 @@ result, and no information is left at \fI*parsePtr\fR.
.PP
\fBTcl_ParseBraces\fR parses a string or command argument
enclosed in braces such as
-\fB{hello}\fR or \fB{string \\t with \\t tabs}\fR
-from the beginning of its argument \fIstring\fR.
-The first character of \fIstring\fR must be \fB{\fR.
+\fB{hello}\fR or \fB{string \et with \et tabs}\fR
+from the beginning of its argument \fIstart\fR.
+The first character of \fIstart\fR must be \fB{\fR.
If the braced string was parsed successfully,
\fBTcl_ParseBraces\fR returns \fBTCL_OK\fR,
fills in the structure pointed to by \fIparsePtr\fR
@@ -133,15 +133,15 @@ an error message is left in \fIinterp\fR's result,
and no information is left at \fI*parsePtr\fR or \fI*termPtr\fR.
.PP
\fBTcl_ParseQuotedString\fR parses a double-quoted string such as
-\fB"sum is [expr $a+$b]"\fR
-from the beginning of the argument \fIstring\fR.
-The first character of \fIstring\fR must be \fB"\fR.
+\fB"sum is [expr {$a+$b}]"\fR
+from the beginning of the argument \fIstart\fR.
+The first character of \fIstart\fR must be \fB\N'34'\fR.
If the double-quoted string was parsed successfully,
\fBTcl_ParseQuotedString\fR returns \fBTCL_OK\fR,
fills in the structure pointed to by \fIparsePtr\fR
with information about the structure of the string
(see below for details),
-and stores a pointer to the character just after the terminating \fB"\fR
+and stores a pointer to the character just after the terminating \fB\N'34'\fR
in the location given by \fI*termPtr\fR.
If an error occurs while parsing the string
then \fBTCL_ERROR\fR is returned,
@@ -149,20 +149,20 @@ an error message is left in \fIinterp\fR's result,
and no information is left at \fI*parsePtr\fR or \fI*termPtr\fR.
.PP
\fBTcl_ParseVarName\fR parses a Tcl variable reference such as
-\fB$abc\fR or \fB$x([expr $index + 1])\fR from the beginning of its
-\fIstring\fR argument.
-The first character of \fIstring\fR must be \fB$\fR.
+\fB$abc\fR or \fB$x([expr {$index + 1}])\fR from the beginning of its
+\fIstart\fR argument.
+The first character of \fIstart\fR must be \fB$\fR.
If a variable name was parsed successfully, \fBTcl_ParseVarName\fR
returns \fBTCL_OK\fR and fills in the structure pointed to by
\fIparsePtr\fR with information about the structure of the variable name
(see below for details). If an error
occurs while parsing the command then \fBTCL_ERROR\fR is returned, an
-error message is left in \fIinterp\fR's result (if \fIinterp\fR isn't
+error message is left in \fIinterp\fR's result (if \fIinterp\fR is not
NULL), and no information is left at \fI*parsePtr\fR.
.PP
\fBTcl_ParseVar\fR parse a Tcl variable reference such as \fB$abc\fR
-or \fB$x([expr $index + 1])\fR from the beginning of its \fIstring\fR
-argument. The first character of \fIstring\fR must be \fB$\fR. If
+or \fB$x([expr {$index + 1}])\fR from the beginning of its \fIstart\fR
+argument. The first character of \fIstart\fR must be \fB$\fR. If
the variable name is parsed successfully, \fBTcl_ParseVar\fR returns a
pointer to the string value of the variable. If an error occurs while
parsing, then NULL is returned and an error message is left in
@@ -210,21 +210,21 @@ of \fBTcl_EvalTokens\fR is deprecated.
return parse information in two data structures, Tcl_Parse and Tcl_Token:
.CS
typedef struct Tcl_Parse {
- CONST char *\fIcommentStart\fR;
- int \fIcommentSize\fR;
- CONST char *\fIcommandStart\fR;
- int \fIcommandSize\fR;
- int \fInumWords\fR;
- Tcl_Token *\fItokenPtr\fR;
- int \fInumTokens\fR;
- ...
+ const char *\fIcommentStart\fR;
+ int \fIcommentSize\fR;
+ const char *\fIcommandStart\fR;
+ int \fIcommandSize\fR;
+ int \fInumWords\fR;
+ Tcl_Token *\fItokenPtr\fR;
+ int \fInumTokens\fR;
+ ...
} Tcl_Parse;
typedef struct Tcl_Token {
- int \fItype\fR;
- CONST char *\fIstart\fR;
- int \fIsize\fR;
- int \fInumComponents\fR;
+ int \fItype\fR;
+ const char *\fIstart\fR;
+ int \fIsize\fR;
+ int \fInumComponents\fR;
} Tcl_Token;
.CE
.PP
@@ -285,6 +285,16 @@ This token has the same meaning as \fBTCL_TOKEN_WORD\fR, except that
the word is guaranteed to consist of a single \fBTCL_TOKEN_TEXT\fR
sub-token. The \fInumComponents\fR field is always 1.
.TP
+\fBTCL_TOKEN_EXPAND_WORD\fR
+.VS 8.5
+This token has the same meaning as \fBTCL_TOKEN_WORD\fR, except that
+the command parser notes this word began with the expansion
+prefix \fB{*}\fR, indicating that after substitution,
+the list value of this word should be expanded to form multiple
+arguments in command evaluation. This
+token type can only be created by Tcl_ParseCommand.
+.VE 8.5
+.TP
\fBTCL_TOKEN_TEXT\fR
The token describes a range of literal text that is part of a word.
The \fInumComponents\fR field is always 0.
@@ -294,7 +304,7 @@ The token describes a backslash sequence such as \fB\en\fR or \fB\e0xa3\fR.
The \fInumComponents\fR field is always 0.
.TP
\fBTCL_TOKEN_COMMAND\fR
-The token describes a command whose result result must be substituted into
+The token describes a command whose result must be substituted into
the word. The token includes the square brackets that surround the
command. The \fInumComponents\fR field is always 0 (the nested command
is not parsed; call \fBTcl_ParseCommand\fR recursively if you want to
@@ -344,7 +354,7 @@ this includes the sub-tokens for any nested \fBTCL_TOKEN_SUB_EXPR\fR tokens.
\fBTCL_TOKEN_OPERATOR\fR
The token describes one operator of an expression
such as \fB&&\fR or \fBhypot\fR.
-An \fBTCL_TOKEN_OPERATOR\fR token is always preceded by a
+A \fBTCL_TOKEN_OPERATOR\fR token is always preceded by a
\fBTCL_TOKEN_SUB_EXPR\fR token
that describes the operator and its operands;
the \fBTCL_TOKEN_SUB_EXPR\fR token's \fInumComponents\fR field
@@ -352,7 +362,7 @@ can be used to determine the number of operands.
A binary operator such as \fB*\fR
is followed by two \fBTCL_TOKEN_SUB_EXPR\fR tokens
that describe its operands.
-A unary operator like \fB-\fR
+A unary operator like \fB\-\fR
is followed by a single \fBTCL_TOKEN_SUB_EXPR\fR token
for its operand.
If the operator is a math function such as \fBlog10\fR,
@@ -373,12 +383,16 @@ is always 0.
After \fBTcl_ParseCommand\fR returns, the first token pointed to by
the \fItokenPtr\fR field of the
Tcl_Parse structure always has type \fBTCL_TOKEN_WORD\fR or
-\fBTCL_TOKEN_SIMPLE_WORD\fR. It is followed by the sub-tokens
+.VS 8.5
+\fBTCL_TOKEN_SIMPLE_WORD\fR or \fBTCL_TOKEN_EXPAND_WORD\fR.
+It is followed by the sub-tokens
that must be concatenated to produce the value of that word.
The next token is the \fBTCL_TOKEN_WORD\fR or \fBTCL_TOKEN_SIMPLE_WORD\fR
-token for the second word, followed by sub-tokens for that
+of \fBTCL_TOKEN_EXPAND_WORD\fR token for the second word,
+followed by sub-tokens for that
word, and so on until all \fInumWords\fR have been accounted
for.
+.VE 8.5
.PP
After \fBTcl_ParseExpr\fR returns, the first token pointed to by
the \fItokenPtr\fR field of the
@@ -415,7 +429,7 @@ Tcl_Parse structure depends on the contents of the quoted string.
It will consist of one or more \fBTCL_TOKEN_TEXT\fR, \fBTCL_TOKEN_BS\fR,
\fBTCL_TOKEN_COMMAND\fR, and \fBTCL_TOKEN_VARIABLE\fR sub-tokens.
The array always contains at least one token;
-for example, if the argument \fIstring\fR is empty,
+for example, if the argument \fIstart\fR is empty,
the array returned consists of a single \fBTCL_TOKEN_TEXT\fR token
with a zero \fIsize\fR field.
Only the token information in the Tcl_Parse structure
@@ -436,7 +450,7 @@ the \fIcommentStart\fR, \fIcommentSize\fR,
.PP
All of the character pointers in the
Tcl_Parse and Tcl_Token structures refer
-to characters in the \fIstring\fR argument passed to
+to characters in the \fIstart\fR argument passed to
\fBTcl_ParseCommand\fR, \fBTcl_ParseExpr\fR, \fBTcl_ParseBraces\fR,
\fBTcl_ParseQuotedString\fR, and \fBTcl_ParseVarName\fR.
.PP
diff --git a/doc/PkgRequire.3 b/doc/PkgRequire.3
index fcccd58..810947d 100644
--- a/doc/PkgRequire.3
+++ b/doc/PkgRequire.3
@@ -8,21 +8,24 @@
.TH Tcl_PkgRequire 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
-Tcl_PkgRequire, Tcl_PkgRequireEx, Tcl_PkgPresent, Tcl_PkgPresentEx, Tcl_PkgProvide, Tcl_PkgProvideEx \- package version control
+Tcl_PkgRequire, Tcl_PkgRequireEx, Tcl_PkgRequireProc, Tcl_PkgPresent, Tcl_PkgPresentEx, Tcl_PkgProvide, Tcl_PkgProvideEx \- package version control
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
-CONST char *
+const char *
\fBTcl_PkgRequire\fR(\fIinterp, name, version, exact\fR)
.sp
-CONST char *
+const char *
\fBTcl_PkgRequireEx\fR(\fIinterp, name, version, exact, clientDataPtr\fR)
.sp
-CONST char *
+int
+\fBTcl_PkgRequireProc\fR(\fIinterp, name, objc, objv, clientDataPtr\fR)
+.sp
+const char *
\fBTcl_PkgPresent\fR(\fIinterp, name, version, exact\fR)
.sp
-CONST char *
+const char *
\fBTcl_PkgPresentEx\fR(\fIinterp, name, version, exact, clientDataPtr\fR)
.sp
int
@@ -31,12 +34,12 @@ int
int
\fBTcl_PkgProvideEx\fR(\fIinterp, name, version, clientData\fR)
.SH ARGUMENTS
-.AS ClientData clientDataPtr
+.AS ClientData clientDataPtr out
.AP Tcl_Interp *interp in
Interpreter where package is needed or available.
-.AP "CONST char" *name in
+.AP "const char" *name in
Name of package.
-.AP "CONST char" *version in
+.AP "const char" *version in
A version string consisting of one or more decimal numbers
separated by dots.
.AP int exact in
@@ -51,7 +54,12 @@ Arbitrary value to be associated with the package.
Pointer to place to store the value associated with the matching
package. It is only changed if the pointer is not NULL and the
function completed successfully.
+.AP int objc in
+Number of requirements.
+.AP Tcl_Obj* objv[] in
+Array of requirements.
.BE
+
.SH DESCRIPTION
.PP
These procedures provide C-level interfaces to Tcl's package and
@@ -71,13 +79,18 @@ that is provided in the interpreter (which may be different than
\fIversion\fR); if an error occurs they return NULL and leave an error
message in the interpreter's result.
.PP
-\fBTcl_PkgProvide\fR returns TCL_OK if it completes successfully;
-if an error occurs it returns TCL_ERROR and leaves an error message
+\fBTcl_PkgProvide\fR returns \fBTCL_OK\fR if it completes successfully;
+if an error occurs it returns \fBTCL_ERROR\fR and leaves an error message
in the interpreter's result.
.PP
\fBTcl_PkgProvideEx\fR, \fBTcl_PkgPresentEx\fR and \fBTcl_PkgRequireEx\fR
allow the setting and retrieving of the client data associated with
the package. In all other respects they are equivalent to the matching
functions.
+.PP
+\fBTcl_PkgRequireProc\fR is the form of \fBpackage require\fR handling
+multiple requirements. The other forms are present for backward
+compatibility and translate their invocations to this form.
+
.SH KEYWORDS
package, present, provide, require, version
diff --git a/doc/Preserve.3 b/doc/Preserve.3
index b5d608e..2b3edc0 100644
--- a/doc/Preserve.3
+++ b/doc/Preserve.3
@@ -9,7 +9,7 @@
.TH Tcl_Preserve 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
-Tcl_Preserve, Tcl_Release, Tcl_EventuallyFree \- avoid freeing storage while it's being used
+Tcl_Preserve, Tcl_Release, Tcl_EventuallyFree \- avoid freeing storage while it is being used
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -36,7 +36,7 @@ having to do with widget deletion, but are also useful in many other
situations. When a widget is deleted, its
widget record (the structure holding information specific to the
widget) must be returned to the storage allocator.
-However, it's possible that the widget record is in active use
+However, it is possible that the widget record is in active use
by one of the procedures on the stack at the time of the deletion.
This can happen, for example, if the command associated with a button
widget causes the button to be destroyed: an X event causes an
diff --git a/doc/PrintDbl.3 b/doc/PrintDbl.3
index 75e7663..279b4d5 100644
--- a/doc/PrintDbl.3
+++ b/doc/PrintDbl.3
@@ -16,19 +16,17 @@ Tcl_PrintDouble \- Convert floating value to string
.sp
\fBTcl_PrintDouble\fR(\fIinterp, value, dst\fR)
.SH ARGUMENTS
-.AS Tcl_Interp *interp
+.AS Tcl_Interp *interp out
.AP Tcl_Interp *interp in
-.VS
Before Tcl 8.0, the \fBtcl_precision\fR variable in this interpreter
controlled the conversion. As of Tcl 8.0, this argument is ignored and
the conversion is controlled by the \fBtcl_precision\fR variable
that is now shared by all interpreters.
-.VE
.AP double value in
Floating-point value to be converted.
.AP char *dst out
-Where to store string representing \fIvalue\fR. Must have at
-least TCL_DOUBLE_SPACE characters of storage.
+Where to store the string representing \fIvalue\fR. Must have at
+least \fBTCL_DOUBLE_SPACE\fR characters of storage.
.BE
.SH DESCRIPTION
@@ -36,10 +34,22 @@ least TCL_DOUBLE_SPACE characters of storage.
\fBTcl_PrintDouble\fR generates a string that represents the value
of \fIvalue\fR and stores it in memory at the location given by
\fIdst\fR. It uses \fB%g\fR format to generate the string, with one
-special twist: the string is guaranteed to contain either
-a ``.'' or an ``e'' so that it doesn't look like an integer. Where
-\fB%g\fR would generate an integer with no decimal point, \fBTcl_PrintDouble\fR
-adds ``.0''.
+special twist: the string is guaranteed to contain either a
+.QW .
+or an
+.QW e
+so that it does not look like an integer. Where \fB%g\fR would
+generate an integer with no decimal point, \fBTcl_PrintDouble\fR adds
+.QW .0 .
+.VS 8.5
+.PP
+If the \fBtcl_precision\fR value is non-zero, the result will have
+precisely that many digits of significance. If the value is zero
+(the default), the result will have the fewest digits needed to
+represent the number in such a way that \fBTcl_NewDoubleObj\fR
+will generate the same number when presented with the given string.
+IEEE semantics of rounding to even apply to the conversion.
+.VE
.SH KEYWORDS
conversion, double-precision, floating-point, string
diff --git a/doc/RecEvalObj.3 b/doc/RecEvalObj.3
index 25982c8..2eed471 100644
--- a/doc/RecEvalObj.3
+++ b/doc/RecEvalObj.3
@@ -16,15 +16,15 @@ Tcl_RecordAndEvalObj \- save command on history list before evaluating
int
\fBTcl_RecordAndEvalObj\fR(\fIinterp, cmdPtr, flags\fR)
.SH ARGUMENTS
-.AS Tcl_Interp *interp;
+.AS Tcl_Interp *interp
.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)
to execute.
.AP int flags in
-An OR'ed combination of flag bits. TCL_NO_EVAL means record the
-command but don't evaluate it. TCL_EVAL_GLOBAL means evaluate
+An OR'ed combination of flag bits. \fBTCL_NO_EVAL\fR means record the
+command but do not evaluate it. \fBTCL_EVAL_GLOBAL\fR means evaluate
the command at global level instead of the current stack level.
.BE
@@ -32,18 +32,18 @@ the command at global level instead of the current stack level.
.PP
\fBTcl_RecordAndEvalObj\fR is invoked to record a command as an event
on the history list and then execute it using \fBTcl_EvalObjEx\fR
-(or \fBTcl_GlobalEvalObj\fR if the TCL_EVAL_GLOBAL bit is set
+(or \fBTcl_GlobalEvalObj\fR if the \fBTCL_EVAL_GLOBAL\fR bit is set
in \fIflags\fR).
-It returns a completion code such as TCL_OK just like \fBTcl_EvalObjEx\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
(a result value or error message)
that can be retrieved using \fBTcl_GetObjResult\fR.
-If you don't want the command recorded on the history list then
+If you do not want the command recorded on the history list then
you should invoke \fBTcl_EvalObjEx\fR instead of \fBTcl_RecordAndEvalObj\fR.
Normally \fBTcl_RecordAndEvalObj\fR is only called with top-level
commands typed by the user, since the purpose of history is to
-allow the user to re-issue recently-invoked commands.
-If the \fIflags\fR argument contains the TCL_NO_EVAL bit then
+allow the user to re-issue recently invoked commands.
+If the \fIflags\fR argument contains the \fBTCL_NO_EVAL\fR bit then
the command is recorded without being evaluated.
.SH "SEE ALSO"
diff --git a/doc/RecordEval.3 b/doc/RecordEval.3
index 4ca030d..a8f3087 100644
--- a/doc/RecordEval.3
+++ b/doc/RecordEval.3
@@ -17,14 +17,14 @@ Tcl_RecordAndEval \- save command on history list before evaluating
int
\fBTcl_RecordAndEval\fR(\fIinterp, cmd, flags\fR)
.SH ARGUMENTS
-.AS Tcl_Interp *interp;
+.AS Tcl_Interp *interp
.AP Tcl_Interp *interp in
Tcl interpreter in which to evaluate command.
-.AP "CONST char" *cmd in
+.AP "const char" *cmd in
Command (or sequence of commands) to execute.
.AP int flags in
-An OR'ed combination of flag bits. TCL_NO_EVAL means record the
-command but don't evaluate it. TCL_EVAL_GLOBAL means evaluate
+An OR'ed combination of flag bits. \fBTCL_NO_EVAL\fR means record the
+command but do not evaluate it. \fBTCL_EVAL_GLOBAL\fR means evaluate
the command at global level instead of the current stack level.
.BE
@@ -32,15 +32,15 @@ the command at global level instead of the current stack level.
.PP
\fBTcl_RecordAndEval\fR is invoked to record a command as an event
on the history list and then execute it using \fBTcl_Eval\fR
-(or \fBTcl_GlobalEval\fR if the TCL_EVAL_GLOBAL bit is set in \fIflags\fR).
-It returns a completion code such as TCL_OK just like \fBTcl_Eval\fR
+(or \fBTcl_GlobalEval\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_Eval\fR
and it leaves information in the interpreter's result.
-If you don't want the command recorded on the history list then
+If you do not want the command recorded on the history list then
you should invoke \fBTcl_Eval\fR instead of \fBTcl_RecordAndEval\fR.
Normally \fBTcl_RecordAndEval\fR is only called with top-level
commands typed by the user, since the purpose of history is to
allow the user to re-issue recently-invoked commands.
-If the \fIflags\fR argument contains the TCL_NO_EVAL bit then
+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
diff --git a/doc/RegConfig.3 b/doc/RegConfig.3
new file mode 100644
index 0000000..19c0bb0
--- /dev/null
+++ b/doc/RegConfig.3
@@ -0,0 +1,112 @@
+'\"
+'\" Copyright (c) 2002 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+'\"
+'\" 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"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_RegisterConfig \- procedures to register embedded configuration information
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_RegisterConfig\fR(\fIinterp, pkgName, configuration, valEncoding\fR)
+.sp
+.SH ARGUMENTS
+.AS Tcl_Interp *configuration
+.AP Tcl_Interp *interp in
+Refers to the interpreter the embedded configuration information is
+registered for. Must not be NULL.
+.AP "const char" *pkgName in
+Contains the name of the package registering the embedded
+configuration as ASCII string. This means that this information is in
+UTF-8 too. Must not be NULL.
+.AP Tcl_Config *configuration in
+Refers to an array of Tcl_Config entries containing the information
+embedded in the binary library. Must not be NULL. The end of the array
+is signaled by either a key identical to NULL, or a key referring to
+the empty string.
+.AP "const char" *valEncoding in
+Contains the name of the encoding used to store the configuration
+values as ASCII string. This means that this information is in UTF-8
+too. Must not be NULL.
+.BE
+
+.SH DESCRIPTION
+.PP
+The function described here has its base in TIP 59 and provides
+extensions with support for the embedding of configuration
+information into their binary library and the generation of a
+Tcl-level interface for querying this information.
+.PP
+To embed configuration information into their binary library an
+extension has to define a non-volatile array of Tcl_Config entries in
+one if its source files and then call \fBTcl_RegisterConfig\fR to
+register that information.
+.PP
+\fBTcl_RegisterConfig\fR takes four arguments; first, a reference to
+the interpreter we are registering the information with, second, the
+name of the package registering its configuration information, third,
+a pointer to an array of structures, and fourth a string declaring the
+encoding used by the configuration values.
+.PP
+The string \fIvalEncoding\fR contains the name of an encoding known to
+Tcl. All these names are use only characters in the ASCII subset of
+UTF-8 and are thus implicitly in the UTF-8 encoding. It is expected
+that keys are legible English text and therefore using the ASCII
+subset of UTF-8. In other words, they are expected to be in UTF-8
+too. The values associated with the keys can be any string
+however. For these the contents of \fIvalEncoding\fR define which
+encoding was used to represent the characters of the strings.
+.PP
+Each element of the \fIconfiguration\fR array refers to two strings
+containing the key and the value associated with that key. The end of
+the array is signaled by either an empty key or a key identical to
+NULL. The function makes \fBno\fR copy of the \fIconfiguration\fR
+array. This means that the caller has to make sure that the memory
+holding this array is never released. This is the meaning behind the
+word \fBnon-volatile\fR used earlier. The easiest way to accomplish
+this is to define a global static array of Tcl_Config entries. See the file
+.QW generic/tclPkgConfig.c
+in the sources of the Tcl core for an example.
+.PP
+When called \fBTcl_RegisterConfig\fR will
+.IP (1)
+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
+their associated values can be retrieved through calls to
+\fBpkgconfig\fR.
+.PP
+The command \fBpkgconfig\fR will provide two subcommands, \fBlist\fR
+and \fBget\fR:
+.RS
+.TP
+::\fIpkgName\fR::\fBpkgconfig\fR list
+Returns a list containing the names of all defined keys.
+.TP
+::\fIpkgName\fR::\fBpkgconfig\fR get \fIkey\fR
+Returns the configuration value associated with the specified
+\fIkey\fR.
+.RE
+.SH TCL_CONFIG
+.PP
+The \fBTcl_Config\fR structure contains the following fields:
+.PP
+.CS
+typedef struct Tcl_Config {
+ const char* key;
+ const char* value;
+} Tcl_Config;
+.CE
+.\" No cross references yet.
+.\" .SH "SEE ALSO"
+.SH KEYWORDS
+embedding, configuration, binary library
diff --git a/doc/RegExp.3 b/doc/RegExp.3
index d2163f2..0ac091c 100644
--- a/doc/RegExp.3
+++ b/doc/RegExp.3
@@ -16,93 +16,88 @@ Tcl_RegExpMatch, Tcl_RegExpCompile, Tcl_RegExpExec, Tcl_RegExpRange, Tcl_GetRegE
\fB#include <tcl.h>\fR
.sp
int
-\fBTcl_RegExpMatchObj\fR(\fIinterp\fR, \fIstrObj\fR, \fIpatObj\fR)
+\fBTcl_RegExpMatchObj\fR(\fIinterp\fR, \fItextObj\fR, \fIpatObj\fR)
.sp
int
-\fBTcl_RegExpMatch\fR(\fIinterp\fR, \fIstring\fR, \fIpattern\fR)
+\fBTcl_RegExpMatch\fR(\fIinterp\fR, \fItext\fR, \fIpattern\fR)
.sp
Tcl_RegExp
\fBTcl_RegExpCompile\fR(\fIinterp\fR, \fIpattern\fR)
.sp
int
-\fBTcl_RegExpExec\fR(\fIinterp\fR, \fIregexp\fR, \fIstring\fR, \fIstart\fR)
+\fBTcl_RegExpExec\fR(\fIinterp\fR, \fIregexp\fR, \fItext\fR, \fIstart\fR)
.sp
+void
\fBTcl_RegExpRange\fR(\fIregexp\fR, \fIindex\fR, \fIstartPtr\fR, \fIendPtr\fR)
-.VS 8.1
.sp
Tcl_RegExp
\fBTcl_GetRegExpFromObj\fR(\fIinterp\fR, \fIpatObj\fR, \fIcflags\fR)
.sp
int
-\fBTcl_RegExpExecObj\fR(\fIinterp\fR, \fIregexp\fR, \fIobjPtr\fR, \fIoffset\fR, \fInmatches\fR, \fIeflags\fR)
+\fBTcl_RegExpExecObj\fR(\fIinterp\fR, \fIregexp\fR, \fItextObj\fR, \fIoffset\fR, \fInmatches\fR, \fIeflags\fR)
.sp
+void
\fBTcl_RegExpGetInfo\fR(\fIregexp\fR, \fIinfoPtr\fR)
-.VE 8.1
-
+.fi
.SH ARGUMENTS
-.AS Tcl_Interp *interp
+.AS Tcl_RegExpInfo *interp in/out
.AP Tcl_Interp *interp in
Tcl interpreter to use for error reporting. The interpreter may be
NULL if no error reporting is desired.
-.VS 8.1
-.AP Tcl_Obj *strObj in/out
-Refers to the object from which to get the string to search. The
+.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
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.
-.VE 8.1
-.AP char *string in
-String to check for a match with a regular expression.
-.AP "CONST char" *pattern in
+.AP char *text in
+Text to search for a match with a regular expression.
+.AP "const char" *pattern in
String in the form of a regular expression pattern.
.AP Tcl_RegExp regexp in
Compiled regular expression. Must have been returned previously
by \fBTcl_GetRegExpFromObj\fR or \fBTcl_RegExpCompile\fR.
.AP char *start in
-If \fIstring\fR is just a portion of some other string, this argument
+If \fItext\fR is just a portion of some other string, this argument
identifies the beginning of the larger string.
-If it isn't the same as \fIstring\fR, then no \fB^\fR matches
-will be allowed.
+If it is not the same as \fItext\fR, then no
+.QW \fB^\fR
+matches will be allowed.
.AP int index in
Specifies which range is desired: 0 means the range of the entire
match, 1 or greater means the range that matched a parenthesized
sub-expression.
-.VS 8.4
-.AP "CONST char" **startPtr out
+.AP "const char" **startPtr out
The address of the first character in the range is stored here, or
NULL if there is no such range.
-.AP "CONST char" **endPtr out
+.AP "const char" **endPtr out
The address of the character just after the last one in the range
is stored here, or NULL if there is no such range.
-.VE 8.4
-.VS 8.1
.AP int cflags in
-OR-ed combination of compilation flags. See below for more information.
-.AP Tcl_Obj *objPtr in/out
-An object which contains the string to check for a match with a
-regular expression.
+OR-ed combination of the compilation flags \fBTCL_REG_ADVANCED\fR,
+\fBTCL_REG_EXTENDED\fR, \fBTCL_REG_BASIC\fR, \fBTCL_REG_EXPANDED\fR,
+\fBTCL_REG_QUOTE\fR, \fBTCL_REG_NOCASE\fR, \fBTCL_REG_NEWLINE\fR,
+\fBTCL_REG_NLSTOP\fR, \fBTCL_REG_NLANCH\fR, \fBTCL_REG_NOSUB\fR, and
+\fBTCL_REG_CANMATCH\fR. See below for more information.
.AP int offset in
-The character offset into the string where matching should begin.
+The character offset into the text where matching should begin.
The value of the offset has no impact on \fB^\fR matches. This
behavior is controlled by \fIeflags\fR.
.AP int nmatches in
The number of matching subexpressions that should be remembered for
later use. If this value is 0, then no subexpression match
-information will be computed. If the value is -1, then
+information will be computed. If the value is \-1, then
all of the matching subexpressions will be remembered. Any other
value will be taken as the maximum number of subexpressions to
remember.
.AP int eflags in
-OR-ed combination of the values TCL_REG_NOTBOL and TCL_REG_NOTEOL.
-See below for more information.
+OR-ed combination of the execution flags \fBTCL_REG_NOTBOL\fR and
+\fBTCL_REG_NOTEOL\fR. See below for more information.
.AP Tcl_RegExpInfo *infoPtr out
The address of the location where information about a previous match
should be stored by \fBTcl_RegExpGetInfo\fR.
-.VE 8.1
.BE
-
.SH DESCRIPTION
.PP
\fBTcl_RegExpMatch\fR determines whether its \fIpattern\fR argument
@@ -114,13 +109,11 @@ If there is no match then \fBTcl_RegExpMatch\fR returns 0.
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.
-.VS 8.1.2
\fBTcl_RegExpMatchObj\fR is similar to \fBTcl_RegExpMatch\fR except it
-operates on the Tcl objects \fIstrObj\fR and \fIpatObj\fR instead of
+operates on the Tcl objects \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.
-.VE 8.1.2
.PP
\fBTcl_RegExpCompile\fR, \fBTcl_RegExpExec\fR, and \fBTcl_RegExpRange\fR
provide lower-level access to the regular expression pattern matcher.
@@ -136,7 +129,7 @@ up to the next call to \fBTcl_RegExpCompile\fR; it is not safe to
retain these values for long periods of time.
.PP
\fBTcl_RegExpExec\fR executes the regular expression pattern matcher.
-It returns 1 if \fIstring\fR contains a range of characters that
+It returns 1 if \fItext\fR contains a range of characters that
match \fIregexp\fR, 0 if no match is found, and
\-1 if an error occurs.
In the case of an error, \fBTcl_RegExpExec\fR leaves an error
@@ -145,14 +138,16 @@ When searching a string for multiple matches of a pattern,
it is important to distinguish between the start of the original
string and the start of the current search.
For example, when searching for the second occurrence of a
-match, the \fIstring\fR argument might point to the character
+match, the \fItext\fR argument might point to the character
just after the first match; however, it is important for the
pattern matcher to know that this is not the start of the entire string,
-so that it doesn't allow \fB^\fR atoms in the pattern to match.
+so that it does not allow
+.QW \fB^\fR
+atoms in the pattern to match.
The \fIstart\fR argument provides this information by pointing
-to the start of the overall string containing \fIstring\fR.
-\fIStart\fR will be less than or equal to \fIstring\fR; if it
-is less than \fIstring\fR then no \fB^\fR matches will be allowed.
+to the start of the overall string containing \fItext\fR.
+\fIStart\fR will be less than or equal to \fItext\fR; if it
+is less than \fItext\fR then no \fB^\fR matches will be allowed.
.PP
\fBTcl_RegExpRange\fR may be invoked after \fBTcl_RegExpExec\fR
returns; it provides detailed information about what ranges of
@@ -168,7 +163,6 @@ information is returned about the range of characters that matched the
If there is no range corresponding to \fIindex\fR then NULL
is stored in \fI*startPtr\fR and \fI*endPtr\fR.
.PP
-.VS 8.1
\fBTcl_GetRegExpFromObj\fR, \fBTcl_RegExpExecObj\fR, and
\fBTcl_RegExpGetInfo\fR are object interfaces that provide the most
direct control of Henry Spencer's regular expression library. For
@@ -190,23 +184,29 @@ occurs while compiling the regular expression then
\fBTcl_GetRegExpFromObj\fR returns NULL and leaves an error message in
the interpreter result. The regular expression token can be used as
long as the internal representation of \fIpatObj\fR refers to the
-compiled form. The \fIeflags\fR argument is a bitwise OR of
+compiled form. The \fIcflags\fR argument is a bit-wise OR of
zero or more of the following flags that control the compilation of
\fIpatObj\fR:
.RS 2
.TP
\fBTCL_REG_ADVANCED\fR
-Compile advanced regular expressions (`AREs'). This mode corresponds to
-the normal regular expression syntax accepted by the Tcl regexp and
-regsub commands.
+Compile advanced regular expressions
+.PQ ARE s .
+This mode corresponds to
+the normal regular expression syntax accepted by the Tcl \fBregexp\fR and
+\fBregsub\fR commands.
.TP
\fBTCL_REG_EXTENDED\fR
-Compile extended regular expressions (`EREs'). This mode corresponds
+Compile extended regular expressions
+.PQ ERE s .
+This mode corresponds
to the regular expression syntax recognized by Tcl 8.0 and earlier
versions.
.TP
\fBTCL_REG_BASIC\fR
-Compile basic regular expressions (`BREs'). This mode corresponds
+Compile basic regular expressions
+.PQ BRE s .
+This mode corresponds
to the regular expression syntax recognized by common Unix utilities
like \fBsed\fR and \fBgrep\fR. This is the default if no flags are
specified.
@@ -226,26 +226,54 @@ Compile for matching that ignores upper/lower case distinctions.
\fBTCL_REG_NEWLINE\fR
Compile for newline-sensitive matching. By default, newline is a
completely ordinary character with no special meaning in either
-regular expressions or strings. With this flag, `[^' bracket
-expressions and `.' never match newline, `^' matches an empty string
-after any newline in addition to its normal function, and `$' matches
+regular expressions or strings. With this flag,
+.QW [^
+bracket expressions and
+.QW .
+never match newline,
+.QW ^
+matches an empty string
+after any newline in addition to its normal function, and
+.QW $
+matches
an empty string before any newline in addition to its normal function.
-\fBREG_NEWLINE\fR is the bitwise OR of \fBREG_NLSTOP\fR and
+\fBREG_NEWLINE\fR is the bit-wise OR of \fBREG_NLSTOP\fR and
\fBREG_NLANCH\fR.
.TP
\fBTCL_REG_NLSTOP\fR
Compile for partial newline-sensitive matching,
with the behavior of
-`[^' bracket expressions and `.' affected,
-but not the behavior of `^' and `$'. In this mode, `[^' bracket
-expressions and `.' never match newline.
+.QW [^
+bracket expressions and
+.QW .
+affected, but not the behavior of
+.QW ^
+and
+.QW $ .
+In this mode,
+.QW [^
+bracket expressions and
+.QW .
+never match newline.
.TP
\fBTCL_REG_NLANCH\fR
Compile for inverse partial newline-sensitive matching,
with the behavior of
-of `^' and `$' (the ``anchors'') affected, but not the behavior of
-`[^' bracket expressions and `.'. In this mode `^' matches an empty string
-after any newline in addition to its normal function, and `$' matches
+.QW ^
+and
+.QW $
+(the
+.QW anchors )
+affected, but not the behavior of
+.QW [^
+bracket expressions and
+.QW . .
+In this mode
+.QW ^
+matches an empty string
+after any newline in addition to its normal function, and
+.QW $
+matches
an empty string before any newline in addition to its normal function.
.TP
\fBTCL_REG_NOSUB\fR
@@ -273,25 +301,33 @@ error message in the interpreter result. The \fInmatches\fR value
indicates to the matcher how many subexpressions are of interest. If
\fInmatches\fR is 0, then no subexpression match information is
recorded, which may allow the matcher to make various optimizations.
-If the value is -1, then all of the subexpressions in the pattern are
+If the value is \-1, then all of the subexpressions in the pattern are
remembered. If the value is a positive integer, then only that number
of subexpressions will be remembered. Matching begins at the
specified Unicode character index given by \fIoffset\fR. Unlike
\fBTcl_RegExpExec\fR, the behavior of anchors is not affected by the
offset value. Instead the behavior of the anchors is explicitly
-controlled by the \fIeflags\fR argument, which is a bitwise OR of
+controlled by the \fIeflags\fR argument, which is a bit-wise OR of
zero or more of the following flags:
.RS 2
.TP
\fBTCL_REG_NOTBOL\fR
The starting character will not be treated as the beginning of a
-line or the beginning of the string, so `^' will not match there.
-Note that this flag has no effect on how `\fB\eA\fR' matches.
+line or the beginning of the string, so
+.QW ^
+will not match there.
+Note that this flag has no effect on how
+.QW \fB\eA\fR
+matches.
.TP
\fBTCL_REG_NOTEOL\fR
The last character in the string will not be treated as the end of a
-line or the end of the string, so '$' will not match there.
-Note that this flag has no effect on how `\fB\eZ\fR' matches.
+line or the end of the string, so
+.QW $
+will not match there.
+Note that this flag has no effect on how
+.QW \fB\eZ\fR
+matches.
.RE
.PP
\fBTcl_RegExpGetInfo\fR retrieves information about the last match
@@ -301,16 +337,16 @@ defined as follows:
.PP
.CS
typedef struct Tcl_RegExpInfo {
- int \fInsubs\fR;
- Tcl_RegExpIndices *\fImatches\fR;
- long \fIextendStart\fR;
+ int \fInsubs\fR;
+ Tcl_RegExpIndices *\fImatches\fR;
+ long \fIextendStart\fR;
} Tcl_RegExpInfo;
.CE
.PP
The \fInsubs\fR field contains a count of the number of parenthesized
subexpressions within the regular expression. If the \fBTCL_REG_NOSUB\fR
was used, then this value will be zero. The \fImatches\fR field
-points to an array of \fInsubs\fR values that indicate the bounds of each
+points to an array of \fInsubs\fR+1 values that indicate the bounds of each
subexpression matched. The first element in the array refers to the
range matched by the entire regular expression, and subsequent elements
refer to the parenthesized subexpressions in the order that they
@@ -319,8 +355,8 @@ follows:
.PP
.CS
typedef struct Tcl_RegExpIndices {
- long \fIstart\fR;
- long \fIend\fR;
+ long \fIstart\fR;
+ long \fIend\fR;
} Tcl_RegExpIndices;
.CE
.PP
@@ -331,7 +367,7 @@ subexpression. The \fIend\fR index identifies the first character
after the matched subexpression. If the subexpression matched the
empty string, then \fIstart\fR and \fIend\fR will be equal. If the
subexpression did not participate in the match, then \fIstart\fR and
-\fIend\fR will be set to -1.
+\fIend\fR will be set to \-1.
.PP
The \fIextendStart\fR field in \fBTcl_RegExpInfo\fR is only set if the
\fBTCL_REG_CANMATCH\fR flag was used. It indicates the first
@@ -340,8 +376,7 @@ found, this will be the same as the beginning of the current match.
If no match was found, then it indicates the earliest point at which a
match might occur if additional text is appended to the string. If it
is no match is possible even with further text, this field will be set
-to -1.
-.VE 8.1
+to \-1.
.SH "SEE ALSO"
re_syntax(n)
.SH KEYWORDS
diff --git a/doc/SaveResult.3 b/doc/SaveResult.3
index 8eb9b46..f47500e 100644
--- a/doc/SaveResult.3
+++ b/doc/SaveResult.3
@@ -1,5 +1,6 @@
'\"
'\" Copyright (c) 1997 by Sun Microsystems, Inc.
+'\" Contributions from Don Porter, NIST, 2004. (not subject to US copyright)
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -8,35 +9,95 @@
.TH Tcl_SaveResult 3 8.1 Tcl "Tcl Library Procedures"
.BS
.SH NAME
-Tcl_SaveResult, Tcl_RestoreResult, Tcl_DiscardResult \- save and restore an interpreter's result
+Tcl_SaveInterpState, Tcl_RestoreInterpState, Tcl_DiscardInterpState, Tcl_SaveResult, Tcl_RestoreResult, Tcl_DiscardResult \- save and restore an interpreter's state
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
-\fBTcl_SaveResult(\fIinterp, statePtr\fB)\fR
+Tcl_InterpState
+\fBTcl_SaveInterpState\fR(\fIinterp, status\fR)
.sp
-\fBTcl_RestoreResult(\fIinterp, statePtr\fB)\fR
+int
+\fBTcl_RestoreInterpState\fR(\fIinterp, state\fR)
.sp
-\fBTcl_DiscardResult(\fIstatePtr\fB)\fR
+\fBTcl_DiscardInterpState\fR(\fIstate\fR)
+.sp
+\fBTcl_SaveResult\fR(\fIinterp, savedPtr\fR)
+.sp
+\fBTcl_RestoreResult\fR(\fIinterp, savedPtr\fR)
+.sp
+\fBTcl_DiscardResult\fR(\fIsavedPtr\fR)
.SH ARGUMENTS
-.AS Tcl_SavedResult statePtr
+.AS Tcl_InterpState savedPtr
.AP Tcl_Interp *interp in
Interpreter for which state should be saved.
-.AP Tcl_SavedResult *statePtr in
+.AP int status in
+Return code value to save as part of interpreter state.
+.AP Tcl_InterpState state in
+Saved state token to be restored or discarded.
+.AP Tcl_SavedResult *savedPtr in
Pointer to location where interpreter result should be saved or restored.
.BE
.SH DESCRIPTION
.PP
+.VS 8.5
These routines allows a C procedure to take a snapshot of the current
-interpreter result so that it can be restored after a call
+state of an interpreter so that it can be restored after a call
to \fBTcl_Eval\fR or some other routine that modifies the interpreter
-result. These routines are passed a pointer to a structure that is
-used to store enough information to restore the interpreter result
-state. This structure can be allocated on the stack of the calling
+state. There are two triplets of routines meant to work together.
+.PP
+The first triplet stores the snapshot of interpreter state in
+an opaque token returned by \fBTcl_SaveInterpState\fR. That token
+value may then be passed back to one of \fBTcl_RestoreInterpState\fR
+or \fBTcl_DiscardInterpState\fR, depending on whether the interp
+state is to be restored. So long as one of the latter two routines
+is called, Tcl will take care of memory management.
+.PP
+The second triplet stores the snapshot of only the interpreter
+result (not its complete state) in memory allocated by the caller.
+These routines are passed a pointer to a \fBTcl_SavedResult\fR structure
+that is used to store enough information to restore the interpreter result.
+This structure can be allocated on the stack of the calling
procedure. These routines do not save the state of any error
-information in the interpreter (e.g. the \fBerrorCode\fR or
-\fBerrorInfo\fR variables).
+information in the interpreter (e.g. the \fB\-errorcode\fR or
+\fB\-errorinfo\fR return options, when an error is in progress).
+.PP
+Because the routines \fBTcl_SaveInterpState\fR,
+\fBTcl_RestoreInterpState\fR, and \fBTcl_DiscardInterpState\fR perform
+a superset of the functions provided by the other routines,
+any new code should only make use of the more powerful routines.
+The older, weaker routines \fBTcl_SaveResult\fR, \fBTcl_RestoreResult\fR,
+and \fBTcl_DiscardResult\fR continue to exist only for the sake
+of existing programs that may already be using them.
+.PP
+\fBTcl_SaveInterpState\fR takes a snapshot of those portions of
+interpreter state that make up the full result of script evaluation.
+This include the interpreter result, the return code (passed in
+as the \fIstatus\fR argument, and any return options, including
+\fB\-errorinfo\fR and \fB\-errorcode\fR when an error is in progress.
+This snapshot is returned as an opaque token of type \fBTcl_InterpState\fR.
+The call to \fBTcl_SaveInterpState\fR does not itself change the
+state of the interpreter. Unlike \fBTcl_SaveResult\fR, it does
+not reset the interpreter.
+.PP
+\fBTcl_RestoreInterpState\fR accepts a \fBTcl_InterpState\fR token
+previously returned by \fBTcl_SaveInterpState\fR and restores the
+state of the interp to the state held in that snapshot. The return
+value of \fBTcl_RestoreInterpState\fR is the status value originally
+passed to \fBTcl_SaveInterpState\fR when the snapshot token was
+created.
+.PP
+\fBTcl_DiscardInterpState\fR is called to release a \fBTcl_InterpState\fR
+token previously returned by \fBTcl_SaveInterpState\fR when that
+snapshot is not to be restored to an interp.
+.PP
+The \fBTcl_InterpState\fR token returned by \fBTcl_SaveInterpState\fR
+must eventually be passed to either \fBTcl_RestoreInterpState\fR
+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.
+.VE 8.5
.PP
\fBTcl_SaveResult\fR moves the string and object results
of \fIinterp\fR into the location specified by \fIstatePtr\fR.
diff --git a/doc/SetChanErr.3 b/doc/SetChanErr.3
new file mode 100644
index 0000000..13bd94a
--- /dev/null
+++ b/doc/SetChanErr.3
@@ -0,0 +1,153 @@
+'\"
+'\" Copyright (c) 2005 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+'\"
+'\" 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"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_SetChannelError, Tcl_SetChannelErrorInterp, Tcl_GetChannelError, Tcl_GetChannelErrorInterp \- functions to create/intercept Tcl errors by channel drivers.
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_SetChannelError\fR(\fIchan, msg\fR)
+.sp
+void
+\fBTcl_SetChannelErrorInterp\fR(\fIinterp, msg\fR)
+.sp
+void
+\fBTcl_GetChannelError\fR(\fIchan, msgPtr\fR)
+.sp
+void
+\fBTcl_GetChannelErrorInterp\fR(\fIinterp, msgPtr\fR)
+.sp
+.SH ARGUMENTS
+.AS Tcl_Channel chan
+.AP Tcl_Channel chan in
+Refers to the Tcl channel whose bypass area is accessed.
+.AP Tcl_Interp* interp in
+Refers to the Tcl interpreter whose bypass area is accessed.
+.AP Tcl_Obj* msg in
+Error message put into a bypass area. A list of return options and
+values, followed by a string message. Both message and the
+option/value information are optional.
+.AP Tcl_Obj** msgPtr out
+Reference to a place where the message stored in the accessed bypass
+area can be stored in.
+.BE
+.SH DESCRIPTION
+.PP
+The current definition of a Tcl channel driver does not permit the
+direct return of arbitrary error messages, except for the setting and
+retrieval of channel options. All other functions are restricted to
+POSIX error codes.
+.PP
+The functions described here overcome this limitation. Channel drivers
+are allowed to use \fBTcl_SetChannelError\fR and
+\fBTcl_SetChannelErrorInterp\fR to place arbitrary error messages in
+\fBbypass areas\fI 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 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 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 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.
+.PP
+\fBTcl_GetChannelError\fR places either the error message held in the
+bypass area of the specified channel into \fImsgPtr\fR, or NULL; and
+resets the bypass. I.e. after an invocation all following invocations
+will return 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.
+.PP
+\fBTcl_GetChannelErrorInterp\fR places either the error message held
+in the bypass area of the specified interpreter into \fImsgPtr\fR, or
+NULL; and resets the bypass. I.e. after an invocation all following
+invocations will return NULL, until an intervening invocation of
+\fBTcl_SetChannelErrorInterp\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 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.
+.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 messages in the bypass areas.
+.PP
+.IP \fBTcl_DriverCloseProc\fR
+May use \fBTcl_SetChannelErrorInterp\fR, and only this function.
+.IP \fBTcl_DriverInputProc\fR
+May use \fBTcl_SetChannelError\fR, and only this function.
+.IP \fBTcl_DriverOutputProc\fR
+May use \fBTcl_SetChannelError\fR, and only this function.
+.IP \fBTcl_DriverSeekProc\fR
+May use \fBTcl_SetChannelError\fR, and only this function.
+.IP \fBTcl_DriverWideSeekProc\fR
+May use \fBTcl_SetChannelError\fR, and only this function.
+.IP \fBTcl_DriverSetOptionProc\fR
+Has already the ability to pass arbitrary error messages. Must
+\fBnot\fR use any of the new functions.
+.IP \fBTcl_DriverGetOptionProc\fR
+Has already the ability to pass arbitrary error messages. Must
+\fBnot\fR use any of the new functions.
+.IP \fBTcl_DriverWatchProc\fR
+Must \fBnot\fR use any of the new functions. Is internally called and
+has no ability to return any type of error whatsoever.
+.IP \fBTcl_DriverBlockModeProc\fR
+May use \fBTcl_SetChannelError\fR, and only this function.
+.IP \fBTcl_DriverGetHandleProc\fR
+Must \fBnot\fR use any of the new functions. It is only a low-level
+function, and not used by Tcl commands.
+.IP \fBTcl_DriverHandlerProc\fR
+Must \fBnot\fR use any of the new functions. Is internally called and
+has no ability to return any type of error whatsoever.
+.PP
+Given the information above the following public functions of the Tcl
+C API are affected by these changes. I.e. when these functions are
+called the channel may now contain a stored arbitrary error message
+requiring processing by the caller.
+.PP
+.IP \fBTcl_StackChannel\fR
+.IP \fBTcl_Seek\fR
+.IP \fBTcl_Tell\fR
+.IP \fBTcl_ReadRaw\fR
+.IP \fBTcl_Read\fR
+.IP \fBTcl_ReadChars\fR
+.IP \fBTcl_Gets\fR
+.IP \fBTcl_GetsObj\fR
+.IP \fBTcl_Flush\fR
+.IP \fBTcl_WriteRaw\fR
+.IP \fBTcl_WriteObj\fR
+.IP \fBTcl_Write\fR
+.IP \fBTcl_WriteChars\fR
+.PP
+All other API functions are unchanged. Especially the functions below
+leave all their error information in the interpreter result.
+.PP
+.IP \fBTcl_Close\fR
+.IP \fBTcl_UnregisterChannel\fR
+.IP \fBTcl_UnstackChannel\fR
+
+.SH "SEE ALSO"
+Tcl_Close(3), Tcl_OpenFileChannel(3), Tcl_SetErrno(3)
+
+.SH KEYWORDS
+channel driver, error messages, channel type
diff --git a/doc/SetErrno.3 b/doc/SetErrno.3
index f29345a..1735952 100644
--- a/doc/SetErrno.3
+++ b/doc/SetErrno.3
@@ -19,14 +19,14 @@ void
int
\fBTcl_GetErrno\fR()
.sp
-CONST char *
+const char *
\fBTcl_ErrnoId\fR()
.sp
-CONST char *
+const char *
\fBTcl_ErrnoMsg\fR(\fIerrorCode\fR)
.sp
.SH ARGUMENTS
-.AS int errorCode in
+.AS int errorCode
.AP int errorCode in
A POSIX error code such as \fBENOENT\fR.
.BE
@@ -52,9 +52,11 @@ instead of accessing \fBerrno\fR directly.
\fBTcl_ErrnoId\fR and \fBTcl_ErrnoMsg\fR return string
representations of \fBerrno\fR values. \fBTcl_ErrnoId\fR
returns a machine-readable textual identifier such as
-"EACCES" that corresponds to the current value of \fBerrno\fR.
+.QW EACCES
+that corresponds to the current value of \fBerrno\fR.
\fBTcl_ErrnoMsg\fR returns a human-readable string such as
-"permission denied" that corresponds to the value of its
+.QW "permission denied"
+that corresponds to the value of its
\fIerrorCode\fR argument. The \fIerrorCode\fR argument is
typically the value returned by \fBTcl_GetErrno\fR.
The strings returned by these functions are
diff --git a/doc/SetResult.3 b/doc/SetResult.3
index 9844251..2245794 100644
--- a/doc/SetResult.3
+++ b/doc/SetResult.3
@@ -19,38 +19,40 @@ Tcl_SetObjResult, Tcl_GetObjResult, Tcl_SetResult, Tcl_GetStringResult, Tcl_Appe
Tcl_Obj *
\fBTcl_GetObjResult\fR(\fIinterp\fR)
.sp
-\fBTcl_SetResult\fR(\fIinterp, string, freeProc\fR)
+\fBTcl_SetResult\fR(\fIinterp, result, freeProc\fR)
.sp
-CONST char *
+const char *
\fBTcl_GetStringResult\fR(\fIinterp\fR)
.sp
-\fBTcl_AppendResult\fR(\fIinterp, string, string, ... , \fB(char *) NULL\fR)
+\fBTcl_AppendResult\fR(\fIinterp, result, result, ... , \fB(char *) NULL\fR)
.sp
\fBTcl_AppendResultVA\fR(\fIinterp, argList\fR)
.sp
-\fBTcl_AppendElement\fR(\fIinterp, string\fR)
+\fBTcl_AppendElement\fR(\fIinterp, element\fR)
.sp
\fBTcl_ResetResult\fR(\fIinterp\fR)
.sp
\fBTcl_FreeResult\fR(\fIinterp\fR)
.SH ARGUMENTS
-.AS Tcl_FreeProc freeProc
+.AS Tcl_FreeProc freeProc out
.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.
-.AP char *string in
+.AP char *result in
String value to become result for \fIinterp\fR or to be
appended to the existing result.
+.AP char *element in
+String value to append as a list element
+to the existing result of \fIinterp\fR.
.AP Tcl_FreeProc *freeProc in
Address of procedure to call to release storage at
-\fIstring\fR, or \fBTCL_STATIC\fR, \fBTCL_DYNAMIC\fR, or
+\fIresult\fR, or \fBTCL_STATIC\fR, \fBTCL_DYNAMIC\fR, or
\fBTCL_VOLATILE\fR.
.AP va_list argList in
-An argument list which must have been initialised using
-\fBTCL_VARARGS_START\fR, and cleared using \fBva_end\fR.
+An argument list which must have been initialized using
+\fBva_start\fR, and cleared using \fBva_end\fR.
.BE
-
.SH DESCRIPTION
.PP
The procedures described here are utilities for manipulating the
@@ -82,20 +84,20 @@ references to it remain.
The object's reference count is not incremented;
if the caller needs to retain a long-term pointer to the object
they should use \fBTcl_IncrRefCount\fR to increment its reference count
-in order to keep it from being freed too early or accidently changed.
+in order to keep it from being freed too early or accidentally changed.
.PP
\fBTcl_SetResult\fR
-arranges for \fIstring\fR to be the result for the current Tcl
+arranges for \fIresult\fR to be the result for the current Tcl
command in \fIinterp\fR, replacing any existing result.
The \fIfreeProc\fR argument specifies how to manage the storage
-for the \fIstring\fR argument;
+for the \fIresult\fR argument;
it is discussed in the section
\fBTHE TCL_FREEPROC ARGUMENT TO TCL_SETRESULT\fR below.
-If \fIstring\fR is \fBNULL\fR, then \fIfreeProc\fR is ignored
+If \fIresult\fR is \fBNULL\fR, then \fIfreeProc\fR is ignored
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 an string.
+\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,
@@ -114,60 +116,62 @@ and the result is left as a empty string.
\fBTcl_ResetResult\fR also clears the error state managed by
\fBTcl_AddErrorInfo\fR, \fBTcl_AddObjErrorInfo\fR,
and \fBTcl_SetErrorCode\fR.
-
-.SH "OLD STRING PROCEDURES"
-.PP
-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
-can be significantly more efficient.
.PP
\fBTcl_AppendResult\fR makes it easy to build up Tcl results in pieces.
-It takes each of its \fIstring\fR arguments and appends them in order
+It takes each of its \fIresult\fR arguments and appends them in order
to the current result associated with \fIinterp\fR.
If the result is in its initialized empty state (e.g. a command procedure
was just invoked or \fBTcl_ResetResult\fR was just called),
then \fBTcl_AppendResult\fR sets the result to the concatenation of
-its \fIstring\fR arguments.
+its \fIresult\fR arguments.
\fBTcl_AppendResult\fR may be called repeatedly as additional pieces
of the result are produced.
\fBTcl_AppendResult\fR takes care of all the
storage management issues associated with managing \fIinterp\fR's
result, such as allocating a larger result area if necessary.
-It also converts the current interpreter result from an object
-to a string, if necessary, before appending the argument strings.
-Any number of \fIstring\fR arguments may be passed in a single
+It also manages conversion to and from the \fIresult\fR field of the
+\fIinterp\fR so as to handle backward-compatibility with old-style
+extensions.
+Any number of \fIresult\fR arguments may be passed in a single
call; the last argument in the list must be a NULL pointer.
.PP
\fBTcl_AppendResultVA\fR is the same as \fBTcl_AppendResult\fR except that
instead of taking a variable number of arguments it takes an argument list.
+.SH "OLD STRING PROCEDURES"
+.PP
+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
+can be significantly more efficient.
.PP
\fBTcl_AppendElement\fR is similar to \fBTcl_AppendResult\fR in
that it allows results to be built up in pieces.
-However, \fBTcl_AppendElement\fR takes only a single \fIstring\fR
+However, \fBTcl_AppendElement\fR takes only a single \fIelement\fR
argument and it appends that argument to the current result
as a proper Tcl list element.
\fBTcl_AppendElement\fR adds backslashes or braces if necessary
to ensure that \fIinterp\fR's result can be parsed as a list and that
-\fIstring\fR will be extracted as a single element.
+\fIelement\fR will be extracted as a single element.
Under normal conditions, \fBTcl_AppendElement\fR will add a space
character to \fIinterp\fR's result just before adding the new
list element, so that the list elements in the result are properly
separated.
However if the new list element is the first in a list or sub-list
(i.e. \fIinterp\fR's current result is empty, or consists of the
-single character ``{'', or ends in the characters `` {'') then no
-space is added.
+single character
+.QW { ,
+or ends in the characters
+.QW " {" )
+then no space is added.
.PP
\fBTcl_FreeResult\fR performs part of the work
of \fBTcl_ResetResult\fR.
It frees up the memory associated with \fIinterp\fR's result.
-It also sets \fIinterp->freeProc\fR to zero, but doesn't
+It also sets \fIinterp->freeProc\fR to zero, but does not
change \fIinterp->result\fR or clear error state.
\fBTcl_FreeResult\fR is most commonly used when a procedure
is about to replace one result value with another.
-
.SH "DIRECT ACCESS TO INTERP->RESULT IS DEPRECATED"
.PP
It used to be legal for programs to
@@ -178,32 +182,31 @@ because it can make the result's string and object forms inconsistent.
Programs should always read the result
using the procedures \fBTcl_GetObjResult\fR or \fBTcl_GetStringResult\fR,
and write the result using \fBTcl_SetObjResult\fR or \fBTcl_SetResult\fR.
-
.SH "THE TCL_FREEPROC ARGUMENT TO TCL_SETRESULT"
.PP
\fBTcl_SetResult\fR's \fIfreeProc\fR argument specifies how
-the Tcl system is to manage the storage for the \fIstring\fR argument.
+the Tcl system is to manage the storage for the \fIresult\fR argument.
If \fBTcl_SetResult\fR or \fBTcl_SetObjResult\fR are called
at a time when \fIinterp\fR holds a string result,
they do whatever is necessary to dispose of the old string result
(see the \fBTcl_Interp\fR manual entry for details on this).
.PP
-If \fIfreeProc\fR is \fBTCL_STATIC\fR it means that \fIstring\fR
+If \fIfreeProc\fR is \fBTCL_STATIC\fR it means that \fIresult\fR
refers to an area of static storage that is guaranteed not to be
modified until at least the next call to \fBTcl_Eval\fR.
If \fIfreeProc\fR
-is \fBTCL_DYNAMIC\fR it means that \fIstring\fR was allocated with a call
+is \fBTCL_DYNAMIC\fR it means that \fIresult\fR was allocated with a call
to \fBTcl_Alloc\fR and is now the property of the Tcl system.
\fBTcl_SetResult\fR will arrange for the string's storage to be
released by calling \fBTcl_Free\fR when it is no longer needed.
-If \fIfreeProc\fR is \fBTCL_VOLATILE\fR it means that \fIstring\fR
+If \fIfreeProc\fR is \fBTCL_VOLATILE\fR it means that \fIresult\fR
points to an area of memory that is likely to be overwritten when
\fBTcl_SetResult\fR returns (e.g. it points to something in a stack frame).
In this case \fBTcl_SetResult\fR will make a copy of the string in
dynamically allocated storage and arrange for the copy to be the
result for the current Tcl command.
.PP
-If \fIfreeProc\fR isn't one of the values \fBTCL_STATIC\fR,
+If \fIfreeProc\fR is not one of the values \fBTCL_STATIC\fR,
\fBTCL_DYNAMIC\fR, and \fBTCL_VOLATILE\fR, then it is the address
of a procedure that Tcl should call to free the string.
This allows applications to use non-standard storage allocators.
@@ -214,10 +217,8 @@ result that match the type \fBTcl_FreeProc\fR:
typedef void Tcl_FreeProc(char *\fIblockPtr\fR);
.CE
When \fIfreeProc\fR is called, its \fIblockPtr\fR will be set to
-the value of \fIstring\fR passed to \fBTcl_SetResult\fR.
-
+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
diff --git a/doc/SetVar.3 b/doc/SetVar.3
index 9391e3e..ce47a73 100644
--- a/doc/SetVar.3
+++ b/doc/SetVar.3
@@ -14,29 +14,25 @@ Tcl_SetVar2Ex, Tcl_SetVar, Tcl_SetVar2, Tcl_ObjSetVar2, Tcl_GetVar2Ex, Tcl_GetVa
.nf
\fB#include <tcl.h>\fR
.sp
-.VS 8.1
Tcl_Obj *
\fBTcl_SetVar2Ex\fR(\fIinterp, name1, name2, newValuePtr, flags\fR)
-.VE
.sp
-CONST char *
+const char *
\fBTcl_SetVar\fR(\fIinterp, varName, newValue, flags\fR)
.sp
-CONST char *
+const char *
\fBTcl_SetVar2\fR(\fIinterp, name1, name2, newValue, flags\fR)
.sp
Tcl_Obj *
\fBTcl_ObjSetVar2\fR(\fIinterp, part1Ptr, part2Ptr, newValuePtr, flags\fR)
.sp
-.VS 8.1
Tcl_Obj *
\fBTcl_GetVar2Ex\fR(\fIinterp, name1, name2, flags\fR)
-.VE
.sp
-CONST char *
+const char *
\fBTcl_GetVar\fR(\fIinterp, varName, flags\fR)
.sp
-CONST char *
+const char *
\fBTcl_GetVar2\fR(\fIinterp, name1, name2, flags\fR)
.sp
Tcl_Obj *
@@ -51,29 +47,27 @@ int
.AS Tcl_Interp *newValuePtr
.AP Tcl_Interp *interp in
Interpreter containing variable.
-.AP "CONST char" *name1 in
+.AP "const char" *name1 in
Contains the name of an array variable (if \fIname2\fR is non-NULL)
or (if \fIname2\fR is NULL) either the name of a scalar variable
or a complete name including both variable name and index.
May include \fB::\fR namespace qualifiers
to specify a variable in a particular namespace.
-.AP "CONST char" *name2 in
+.AP "const char" *name2 in
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
-.VS 8.1
Points to a Tcl object containing the new value for the variable.
-.VE
.AP int flags in
OR-ed combination of bits providing additional information. See below
for valid values.
-.AP "CONST char" *varName in
+.AP "const char" *varName in
Name of variable.
May include \fB::\fR namespace qualifiers
to specify a variable in a particular namespace.
May refer to a scalar variable or an element of
an array.
-.AP "CONST char" *newValue in
+.AP "const char" *newValue in
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
@@ -91,7 +85,6 @@ within an array and \fIpart1Ptr\fR must refer to an array variable.
These procedures are used to create, modify, read, and delete
Tcl variables from C code.
.PP
-.VS 8.1
\fBTcl_SetVar2Ex\fR, \fBTcl_SetVar\fR, \fBTcl_SetVar2\fR, and
\fBTcl_ObjSetVar2\fR
will create a new variable or modify an existing one.
@@ -105,14 +98,12 @@ a pointer to a Tcl_Obj. \fBTcl_SetVar\fR and \fBTcl_SetVar2\fR
take the new value as a string and return a string; they are
usually less efficient than \fBTcl_ObjSetVar2\fR. Note that the
return value may be different than the \fInewValuePtr\fR or
-.VE
\fInewValue\fR argument, due to modifications made by write traces.
If an error occurs in setting the variable (e.g. an array
variable is referenced without giving an index into the array)
NULL is returned and an error message is left in \fIinterp\fR's
result if the \fBTCL_LEAVE_ERR_MSG\fR \fIflag\fR bit is set.
.PP
-.VS 8.1
\fBTcl_GetVar2Ex\fR, \fBTcl_GetVar\fR, \fBTcl_GetVar2\fR, and
\fBTcl_ObjGetVar2\fR
return the current value of a variable.
@@ -125,9 +116,8 @@ returned as a pointer to a Tcl_Obj. For \fBTcl_GetVar\fR and
\fBTcl_GetVar2\fR the value is returned as a string; this is
usually less efficient, so \fBTcl_GetVar2Ex\fR or \fBTcl_ObjGetVar2\fR
are preferred.
-.VE
If an error occurs while reading the variable (e.g. the variable
-doesn't exist or an array element is specified for a scalar
+does not exist or an array element is specified for a scalar
variable), then NULL is returned and an error message is left
in \fIinterp\fR's result if the \fBTCL_LEAVE_ERR_MSG\fR \fIflag\fR
bit is set.
@@ -137,9 +127,9 @@ a variable, so that future attempts to read the variable will return
an error.
The arguments to these procedures are treated in the same way
as the arguments to the procedures above.
-If the variable is successfully removed then TCL_OK is returned.
-If the variable cannot be removed because it doesn't exist then
-TCL_ERROR is returned and an error message is left
+If the variable is successfully removed then \fBTCL_OK\fR is returned.
+If the variable cannot be removed because it does not exist then
+\fBTCL_ERROR\fR is returned and an error message is left
in \fIinterp\fR's result if the \fBTCL_LEAVE_ERR_MSG\fR \fIflag\fR
bit is set.
If an array element is specified, the given element is removed
@@ -158,23 +148,20 @@ close parenthesis, then the value between the parentheses is
treated as an index (which can have any string value) and
the characters before the first open
parenthesis are treated as the name of an array variable.
-If \fIvarName\fR doesn't have parentheses as described above, then
+If \fIvarName\fR does not have parentheses as described above, then
the entire string is treated as the name of a scalar variable.
.IP [2]
If the \fIname1\fR and \fIname2\fR arguments are provided and
\fIname2\fR is non-NULL, then an array element is specified and
the array name and index have
already been separated by the caller: \fIname1\fR contains the
-name and \fIname2\fR contains the index.
-.VS 8.1
-An error is generated
+name and \fIname2\fR contains the index. An error is generated
if \fIname1\fR contains an open parenthesis and ends with a
close parenthesis (array element) and \fIname2\fR is non-NULL.
.IP [3]
If \fIname2\fR is NULL, \fIname1\fR is treated just like
\fIvarName\fR in case [1] above (it can be either a scalar or an array
element variable name).
-.VE
.PP
The \fIflags\fR argument may be used to specify any of several
options to the procedures.
@@ -203,7 +190,7 @@ If an error is returned and this bit is set in \fIflags\fR, then
an error message will be left in the interpreter's result,
where it can be retrieved with \fBTcl_GetObjResult\fR
or \fBTcl_GetStringResult\fR.
-If this flag bit isn't set then no error message is left
+If this flag bit is not set then no error message is left
and the interpreter's result will not be modified.
.TP
\fBTCL_APPEND_VALUE\fR
@@ -218,7 +205,10 @@ Tcl list element before setting (or appending to) the variable.
A separator space is appended before the new list element unless
the list element is going to be the first element in a list or
sublist (i.e. the variable's current value is empty, or contains
-the single character ``{'', or ends in `` }'').
+the single character
+.QW { ,
+or ends in
+.QW " }" ).
When appending, the original value of the variable must also be
a valid list, so that the operation is the appending of a new
list element onto a list.
@@ -231,12 +221,12 @@ Under normal circumstances, the return value is a pointer
to the variable's value (which is stored in Tcl's variable
structure and will not change before the next call to \fBTcl_SetVar\fR
or \fBTcl_SetVar2\fR).
-\fBTcl_GetVar\fR and \fBTcl_GetVar2\fR use the flag bits TCL_GLOBAL_ONLY
-and TCL_LEAVE_ERR_MSG, both of
+\fBTcl_GetVar\fR and \fBTcl_GetVar2\fR use the flag bits \fBTCL_GLOBAL_ONLY\fR
+and \fBTCL_LEAVE_ERR_MSG\fR, both of
which have
the same meaning as for \fBTcl_SetVar\fR.
If an error occurs in reading the variable (e.g. the variable
-doesn't exist or an array element is specified for a scalar
+does not exist or an array element is specified for a scalar
variable), then NULL is returned.
.PP
\fBTcl_UnsetVar\fR and \fBTcl_UnsetVar2\fR may be used to remove
@@ -244,9 +234,9 @@ a variable, so that future calls to \fBTcl_GetVar\fR or \fBTcl_GetVar2\fR
for the variable will return an error.
The arguments to these procedures are treated in the same way
as the arguments to \fBTcl_GetVar\fR and \fBTcl_GetVar2\fR.
-If the variable is successfully removed then TCL_OK is returned.
-If the variable cannot be removed because it doesn't exist then
-TCL_ERROR is returned.
+If the variable is successfully removed then \fBTCL_OK\fR is returned.
+If the variable cannot be removed because it does not exist then
+\fBTCL_ERROR\fR is returned.
If an array element is specified, the given element is removed
but the array remains.
If an array name is specified without an index, then the entire
diff --git a/doc/Signal.3 b/doc/Signal.3
index f8eafd0..5b12654 100644
--- a/doc/Signal.3
+++ b/doc/Signal.3
@@ -13,13 +13,14 @@ Tcl_SignalId, Tcl_SignalMsg \- Convert signal codes
.nf
\fB#include <tcl.h>\fR
.sp
-CONST char *
+const char *
\fBTcl_SignalId\fR(\fIsig\fR)
.sp
-CONST char *
+const char *
\fBTcl_SignalMsg\fR(\fIsig\fR)
.sp
.SH ARGUMENTS
+.AS int sig
.AP int sig in
A POSIX signal number such as \fBSIGPIPE\fR.
.BE
@@ -29,8 +30,11 @@ A POSIX signal number such as \fBSIGPIPE\fR.
\fBTcl_SignalId\fR and \fBTcl_SignalMsg\fR return a string
representation of the provided signal number (\fIsig\fR).
\fBTcl_SignalId\fR returns a machine-readable textual identifier such
-as "SIGPIPE". \fBTcl_SignalMsg\fR returns a human-readable string such
-as "bus error". The strings returned by these functions are
+as
+.QW SIGPIPE .
+\fBTcl_SignalMsg\fR returns a human-readable string such as
+.QW "bus error" .
+The strings returned by these functions are
statically allocated and the caller must not free or modify them.
.SH KEYWORDS
diff --git a/doc/Sleep.3 b/doc/Sleep.3
index 1abd2e6..2423ba1 100644
--- a/doc/Sleep.3
+++ b/doc/Sleep.3
@@ -16,20 +16,19 @@ Tcl_Sleep \- delay execution for a given number of milliseconds
.sp
\fBTcl_Sleep\fR(\fIms\fR)
.SH ARGUMENTS
+.AS int ms
.AP int ms in
Number of milliseconds to sleep.
.BE
-
.SH DESCRIPTION
.PP
This procedure delays the calling process by the number of
milliseconds given by the \fIms\fR parameter and returns
after that time has elapsed. It is typically used for things
like flashing a button, where the delay is short and the
-application needn't do anything while it waits. For longer
+application need not do anything while it waits. For longer
delays where the application needs to respond to other events
during the delay, the procedure \fBTcl_CreateTimerHandler\fR
should be used instead of \fBTcl_Sleep\fR.
-
.SH KEYWORDS
sleep, time, wait
diff --git a/doc/SourceRCFile.3 b/doc/SourceRCFile.3
index ed949cd..eabc47c 100644
--- a/doc/SourceRCFile.3
+++ b/doc/SourceRCFile.3
@@ -14,6 +14,7 @@ Tcl_SourceRCFile \- source the Tcl rc file
void
\fBTcl_SourceRCFile\fR(\fIinterp\fR)
.SH ARGUMENTS
+.AS Tcl_Interp *interp
.AP Tcl_Interp *interp in
Tcl interpreter to source rc file into.
.BE
@@ -26,10 +27,6 @@ sourced is obtained from the global variable \fBtcl_rcFileName\fR in
the interpreter given by \fIinterp\fR. If this variable is not
defined, or if the file it indicates cannot be found, no action is
taken.
-.PP
-On the Macintosh, after sourcing the rc file, this function will
-additionally source the TEXT resource indicated by the global variable
-\fBtcl_rcRsrcName\fR in \fIinterp\fR.
.SH KEYWORDS
application-specific initialization, main program, rc file
diff --git a/doc/SplitList.3 b/doc/SplitList.3
index b1a298d..fd6ec8b 100644
--- a/doc/SplitList.3
+++ b/doc/SplitList.3
@@ -32,7 +32,7 @@ int
int
\fBTcl_ConvertCountedElement\fR(\fIsrc, length, dst, flags\fR)
.SH ARGUMENTS
-.AS "CONST char * CONST" ***argvPtr
+.AS "const char *const" ***argvPtr out
.AP Tcl_Interp *interp out
Interpreter to use for error reporting. If NULL, then no error message
is left.
@@ -40,17 +40,17 @@ is left.
Pointer to a string with proper list structure.
.AP int *argcPtr out
Filled in with number of elements in \fIlist\fR.
-.AP "CONST char" ***argvPtr out
+.AP "const char" ***argvPtr out
\fI*argvPtr\fR will be filled in with the address of an array of
pointers to the strings that are the extracted elements of \fIlist\fR.
There will be \fI*argcPtr\fR valid entries in the array, followed by
a NULL entry.
.AP int argc in
Number of elements in \fIargv\fR.
-.AP "CONST char * CONST" *argv in
+.AP "const char *const" *argv in
Array of strings to merge together into a single list.
Each string will become a separate element of the list.
-.AP "CONST char" *src in
+.AP "const char" *src in
String that is to become an element of a list.
.AP int *flagsPtr in
Pointer to word to fill in with information about \fIsrc\fR.
@@ -151,7 +151,7 @@ include spaces between adjacent list elements.
\fBTcl_ConvertElement\fR uses one of two different approaches to
handle the special characters in \fIsrc\fR. Wherever possible, it
handles special characters by surrounding the string with braces.
-This produces clean-looking output, but can't be used in some situations,
+This produces clean-looking output, but cannot be used in some situations,
such as when \fIsrc\fR contains unmatched braces.
In these situations, \fBTcl_ConvertElement\fR handles special
characters by generating backslash sequences for them.
@@ -164,6 +164,20 @@ used to generate a portion of an argument for a Tcl command.
In this case, surrounding \fIsrc\fR with curly braces would cause
the command not to be parsed correctly.
.PP
+.VS 8.5
+By default, \fBTcl_ConvertElement\fR will use quoting in its output
+to be sure the first character of an element is not the hash
+character
+.PQ # .
+This is to be sure the first element of any list
+passed to \fBeval\fR is not mis-parsed as the beginning of a comment.
+When a list element is not the first element of a list, this quoting
+is not necessary. When the caller can be sure that the element is
+not the first element of a list, it can disable quoting of the leading
+hash character by OR-ing the flag value returned by \fBTcl_ScanElement\fR
+with \fBTCL_DONT_QUOTE_HASH\fR.
+.VE 8.5
+.PP
\fBTcl_ScanCountedElement\fR and \fBTcl_ConvertCountedElement\fR are
the same as \fBTcl_ScanElement\fR and \fBTcl_ConvertElement\fR, except
the length of string \fIsrc\fR is specified by the \fIlength\fR
diff --git a/doc/SplitPath.3 b/doc/SplitPath.3
index 9bc6acb..6578e3d 100644
--- a/doc/SplitPath.3
+++ b/doc/SplitPath.3
@@ -21,20 +21,20 @@ char *
Tcl_PathType
\fBTcl_GetPathType\fR(\fIpath\fR)
.SH ARGUMENTS
-.AS Tcl_DString ***argvPtr
-.AP "CONST char * CONST" *argvPtr in
+.AS "const char *const" ***argvPtr in/out
+.AP "const char" *path in
File path in a form appropriate for the current platform (see the
\fBfilename\fR manual entry for acceptable forms for path names).
.AP int *argcPtr out
Filled in with number of path elements in \fIpath\fR.
-.AP "CONST char" ***argvPtr out
+.AP "const char" ***argvPtr out
\fI*argvPtr\fR will be filled in with the address of an array of
pointers to the strings that are the extracted elements of \fIpath\fR.
There will be \fI*argcPtr\fR valid entries in the array, followed by
a NULL entry.
.AP int argc in
Number of elements in \fIargv\fR.
-.AP "CONST char * CONST" *argv in
+.AP "const char *const" *argv in
Array of path elements to merge together into a single path.
.AP Tcl_DString *resultPtr in/out
A pointer to an initialized \fBTcl_DString\fR to which the result of
diff --git a/doc/StaticPkg.3 b/doc/StaticPkg.3
index f4c279c..0dd67d1 100644
--- a/doc/StaticPkg.3
+++ b/doc/StaticPkg.3
@@ -8,7 +8,7 @@
.TH Tcl_StaticPackage 3 7.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
-Tcl_StaticPackage \- make a statically linked package available via the \fBload\fR command
+Tcl_StaticPackage \- make a statically linked package available via the 'load' command
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -20,8 +20,8 @@ Tcl_StaticPackage \- make a statically linked package available via the \fBload\
If not NULL, points to an interpreter into which the package has
already been loaded (i.e., the caller has already invoked the
appropriate initialization procedure). NULL means the package
-hasn't yet been incorporated into any interpreter.
-.AP "CONST char" *pkgName in
+has not yet been incorporated into any interpreter.
+.AP "const char" *pkgName in
Name of the package; should be properly capitalized (first letter
upper-case, all others lower-case).
.AP Tcl_PackageInitProc *initProc in
@@ -30,7 +30,7 @@ interpreter.
.AP Tcl_PackageInitProc *safeInitProc in
Procedure to call to incorporate this package into a safe interpreter
(one that will execute untrusted scripts). NULL means the package
-can't be used in safe interpreters.
+cannot be used in safe interpreters.
.BE
.SH DESCRIPTION
diff --git a/doc/StdChannels.3 b/doc/StdChannels.3
index 2a7dd05..b5b020e 100644
--- a/doc/StdChannels.3
+++ b/doc/StdChannels.3
@@ -26,8 +26,7 @@ output and the other for error messages.
.PP
Tcl generalizes this concept in a cross-platform way and
exposes standard channels to the script level.
-
-.SH APIs
+.SS "APPLICATION PROGRAMMING INTERFACES"
.PP
The public API procedures dealing directly with standard channels are
\fBTcl_GetStdChannel\fR and \fBTcl_SetStdChannel\fR. Additional public
@@ -41,17 +40,21 @@ channel information, or when implicitly required during registration
of a new channel.
.PP
These cases differ in how they handle unavailable platform- specific
-standard channels. (A channel is not ``available'' if it could not be
+standard channels. (A channel is not
+.QW available
+if it could not be
successfully opened; for example, in a Tcl application run as a
Windows NT service.)
.TP
1)
A single standard channel is initialized when it is explicitly
-specified in a call to \fBTcl_SetStdChannel\fR. The state of the
+specified in a call to \fBTcl_SetStdChannel\fR. The states of the
other standard channels are unaffected.
-.sp
+.RS
+.PP
Missing platform-specific standard channels do not matter here. This
approach is not available at the script level.
+.RE
.TP
2)
All uninitialized standard channels are initialized to
@@ -67,9 +70,7 @@ when information about any standard channel is requested with a call
to \fBTcl_GetStdChannel\fR, or with a call to \fBTcl_GetChannel\fR
which specifies one of the standard names (\fBstdin\fR, \fBstdout\fR
and \fBstderr\fR).
-.RE
-.sp
-.RS
+.PP
In case of missing platform-specific standard channels, the Tcl
standard channels are considered as initialized and then immediately
closed. This means that the first three Tcl channels then opened by
@@ -80,14 +81,13 @@ the application are designated as the Tcl standard channels.
All uninitialized standard channels are initialized to
platform-specific default values when a user-requested channel is
registered with \fBTcl_RegisterChannel\fR.
-.sp
+.PP
In case of unavailable platform-specific standard channels the channel
whose creation caused the initialization of the Tcl standard channels
is made a normal channel. The next three Tcl channels opened by the
application are designated as the Tcl standard channels. In other
words, of the first four Tcl channels opened by the application the
second to fourth are designated as the Tcl standard channels.
-.PP
.SH "RE-INITIALIZATION OF TCL STANDARD CHANNELS"
.PP
Once a Tcl standard channel is initialized through one of the methods
@@ -101,21 +101,20 @@ channel, too. If more than one Tcl standard channel was closed
that slot was not initialized before. It is this behavior which
enables an application to employ method 1 of initialization, i.e. to
create and designate their own Tcl standard channels.
-
-.SH tclsh
+.SH "SHELL-SPECIFIC DETAILS"
+.SS tclsh
.PP
-The Tcl shell (or rather \fBTcl_Main\fR) uses method 2 to initialize
+The Tcl shell (or rather the function \fBTcl_Main\fR, which forms the
+core of the shell's implementation) uses method 2 to initialize
the standard channels.
-
-.SH wish
+.SS wish
.PP
-The windowing shell (or rather \fBTk_MainEx\fR) uses method 1 to
+The windowing shell (or rather the function \fBTk_MainEx\fR, which
+forms the core of the shell's implementation) uses method 1 to
initialize the standard channels (See \fBTk_InitConsoleChannels\fR)
on non-Unix platforms. On Unix platforms, \fBTk_MainEx\fR implicitly
uses method 2 to initialize the standard channels.
-
.SH "SEE ALSO"
Tcl_CreateChannel(3), Tcl_RegisterChannel(3), Tcl_GetChannel(3), Tcl_GetStdChannel(3), Tcl_SetStdChannel(3), Tk_InitConsoleChannels(3), tclsh(1), wish(1), Tcl_Main(3), Tk_MainEx(3)
-
.SH KEYWORDS
standard channels
diff --git a/doc/StrMatch.3 b/doc/StrMatch.3
index f490c19..5adaf6e 100644
--- a/doc/StrMatch.3
+++ b/doc/StrMatch.3
@@ -6,7 +6,7 @@
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.so man.macros
-.TH Tcl_StringMatch 3 8.1 Tcl "Tcl Library Procedures"
+.TH Tcl_StringMatch 3 8.5 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_StringMatch, Tcl_StringCaseMatch \- test whether a string matches a pattern
@@ -15,19 +15,20 @@ Tcl_StringMatch, Tcl_StringCaseMatch \- test whether a string matches a pattern
\fB#include <tcl.h>\fR
.sp
int
-\fBTcl_StringMatch\fR(\fIstring\fR, \fIpattern\fR)
+\fBTcl_StringMatch\fR(\fIstr\fR, \fIpattern\fR)
.sp
int
-\fBTcl_StringCaseMatch\fR(\fIstring\fR, \fIpattern\fR, \fInocase\fR)
+\fBTcl_StringCaseMatch\fR(\fIstr\fR, \fIpattern\fR, \fIflags\fR)
.SH ARGUMENTS
-.AP char *string in
+.AS "const char" *pattern
+.AP "const char" *str in
String to test.
-.AP char *pattern in
+.AP "const char" *pattern in
Pattern to match against string. May contain special
characters from the set *?\e[].
-.AP int nocase in
-Specifies whether the match should be done case-sensitive (0) or
-case-insensitive (1).
+.AP int flags in
+OR-ed combination of match flags, currently only \fBTCL_MATCH_NOCASE\fR.
+0 specifies a case-sensitive search.
.BE
.SH DESCRIPTION
@@ -35,16 +36,14 @@ case-insensitive (1).
This utility procedure determines whether a string matches
a given pattern. If it does, then \fBTcl_StringMatch\fR returns
1. Otherwise \fBTcl_StringMatch\fR returns 0. The algorithm
-used for matching is the same algorithm used in the ``string match''
+used for matching is the same algorithm used in the \fBstring match\fR
Tcl command and is similar to the algorithm used by the C-shell
for file name matching; see the Tcl manual entry for details.
-.VS 8.1
.PP
-In \fBTcl_StringCaseMatch\fR, the algorithm is the same, but you have
-the option to make the matching case-insensitive. If you choose this
-(by passing \fBnocase\fR as 1), then the string and pattern are
-essentially matched in the lower case.
-.VE 8.1
+In \fBTcl_StringCaseMatch\fR, the algorithm is
+the same, but you have the option to make the matching case-insensitive.
+If you choose this (by passing \fBTCL_MATCH_NOCASE\fR), then the string and
+pattern are essentially matched in the lower case.
.SH KEYWORDS
match, pattern, string
diff --git a/doc/StringObj.3 b/doc/StringObj.3
index 6a624db..e451c61 100644
--- a/doc/StringObj.3
+++ b/doc/StringObj.3
@@ -8,7 +8,7 @@
.TH Tcl_StringObj 3 8.1 Tcl "Tcl Library Procedures"
.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_AppendStringsToObj, Tcl_AppendStringsToObjVA, Tcl_AppendObjToObj, Tcl_SetObjLength, Tcl_ConcatObj, Tcl_AttemptSetObjLength \- 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 objects as strings
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -60,6 +60,23 @@ void
.sp
void
\fBTcl_AppendStringsToObjVA\fR(\fIobjPtr, argList\fR)
+.VS 8.5
+.sp
+void
+\fBTcl_AppendLimitedToObj\fR(\fIobjPtr, bytes, length, limit, ellipsis\fR)
+.sp
+Tcl_Obj *
+\fBTcl_Format\fR(\fIinterp, format, objc, objv\fR)
+.sp
+int
+\fBTcl_AppendFormatToObj\fR(\fIinterp, objPtr, format, objc, objv\fR)
+.sp
+Tcl_Obj *
+\fBTcl_ObjPrintf\fR(\fIformat, ...\fR)
+.sp
+int
+\fBTcl_AppendPrintfToObj\fR(\fIobjPtr, format, ...\fR)
+.VE 8.5
.sp
void
\fBTcl_SetObjLength\fR(\fIobjPtr, newLength\fR)
@@ -70,22 +87,20 @@ int
Tcl_Obj *
\fBTcl_ConcatObj\fR(\fIobjc, objv\fR)
.SH ARGUMENTS
-.AS "CONST Tcl_UniChar" *appendObjPtr in/out
-.AP "CONST char" *bytes in
-.VS 8.1
+.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.
-This byte array should not contain embedded null bytes
-unless \fIlength\fR is negative. (Applications needing null bytes
-should represent them as the two-byte sequence \fI\\700\\600\fR, use
+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
\fBTcl_ExternalToUtf\fR to convert, or \fBTcl_NewByteArrayObj\fR if
the string is a collection of uninterpreted bytes.)
-.VE 8.1
.AP int length in
The number of bytes to copy from \fIbytes\fR when
initializing, setting, or appending to a string object.
If negative, all bytes up to the first null are used.
-.AP "CONST Tcl_UniChar" *unicode in
+.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.
This byte array may contain embedded null characters
@@ -108,19 +123,26 @@ Points to an object to manipulate.
The object 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 the length of an object's string representation.
-.AP "CONST char" *string in
+the length of an object'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
-\fBTCL_VARARGS_START\fR, and cleared using \fBva_end\fR.
+\fBva_start\fR, and cleared using \fBva_end\fR.
+.AP int limit in
+Maximum number of bytes to be appended.
+.AP "const char" *ellipsis in
+Suffix to append when the limit leads to string truncation.
+If NULL is passed then the suffix "..." is used.
+.AP "const char" *format in
+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.
.AP int newLength in
New length for the string value of \fIobjPtr\fR, not including the
final null character.
-.AP int objc in
-The number of elements to concatenate.
-.AP Tcl_Obj *objv[] in
-The array of objects to concatenate.
.BE
.SH DESCRIPTION
@@ -130,7 +152,7 @@ be manipulated as string values. They use the internal representation
of the object 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 doesn't have to be copied for each append.
+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
@@ -163,7 +185,7 @@ will be able to modify the string representation within the
\fBTcl_UpdateStringProc\fR of their \fBTcl_ObjType\fR. Except for that
limited purpose, the pointer returned by \fBTcl_GetStringFromObj\fR
or \fBTcl_GetString\fR should be treated as read-only. It is
-recommended that this pointer be assigned to a (CONST char *) variable.
+recommended that this pointer be assigned to a (const char *) variable.
Even in the limited situations where writing to this pointer is
acceptable, one should take care to respect the copy-on-write
semantics required by \fBTcl_Obj\fR's, with appropriate calls
@@ -229,6 +251,88 @@ must be a NULL pointer to indicate the end of the list.
except that instead of taking a variable number of arguments it takes an
argument list.
.PP
+.VS 8.5
+\fBTcl_AppendLimitedToObj\fR is similar to \fBTcl_AppendToObj\fR
+except that it imposes a limit on how many bytes are appended.
+This can be handy when the string to be appended might be
+very large, but the value being constructed should not be allowed to grow
+without bound. A common usage is when constructing an error message, where the
+end result should be kept short enough to be read.
+Bytes from \fIbytes\fR are appended to \fIobjPtr\fR, but no more
+than \fIlimit\fR bytes total are to be appended. If the limit prevents
+all \fIlength\fR bytes that are available from being appended, then the
+appending is done so that the last bytes appended are from the
+string \fIellipsis\fR. This allows for an indication of the truncation
+to be left in the string.
+When \fIlength\fR is \fB-1\fR, all bytes up to the first zero byte are appended,
+subject to the limit. When \fIellipsis\fR is NULL, the default
+string \fB...\fR is used. When \fIellipsis\fR is non-NULL, it must point
+to a zero-byte-terminated string in Tcl's internal UTF encoding.
+The number of bytes appended can be less than the lesser
+of \fIlength\fR and \fIlimit\fR when appending fewer
+bytes is necessary to append only whole multi-byte characters.
+.PP
+\fBTcl_Format\fR is the C-level interface to the engine of the \fBformat\fR
+command. The actual command procedure for \fBformat\fR is little more
+than
+.CS
+Tcl_Format(interp, Tcl_GetString(objv[1]), objc-2, objv+2);
+.CE
+The \fIobjc\fR Tcl_Obj values in \fIobjv\fR are formatted into a string
+according to the conversion specification in \fIformat\fR argument, following
+the documentation for the \fBformat\fR command. The resulting formatted
+string is converted to a new Tcl_Obj with refcount of zero and returned.
+If some error happens during production of the formatted string, NULL is
+returned, and an error message is recorded in \fIinterp\fR, if \fIinterp\fR
+is non-NULL.
+.PP
+\fBTcl_AppendFormatToObj\fR is an appending alternative form
+of \fBTcl_Format\fR with functionality equivalent to
+.CS
+Tcl_Obj *newPtr = Tcl_Format(interp, format, objc, objv);
+if (newPtr == NULL) return TCL_ERROR;
+Tcl_AppendObjToObj(objPtr, newPtr);
+return TCL_OK;
+.CE
+but with greater convenience and efficiency when the appending
+functionality is needed.
+.PP
+\fBTcl_ObjPrintf\fR serves as a replacement for the common sequence
+.CS
+char buf[SOME_SUITABLE_LENGTH];
+sprintf(buf, format, ...);
+Tcl_NewStringObj(buf, -1);
+.CE
+but with greater convenience and no need to
+determine \fBSOME_SUITABLE_LENGTH\fR. The formatting is done with the same
+core formatting engine used by \fBTcl_Format\fR. This means the set of
+supported conversion specifiers is that of the \fBformat\fR command and
+not that of the \fBsprintf\fR routine where the two sets differ. When a
+conversion specifier passed to \fBTcl_ObjPrintf\fR includes a precision,
+the value is taken as a number of bytes, as \fBsprintf\fR does, and not
+as a number of characters, as \fBformat\fR does. This is done on the
+assumption that C code is more likely to know how many bytes it is
+passing around than the number of encoded characters those bytes happen
+to represent. The variable number of arguments passed in should be of
+the types that would be suitable for passing to \fBsprintf\fR. Note in
+this example usage, \fIx\fR is of type \fBlong\fR.
+.CS
+long x = 5;
+Tcl_Obj *objPtr = Tcl_ObjPrintf("Value is %d", x);
+.CE
+If the value of \fIformat\fR contains internal inconsistencies or invalid
+specifier formats, the formatted string result produced by
+\fBTcl_ObjPrintf\fR will be an error message describing the error.
+.PP
+\fBTcl_AppendPrintfToObj\fR is an appending alternative form
+of \fBTcl_ObjPrintf\fR with functionality equivalent to
+.CS
+Tcl_AppendObjToObj(objPtr, Tcl_ObjPrintf(format, ...));
+.CE
+but with greater convenience and efficiency when the appending
+functionality is needed.
+.VE 8.5
+.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
@@ -265,7 +369,7 @@ cleaner-looking. \fBTcl_ConcatObj\fR returns a pointer to a
newly-created object whose ref count is zero.
.SH "SEE ALSO"
-Tcl_NewObj, Tcl_IncrRefCount, Tcl_DecrRefCount
+Tcl_NewObj, Tcl_IncrRefCount, Tcl_DecrRefCount, format, sprintf
.SH KEYWORDS
append, internal representation, object, object type, string object,
diff --git a/doc/SubstObj.3 b/doc/SubstObj.3
index 9f016c0..786b595 100644
--- a/doc/SubstObj.3
+++ b/doc/SubstObj.3
@@ -16,7 +16,7 @@ Tcl_SubstObj \- perform substitutions on Tcl objects
Tcl_Obj *
\fBTcl_SubstObj\fR(\fIinterp, objPtr, flags\fR)
.SH ARGUMENTS
-.AS Tcl_Interp **termPtr;
+.AS Tcl_Interp **termPtr
.AP Tcl_Interp *interp in
Interpreter in which to execute Tcl scripts and lookup variables. If
an error occurs, the interpreter's result is modified to hold an error
@@ -30,7 +30,6 @@ perform. The flags \fBTCL_SUBST_COMMANDS\fR,
currently supported, and \fBTCL_SUBST_ALL\fR is provided as a
convenience for the common case where all substitutions are desired.
.BE
-
.SH DESCRIPTION
.PP
The \fBTcl_SubstObj\fR function is used to perform substitutions on
@@ -51,19 +50,19 @@ When the \fBTCL_SUBST_VARIABLES\fR bit is set in \fIflags\fR,
sequences that look like variable substitutions for Tcl commands are
replaced by the contents of the named variable.
.PP
-When th \fBTCL_SUBST_COMMANDS\fR bit is set in \fIflags\fR, sequences
+When the \fBTCL_SUBST_COMMANDS\fR bit is set in \fIflags\fR, sequences
that look like command substitutions for Tcl commands are replaced by
-the result of evaluating that script. Where an uncaught continue
-exception occurs during the evaluation of a command substitution, an
-empty string is substituted for the command. Where an uncaught break
-exception occurs during the evaluation of a command substitution, the
+the result of evaluating that script. Where an uncaught
+.QW "continue exception"
+occurs during the evaluation of a command substitution, an
+empty string is substituted for the command. Where an uncaught
+.QW "break exception"
+occurs during the evaluation of a command substitution, the
result of the whole substitution on \fIobjPtr\fR will be truncated at
the point immediately before the start of the command substitution,
and no characters will be added to the result or substitutions
performed after that point.
-
.SH "SEE ALSO"
subst(n)
-
.SH KEYWORDS
backslash substitution, command substitution, variable substitution
diff --git a/doc/TCL_MEM_DEBUG.3 b/doc/TCL_MEM_DEBUG.3
index c531ac6..05d4564 100644
--- a/doc/TCL_MEM_DEBUG.3
+++ b/doc/TCL_MEM_DEBUG.3
@@ -7,53 +7,56 @@
.TH TCL_MEM_DEBUG 3 8.1 Tcl "Tcl Library Procedures"
.BS
.SH NAME
-TCL_MEM_DEBUG \- Compile-time flag to enable Tcl memory debugging.
+TCL_MEM_DEBUG \- Compile-time flag to enable Tcl memory debugging
.BE
-
.SH DESCRIPTION
When Tcl is compiled with \fBTCL_MEM_DEBUG\fR defined, a powerful set
-of memory debugging aids are included in the compiled binary. This
+of memory debugging aids is included in the compiled binary. This
includes C and Tcl functions which can aid with debugging
memory leaks, memory allocation overruns, and other memory related
errors.
-
.SH "ENABLING MEMORY DEBUGGING"
.PP
To enable memory debugging, Tcl should be recompiled from scratch with
-\fBTCL_MEM_DEBUG\fR defined. This will also compile in a non-stub
+\fBTCL_MEM_DEBUG\fR defined (e.g. by passing the
+\fI\-\-enable\-symbols=mem\fR flag to the \fIconfigure\fR script when
+building). This will also compile in a non-stub
version of \fBTcl_InitMemory\fR to add the \fBmemory\fR command to Tcl.
.PP
\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 \fBTclDbCkfree\fR and \fBTcl_DbCkalloc\fR or
+errors will occur, with either \fBTcl_DbCkfree\fR and \fBTcl_DbCkalloc\fR or
\fBTcl_Ckalloc\fR and \fBTcl_Ckfree\fR being undefined.
.PP
Once memory debugging support has been compiled into Tcl, the C
functions \fBTcl_ValidateAllMemory\fR, and \fBTcl_DumpActiveMemory\fR,
and the Tcl \fBmemory\fR command can be used to validate and examine
memory usage.
-
.SH "GUARD ZONES"
.PP
When memory debugging is enabled, whenever a call to \fBckalloc\fR is
-made, slightly more memory than requested is allocated so the memory debugging
-code can keep track of the allocated memory, and eight-byte ``guard
-zones'' are placed in front of and behind the space that will be
+made, slightly more memory than requested is allocated so the memory
+debugging code can keep track of the allocated memory, and eight-byte
+.QW "guard zones"
+are placed in front of and behind the space that will be
returned to the caller. (The sizes of the guard zones are defined by the
C #define \fBLOW_GUARD_SIZE\fR and #define \fBHIGH_GUARD_SIZE\fR
-in the file \fIgeneric/tclCkalloc.c\fR -- it can
+in the file \fIgeneric/tclCkalloc.c\fR \(em it can
be extended if you suspect large overwrite problems, at some cost in
performance.) A known pattern is written into the guard zones and, on
a call to \fBckfree\fR, the guard zones of the space being freed are
checked to see if either zone has been modified in any way. If one
has been, the guard bytes and their new contents are identified, and a
-``low guard failed'' or ``high guard failed'' message is issued. The
-``guard failed'' message includes the address of the memory packet and
+.QW "low guard failed"
+or
+.QW "high guard failed"
+message is issued. The
+.QW "guard failed"
+message includes the address of the memory packet and
the file name and line number of the code that called \fBckfree\fR.
This allows you to detect the common sorts of one-off problems, where
not enough space was allocated to contain the data written, for
example.
-
.SH "DEBUGGING DIFFICULT MEMORY CORRUPTION PROBLEMS"
.PP
Normally, Tcl compiled with memory debugging enabled will make it easy
@@ -66,16 +69,12 @@ This will enable memory validation from the first call to
\fBckalloc\fR, again, at a large performance impact.
.PP
If you are desperate and validating memory on every call to
-\fBckalloc\fR and \fBckfree\fR isn't enough, you can explicitly call
+\fBckalloc\fR and \fBckfree\fR is not enough, you can explicitly call
\fBTcl_ValidateAllMemory\fR directly at any point. It takes a \fIchar
*\fR and an \fIint\fR which are normally the filename and line number
of the caller, but they can actually be anything you want. Remember
to remove the calls after you find the problem.
-
.SH "SEE ALSO"
ckalloc, memory, Tcl_ValidateAllMemory, Tcl_DumpActiveMemory
-
.SH KEYWORDS
memory, debug
-
-
diff --git a/doc/Tcl.n b/doc/Tcl.n
index d329bb9..8b5b501 100644
--- a/doc/Tcl.n
+++ b/doc/Tcl.n
@@ -6,7 +6,7 @@
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.so man.macros
-.TH Tcl n "8.1" Tcl "Tcl Built-In Commands"
+.TH Tcl n "8.5" Tcl "Tcl Built-In Commands"
.BS
.SH NAME
Tcl \- Tool Command Language
@@ -39,17 +39,37 @@ Different commands interpret their words differently.
Words of a command are separated by white space (except for
newlines, which are command separators).
.IP "[4] \fBDouble quotes.\fR"
-If the first character of a word is double-quote (``"'') then
-the word is terminated by the next double-quote character.
+If the first character of a word is double-quote
+.PQ \N'34'
+then the word is terminated by the next double-quote character.
If semi-colons, close brackets, or white space characters
(including newlines) appear between the quotes then they are treated
as ordinary characters and included in the word.
Command substitution, variable substitution, and backslash substitution
are performed on the characters between the quotes as described below.
The double-quotes are not retained as part of the word.
-.IP "[5] \fBBraces.\fR"
-If the first character of a word is an open brace (``{'') then
-the word is terminated by the matching close brace (``}'').
+.VS 8.5 br
+.IP "[5] \fBArgument expansion.\fR"
+If a word starts with the string
+.QW {*}
+followed by a non-whitespace character, then the leading
+.QW {*}
+is removed and the rest of the word is parsed and substituted as any other
+word. After substitution, the word is parsed as a list (without command or
+variable substitutions; backslash substitutions are performed as is normal for
+a list and individual internal words may be surrounded by either braces or
+double-quote characters), and its words are added to the command being
+substituted. For instance,
+.QW "cmd a {*}{b [c]} d {*}{$e f \N'34'g h\N'34'}"
+is equivalent to
+.QW "cmd a b {[c]} d {$e} f \N'34'g h\N'34'" .
+.VE 8.5
+.IP "[6] \fBBraces.\fR"
+If the first character of a word is an open brace
+.PQ {
+and rule [5] does not apply, then
+the word is terminated by the matching close brace
+.PQ } "" .
Braces nest within the word: for each additional open
brace there must be an additional close brace (however,
if an open brace or close brace within the word is
@@ -61,20 +81,24 @@ below, nor do semi-colons, newlines, close brackets,
or white space receive any special interpretation.
The word will consist of exactly the characters between the
outer braces, not including the braces themselves.
-.IP "[6] \fBCommand substitution.\fR"
-If a word contains an open bracket (``['') then Tcl performs
-\fIcommand substitution\fR.
+.IP "[7] \fBCommand substitution.\fR"
+If a word contains an open bracket
+.PQ [
+then Tcl performs \fIcommand substitution\fR.
To do this it invokes the Tcl interpreter recursively to process
the characters following the open bracket as a Tcl script.
The script may contain any number of commands and must be terminated
-by a close bracket (``]'').
+by a close bracket
+.PQ ] "" .
The result of the script (i.e. the result of its last command) is
substituted into the word in place of the brackets and all of the
characters between them.
There may be any number of command substitutions in a single word.
Command substitution is not performed on words enclosed in braces.
-.IP "[7] \fBVariable substitution.\fR"
-If a word contains a dollar-sign (``$'') followed by one of the forms
+.IP "[8] \fBVariable substitution.\fR"
+If a word contains a dollar-sign
+.PQ $
+followed by one of the forms
described below, then Tcl performs \fIvariable
substitution\fR: the dollar-sign and the following characters are
replaced in the word by the value of a variable.
@@ -101,9 +125,10 @@ characters whatsoever except for close braces.
There may be any number of variable substitutions in a single word.
Variable substitution is not performed on words enclosed in braces.
.RE
-.IP "[8] \fBBackslash substitution.\fR"
-If a backslash (``\e'') appears within a word then
-\fIbackslash substitution\fR occurs.
+.IP "[9] \fBBackslash substitution.\fR"
+If a backslash
+.PQ \e
+appears within a word then \fIbackslash substitution\fR occurs.
In all cases but those described below the backslash is dropped and
the following character is treated as an ordinary
character and included in the word.
@@ -141,12 +166,12 @@ A single space character replaces the backslash, newline, and all spaces
and tabs after the newline. This backslash sequence is unique in that it
is replaced in a separate pre-pass before the command is actually parsed.
This means that it will be replaced even when it occurs between braces,
-and the resulting space will be treated as a word separator if it isn't
+and the resulting space will be treated as a word separator if it is not
in braces or quotes.
.TP 7
\e\e
-Backslash (``\e'').
-.VS 8.1 br
+Backslash
+.PQ \e "" .
.TP 7
\e\fIooo\fR
.
@@ -167,19 +192,20 @@ be 0.
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.
-.VE
.LP
Backslash substitution is not performed on words enclosed in braces,
except for backslash-newline as described above.
.RE
-.IP "[9] \fBComments.\fR"
-If a hash character (``#'') appears at a point where Tcl is
+.IP "[10] \fBComments.\fR"
+If a hash character
+.PQ #
+appears at a point where Tcl is
expecting the first character of the first word of a command,
then the hash character and the characters that follow it, up
through the next newline, are treated as a comment and ignored.
The comment character only has significance when it appears
at the beginning of a command.
-.IP "[10] \fBOrder of substitution.\fR"
+.IP "[11] \fBOrder of substitution.\fR"
Each character is processed exactly once by the Tcl interpreter
as part of creating the words of a command.
For example, if variable substitution occurs then no further
@@ -200,8 +226,9 @@ set y [set x 0][incr x][incr x]
.CE
will always set the variable \fIy\fR to the value, \fI012\fR.
.RE
-.IP "[11] \fBSubstitution and word boundaries.\fR"
-Substitutions do not affect the word boundaries of a command.
+.IP "[12] \fBSubstitution and word boundaries.\fR"
+Substitutions do not affect the word boundaries of a command,
+except for argument expansion as specified in rule [5].
For example, during variable substitution the entire value of
the variable becomes part of a single word, even if the variable's
value contains spaces.
diff --git a/doc/Tcl_Main.3 b/doc/Tcl_Main.3
index 4f29c82..54b2e84 100644
--- a/doc/Tcl_Main.3
+++ b/doc/Tcl_Main.3
@@ -19,7 +19,7 @@ Tcl_Main, Tcl_SetMainLoop \- main program and event loop definition for Tcl-base
.sp
\fBTcl_SetMainLoop\fR(\fImainLoopProc\fR)
.SH ARGUMENTS
-.AS Tcl_AppInitProc *appInitProc
+.AS Tcl_MainLoopProc *mainLoopProc
.AP int argc in
Number of elements in \fIargv\fR.
.AP char *argv[] in
@@ -34,7 +34,9 @@ Address of an application-specific event loop procedure.
.SH DESCRIPTION
.PP
\fBTcl_Main\fR can serve as the main program for Tcl-based shell
-applications. A ``shell application'' is a program
+applications. A
+.QW "shell application"
+is a program
like tclsh or wish that supports both interactive interpretation
of Tcl and evaluation of a script contained in a file given as
a command line argument. \fBTcl_Main\fR is offered as a convenience
@@ -74,9 +76,12 @@ channels to their default values. See \fBTcl_StandardChannels\fR for
more information.
.PP
\fBTcl_Main\fR supports two modes of operation, depending on the
-values of \fIargc\fR and \fIargv\fR. If \fIargv[1]\fR exists and
-does not begin with the character \fI-\fR, it is taken to be the
-name of a file containing a \fIstartup script\fR, which \fBTcl_Main\fR
+values of \fIargc\fR and \fIargv\fR. If the first few arguments
+in \fIargv\fR match ?\fB\-encoding \fIname\fR? \fIfileName\fR,
+where \fIfileName\fR does not begin with the character \fI\-\fR,
+then \fIfileName\fR is taken to be the name of a file containing
+a \fIstartup script\fR, and \fIname\fR is taken to be the name
+of the encoding of the contents of that file, which \fBTcl_Main\fR
will attempt to evaluate. Otherwise, \fBTcl_Main\fR will enter an
interactive mode.
.PP
@@ -86,8 +91,9 @@ the Tcl variables \fIargc\fR, \fIargv\fR, \fIargv0\fR, and
.PP
When it has finished its own initialization, but before it processes
commands, \fBTcl_Main\fR calls the procedure given by the
-\fIappInitProc\fR argument. This procedure provides a ``hook'' for
-the application to perform its own initialization of the interpreter
+\fIappInitProc\fR argument. This procedure provides a
+.QW hook
+for the application to perform its own initialization of the interpreter
created by \fBTcl_Main\fR, such as defining application-specific
commands. The procedure must have an interface that matches the
type \fBTcl_AppInitProc\fR:
@@ -114,7 +120,6 @@ The prompts and command evaluation results are written to the standard
output channel only if the Tcl variable \fItcl_interactive\fR in the
master interpreter holds a non-zero integer value.
.PP
-.VS 8.4
\fBTcl_SetMainLoop\fR allows setting an event loop procedure to be run.
This allows, for example, Tk to be dynamically loaded and set its event
loop. The event loop will run following the startup script. If you
@@ -127,7 +132,6 @@ The main loop procedure must have an interface that matches the type
.CS
typedef void Tcl_MainLoopProc(void);
.CE
-.VE 8.4
.PP
\fBTcl_Main\fR does not return. Normally a program based on
\fBTcl_Main\fR will terminate when the \fBexit\fR command is
diff --git a/doc/Thread.3 b/doc/Thread.3
index 2ffd6ef..80d34ad 100644
--- a/doc/Thread.3
+++ b/doc/Thread.3
@@ -9,7 +9,7 @@
.TH Threads 3 "8.1" Tcl "Tcl Library Procedures"
.BS
.SH NAME
-Tcl_ConditionNotify, Tcl_ConditionWait, Tcl_ConditionFinalize, Tcl_GetThreadData, Tcl_MutexLock, Tcl_MutexUnlock, Tcl_MutexFinalize, Tcl_CreateThread, Tcl_JoinThread \- Tcl thread support.
+Tcl_ConditionNotify, Tcl_ConditionWait, Tcl_ConditionFinalize, Tcl_GetThreadData, Tcl_MutexLock, Tcl_MutexUnlock, Tcl_MutexFinalize, Tcl_CreateThread, Tcl_JoinThread \- Tcl thread support
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -41,14 +41,14 @@ int
int
\fBTcl_JoinThread\fR(\fIid, result\fR)
.SH ARGUMENTS
-.AS Tcl_ThreadDataKey *keyPtr
+.AS Tcl_CreateThreadProc threadProc out
.AP Tcl_Condition *condPtr in
A condition variable, which must be associated with a mutex lock.
.AP Tcl_Mutex *mutexPtr in
A mutex lock.
.AP Tcl_Time *timePtr in
A time limit on the condition wait. NULL to wait forever.
-Note that a polling value of 0 seconds doesn't make much sense.
+Note that a polling value of 0 seconds does not make much sense.
.AP Tcl_ThreadDataKey *keyPtr in
This identifies a block of thread local storage. The key should be
static and process-wide, yet each thread will end up associating
@@ -80,42 +80,38 @@ waited upon into it.
Beginning with the 8.1 release, the Tcl core is thread safe, which
allows you to incorporate Tcl into multithreaded applications without
customizing the Tcl core. To enable Tcl multithreading support,
-you must include the \fB--enable-threads\fR option to \fBconfigure\fR
+you must include the \fB\-\|\-enable-threads\fR option to \fBconfigure\fR
when you configure and compile your Tcl core.
.PP
An important constraint of the Tcl threads implementation is that
\fIonly the thread that created a Tcl interpreter can use that
interpreter\fR. In other words, multiple threads can not access
-the same Tcl interpreter. (However, as was the case in previous
-releases, a single thread can safely create and use multiple
-interpreters.)
-.PP
-.VS 8.3.1
-Tcl does provide \fBTcl_CreateThread\fR for creating threads. The
+the same Tcl interpreter. (However, a single thread can safely create
+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
\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 are only the values
-\fBTCL_THREAD_NOFLAGS\fR and \fBTCL_THREAD_JOINABLE\fR defined. The
+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.
.PP
-Restrictions: On some unix systems the pthread-library does not
-contain the functionality to specify the stacksize of a thread. The
-specified value for the stacksize is ignored on these systems. Both
-Windows and Macintosh currently do not support joinable threads. This
-flag value is therefore ignored on these platforms.
-.VE
+Restrictions: On some UNIX systems the pthread-library does not
+contain the functionality to specify the stack size of a thread. The
+specified value for the stack size is ignored on these systems.
+Windows currently does not support joinable threads. This
+flag value is therefore ignored on this platform.
.PP
-Tcl does provide \fBTcl_ExitThread\fR and \fBTcl_FinalizeThread\fR
+Tcl provides the \fBTcl_ExitThread\fR and \fBTcl_FinalizeThread\fR functions
for terminating threads and invoking optional per-thread exit
handlers. See the \fBTcl_Exit\fR page for more information on these
procedures.
.PP
-.VS
The \fBTcl_JoinThread\fR function is provided to allow threads to wait
upon the exit of another thread, which must have been marked as
joinable through usage of the \fBTCL_THREAD_JOINABLE\fR-flag during
@@ -127,36 +123,29 @@ thread which already exited is possible, the system will retain the
necessary information until after the call to \fBTcl_JoinThread\fR.
This means that not calling \fBTcl_JoinThread\fR for a joinable thread
will cause a memory leak.
-.VE
.PP
+The \fBTcl_GetThreadData\fR call returns a pointer to a block of
+thread-private data. Its argument is a key that is shared by all threads
+and a size for the block of storage. The storage is automatically
+allocated and initialized to all zeros the first time each thread asks for it.
+The storage is automatically deallocated by \fBTcl_FinalizeThread\fR.
+.SS "SYNCHRONIZATION AND COMMUNICATION"
Tcl provides \fBTcl_ThreadQueueEvent\fR and \fBTcl_ThreadAlert\fR
-for handling event queueing in multithreaded applications. See
+for handling event queuing in multithreaded applications. See
the \fBNotifier\fR manual page for more information on these procedures.
.PP
-In this release, the Tcl language itself provides no support for
-creating multithreaded scripts (for example, scripts that could spawn
-a Tcl interpreter in a separate thread). If you need to add this
-feature at this time, see the \fItclThreadTest.c\fR
-file in the Tcl source distribution for an experimental implementation
-or use the Tcl "Threading Extension" package implementing thread creation
-and management commands at the script level.
-
-
-.SH DESCRIPTION
A mutex is a lock that is used to serialize all threads through a piece
of code by calling \fBTcl_MutexLock\fR and \fBTcl_MutexUnlock\fR.
If one thread holds a mutex, any other thread calling \fBTcl_MutexLock\fR will
block until \fBTcl_MutexUnlock\fR is called.
-.VS
A mutex can be destroyed after its use by calling \fBTcl_MutexFinalize\fR.
The result of locking a mutex twice from the same thread is undefined.
On some platforms it will result in a deadlock.
-.VE
The \fBTcl_MutexLock\fR, \fBTcl_MutexUnlock\fR and \fBTcl_MutexFinalize\fR
procedures are defined as empty macros if not compiling with threads enabled.
For declaration of mutexes the \fBTCL_DECLARE_MUTEX\fR macro should be used.
This macro assures correct mutex handling even when the core is compiled
-without threads enabled.
+without threads enabled.
.PP
A condition variable is used as a signaling mechanism:
a thread can lock a mutex and then wait on a condition variable
@@ -174,40 +163,33 @@ The caller of \fBTcl_ConditionWait\fR should be prepared for spurious
notifications by calling \fBTcl_ConditionWait\fR within a while loop
that tests some invariant.
.PP
-.VS
A condition variable can be destroyed after its use by calling
\fBTcl_ConditionFinalize\fR.
.PP
The \fBTcl_ConditionNotify\fR, \fBTcl_ConditionWait\fR and
\fBTcl_ConditionFinalize\fR procedures are defined as empty macros if
not compiling with threads enabled.
-.VE
-.PP
-The \fBTcl_GetThreadData\fR call returns a pointer to a block of
-thread-private data. Its argument is a key that is shared by all threads
-and a size for the block of storage. The storage is automatically
-allocated and initialized to all zeros the first time each thread asks for it.
-The storage is automatically deallocated by \fBTcl_FinalizeThread\fR.
-.SH INITIALIZATION
+.SS INITIALIZATION
.PP
-All of these synchronization objects are self initializing.
+All of these synchronization objects are self-initializing.
They are implemented as opaque pointers that should be NULL
upon first use.
The mutexes and condition variables are
-.VS
either cleaned up by process exit handlers (if living that long) or
explicitly by calls to \fBTcl_MutexFinalize\fR or
\fBTcl_ConditionFinalize\fR.
-.VE
Thread local storage is reclaimed during \fBTcl_FinalizeThread\fR.
-.SH "CREATING THREADS"
-The API to create threads is not finalized at this time.
-There are private facilities to create threads that contain a new
-Tcl interpreter, and to send scripts among threads.
-Dive into tclThreadTest.c and tclThread.c for examples.
+.SH "SCRIPT-LEVEL ACCESS TO THREADS"
+.VS 8.5
+Tcl provides no built-in commands for scripts to use to create,
+manage, or join threads, nor any script-level access to mutex or
+condition variables. It provides such facilities only via C
+interfaces, and leaves it up to packages to expose these matters to
+the script level. One such package is the \fBThread\fR package.
+.VE 8.5
.SH "SEE ALSO"
-Tcl_GetCurrentThread, Tcl_ThreadQueueEvent, Tcl_ThreadAlert,
-Tcl_ExitThread, Tcl_FinalizeThread,
-Tcl_CreateThreadExitHandler, Tcl_DeleteThreadExitHandler
+Tcl_GetCurrentThread(3), Tcl_ThreadQueueEvent(3), Tcl_ThreadAlert(3),
+Tcl_ExitThread(3), Tcl_FinalizeThread(3), Tcl_CreateThreadExitHandler(3),
+Tcl_DeleteThreadExitHandler(3), Thread
.SH KEYWORDS
thread, mutex, condition variable, thread local storage
diff --git a/doc/ToUpper.3 b/doc/ToUpper.3
index ece0fb2..d6b3006 100644
--- a/doc/ToUpper.3
+++ b/doc/ToUpper.3
@@ -8,7 +8,7 @@
.TH Tcl_UtfToUpper 3 "8.1" Tcl "Tcl Library Procedures"
.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.
+Tcl_UniCharToUpper, Tcl_UniCharToLower, Tcl_UniCharToTitle, Tcl_UtfToUpper, Tcl_UtfToLower, Tcl_UtfToTitle \- routines for manipulating the case of Unicode characters and UTF-8 strings
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
diff --git a/doc/TraceCmd.3 b/doc/TraceCmd.3
index 5c84249..020f1ca 100644
--- a/doc/TraceCmd.3
+++ b/doc/TraceCmd.3
@@ -25,10 +25,11 @@ void
.AS Tcl_CommandTraceProc prevClientData
.AP Tcl_Interp *interp in
Interpreter containing the command.
-.AP "CONST char" *cmdName in
+.AP "const char" *cmdName in
Name of command.
.AP int flags in
-OR-ed collection of the value TCL_TRACE_RENAME and TCL_TRACE_DELETE.
+OR'ed collection of the values \fBTCL_TRACE_RENAME\fR and
+\fBTCL_TRACE_DELETE\fR.
.AP Tcl_CommandTraceProc *proc in
Procedure to call when specified operations occur to \fIcmdName\fR.
.AP ClientData clientData in
@@ -38,19 +39,18 @@ If non-NULL, gives last value returned by \fBTcl_CommandTraceInfo\fR,
so this call will return information about next trace. If NULL, this
call will return information about first trace.
.BE
-
.SH DESCRIPTION
.PP
\fBTcl_TraceCommand\fR allows a C procedure to monitor operations
performed on a Tcl command, so that the C procedure is invoked
whenever the command is renamed or deleted. If the trace is created
-successfully then \fBTcl_TraceCommand\fR returns TCL_OK. If an error
+successfully then \fBTcl_TraceCommand\fR returns \fBTCL_OK\fR. If an error
occurred (e.g. \fIcmdName\fR specifies a non-existent command) then
-TCL_ERROR is returned and an error message is left in the
+\fBTCL_ERROR\fR is returned and an error message is left in the
interpreter's result.
.PP
The \fIflags\fR argument to \fBTcl_TraceCommand\fR indicates when the
-trace procedure is to be invoked. It consists of an OR-ed combination
+trace procedure is to be invoked. It consists of an OR'ed combination
of any of the following values:
.TP
\fBTCL_TRACE_RENAME\fR
@@ -64,10 +64,10 @@ Whenever one of the specified operations occurs to the command,
match the type \fBTcl_CommandTraceProc\fR:
.CS
typedef void Tcl_CommandTraceProc(
- ClientData \fIclientData\fR,
+ ClientData \fIclientData\fR,
Tcl_Interp *\fIinterp\fR,
- CONST char *\fIoldName\fR,
- CONST char *\fInewName\fR,
+ const char *\fIoldName\fR,
+ const char *\fInewName\fR,
int \fIflags\fR);
.CE
The \fIclientData\fR and \fIinterp\fR parameters will have the same
@@ -77,17 +77,17 @@ data structure that describes what to do when \fIproc\fR is invoked.
\fIOldName\fR gives the name of the command being renamed, and
\fInewName\fR gives the name that the command is being renamed to (or
an empty string or NULL when the command is being deleted.)
-\fIFlags\fR is an OR-ed combination of bits potentially providing
-several pieces of information. One of the bits TCL_TRACE_RENAME and
-TCL_TRACE_DELETE will be set in \fIflags\fR to indicate which
+\fIFlags\fR is an OR'ed combination of bits potentially providing
+several pieces of information. One of the bits \fBTCL_TRACE_RENAME\fR and
+\fBTCL_TRACE_DELETE\fR will be set in \fIflags\fR to indicate which
operation is being performed on the command. The bit
-TCL_TRACE_DESTROYED will be set in \fIflags\fR if the trace is about
+\fBTCL_TRACE_DESTROYED\fR will be set in \fIflags\fR if the trace is about
to be destroyed; this information may be useful to \fIproc\fR so that
it can clean up its own internal data structures (see the section
-TCL_TRACE_DESTROYED below for more details). Lastly, the bit
-TCL_INTERP_DESTROYED will be set if the entire interpreter is being
+\fBTCL_TRACE_DESTROYED\fR below for more details). Lastly, the bit
+\fBTCL_INTERP_DESTROYED\fR will be set if the entire interpreter is being
destroyed. When this bit is set, \fIproc\fR must be especially
-careful in the things it does (see the section TCL_INTERP_DESTROYED
+careful in the things it does (see the section \fBTCL_INTERP_DESTROYED\fR
below).
.PP
\fBTcl_UntraceCommand\fR may be used to remove a trace. If the
@@ -109,7 +109,7 @@ argument.
If the \fIprevClientData\fR argument is NULL then the return
value corresponds to the first (most recently created) matching
trace, or NULL if there are no matching traces.
-If the \fIprevClientData\fR argument isn't NULL, then it should
+If the \fIprevClientData\fR argument is not NULL, then it should
be the return value from a previous call to \fBTcl_CommandTraceInfo\fR.
In this case, the new return value will correspond to the next
matching trace after the one whose \fIclientData\fR matches
@@ -117,15 +117,13 @@ matching trace after the one whose \fIclientData\fR matches
or if there are no more matching traces after it.
This mechanism makes it possible to step through all of the
traces for a given command that have the same \fIproc\fR.
-
.SH "CALLING COMMANDS DURING TRACES"
.PP
During rename traces, the command being renamed is visible with both
names simultaneously, and the command still exists during delete
-traces (if TCL_INTERP_DESTROYED is not set). However, there is no
+traces (if \fBTCL_INTERP_DESTROYED\fR is not set). However, there is no
mechanism for signaling that an error occurred in a trace procedure,
so great care should be taken that errors do not get silently lost.
-
.SH "MULTIPLE TRACES"
.PP
It is possible for multiple traces to exist on the same command.
@@ -137,32 +135,27 @@ If the command being renamed is renamed by one of its rename traces,
that renaming takes precedence over the one that triggered the trace
and the collection of traces will not be reexecuted; if several traces
rename the command, the last renaming takes precedence.
-
.SH "TCL_TRACE_DESTROYED FLAG"
.PP
-In a delete callback to \fIproc\fR, the TCL_TRACE_DESTROYED bit
+In a delete callback to \fIproc\fR, the \fBTCL_TRACE_DESTROYED\fR bit
is set in \fIflags\fR.
-
-'\" Perhaps need some more comments here? - DKF
-
+.\" Perhaps need some more comments here? - DKF
.SH "TCL_INTERP_DESTROYED"
.PP
When an interpreter is destroyed, unset traces are called for
all of its commands.
-The TCL_INTERP_DESTROYED bit will be set in the \fIflags\fR
+The \fBTCL_INTERP_DESTROYED\fR bit will be set in the \fIflags\fR
argument passed to the trace procedures.
Trace procedures must be extremely careful in what they do if
-the TCL_INTERP_DESTROYED bit is set.
+the \fBTCL_INTERP_DESTROYED\fR bit is set.
It is not safe for the procedures to invoke any Tcl procedures
on the interpreter, since its state is partially deleted.
All that trace procedures should do under these circumstances is
to clean up and free their own internal data structures.
-
.SH BUGS
.PP
-Tcl doesn't do any error checking to prevent trace procedures
-from misusing the interpreter during traces with TCL_INTERP_DESTROYED
+Tcl does not do any error checking to prevent trace procedures
+from misusing the interpreter during traces with \fBTCL_INTERP_DESTROYED\fR
set.
-
.SH KEYWORDS
clientData, trace, command
diff --git a/doc/TraceVar.3 b/doc/TraceVar.3
index 98b242e..f80d86f 100644
--- a/doc/TraceVar.3
+++ b/doc/TraceVar.3
@@ -33,23 +33,24 @@ ClientData
.AS Tcl_VarTraceProc prevClientData
.AP Tcl_Interp *interp in
Interpreter containing variable.
-.AP "CONST char" *varName in
+.AP "const char" *varName in
Name of variable. May refer to a scalar variable, to
an array variable with no index, or to an array variable
with a parenthesized index.
.AP int flags in
-OR-ed combination of the values TCL_TRACE_READS, TCL_TRACE_WRITES,
-TCL_TRACE_UNSETS, TCL_TRACE_ARRAY, TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
-TCL_TRACE_RESULT_DYNAMIC and TCL_TRACE_RESULT_OBJECT.
+OR-ed combination of the values \fBTCL_TRACE_READS\fR,
+\fBTCL_TRACE_WRITES\fR, \fBTCL_TRACE_UNSETS\fR, \fBTCL_TRACE_ARRAY\fR,
+\fBTCL_GLOBAL_ONLY\fR, \fBTCL_NAMESPACE_ONLY\fR,
+\fBTCL_TRACE_RESULT_DYNAMIC\fR and \fBTCL_TRACE_RESULT_OBJECT\fR.
Not all flags are used by all
procedures. See below for more information.
.AP Tcl_VarTraceProc *proc in
Procedure to invoke whenever one of the traced operations occurs.
.AP ClientData clientData in
Arbitrary one-word value to pass to \fIproc\fR.
-.AP "CONST char" *name1 in
+.AP "const char" *name1 in
Name of scalar or array variable (without array index).
-.AP "CONST char" *name2 in
+.AP "const char" *name2 in
For a trace on an element of an array, gives the index of the
element. For traces on scalar variables or on whole arrays,
is NULL.
@@ -59,15 +60,14 @@ If non-NULL, gives last value returned by \fBTcl_VarTraceInfo\fR or
next trace. If NULL, this call will return information about first
trace.
.BE
-
.SH DESCRIPTION
.PP
\fBTcl_TraceVar\fR allows a C procedure to monitor and control
access to a Tcl variable, so that the C procedure is invoked
whenever the variable is read or written or unset.
If the trace is created successfully then \fBTcl_TraceVar\fR returns
-TCL_OK. If an error occurred (e.g. \fIvarName\fR specifies an element
-of an array, but the actual variable isn't an array) then TCL_ERROR
+\fBTCL_OK\fR. If an error occurred (e.g. \fIvarName\fR specifies an element
+of an array, but the actual variable is not an array) then \fBTCL_ERROR\fR
is returned and an error message is left in the interpreter's result.
.PP
The \fIflags\fR argument to \fBTcl_TraceVar\fR indicates when the
@@ -103,21 +103,19 @@ Invoke \fIproc\fR whenever the array command is invoked.
This gives the trace procedure a chance to update the array before
array names or array get is called. Note that this is called
before an array set, but that will trigger write traces.
-.VS 8.4
.TP
\fBTCL_TRACE_RESULT_DYNAMIC\fR
The result of invoking the \fIproc\fR is a dynamically allocated
string that will be released by the Tcl library via a call to
\fBckfree\fR. Must not be specified at the same time as
-TCL_TRACE_RESULT_OBJECT.
+\fBTCL_TRACE_RESULT_OBJECT\fR.
.TP
\fBTCL_TRACE_RESULT_OBJECT\fR
The result of invoking the \fIproc\fR is a Tcl_Obj* (cast to a char*)
with a reference count of at least one. The ownership of that
reference will be transferred to the Tcl core for release (when the
core has finished with it) via a call to \fBTcl_DecrRefCount\fR. Must
-not be specified at the same time as TCL_TRACE_RESULT_DYNAMIC.
-.VE 8.4
+not be specified at the same time as \fBTCL_TRACE_RESULT_DYNAMIC\fR.
.PP
Whenever one of the specified operations occurs on the variable,
\fIproc\fR will be invoked.
@@ -125,11 +123,11 @@ It should have arguments and result that match the type
\fBTcl_VarTraceProc\fR:
.CS
typedef char *Tcl_VarTraceProc(
- ClientData \fIclientData\fR,
- Tcl_Interp *\fIinterp\fR,
- char *\fIname1\fR,
- char *\fIname2\fR,
- int \fIflags\fR);
+ ClientData \fIclientData\fR,
+ Tcl_Interp *\fIinterp\fR,
+ char *\fIname1\fR,
+ char *\fIname2\fR,
+ int \fIflags\fR);
.CE
The \fIclientData\fR and \fIinterp\fR parameters will
have the same values as those passed to \fBTcl_TraceVar\fR when the
@@ -142,30 +140,30 @@ in the normal two-part form (see the description of \fBTcl_TraceVar2\fR
below for details).
\fIFlags\fR is an OR-ed combination of bits providing several
pieces of information.
-One of the bits TCL_TRACE_READS, TCL_TRACE_WRITES, TCL_TRACE_ARRAY,
-or TCL_TRACE_UNSETS
+One of the bits \fBTCL_TRACE_READS\fR, \fBTCL_TRACE_WRITES\fR,
+\fBTCL_TRACE_ARRAY\fR, or \fBTCL_TRACE_UNSETS\fR
will be set in \fIflags\fR to indicate which operation is being performed
on the variable.
-The bit TCL_GLOBAL_ONLY will be set whenever the variable being
+The bit \fBTCL_GLOBAL_ONLY\fR will be set whenever the variable being
accessed is a global one not accessible from the current level of
procedure call: the trace procedure will need to pass this flag
back to variable-related procedures like \fBTcl_GetVar\fR if it
attempts to access the variable.
-The bit TCL_NAMESPACE_ONLY will be set whenever the variable being
+The bit \fBTCL_NAMESPACE_ONLY\fR will be set whenever the variable being
accessed is a namespace one not accessible from the current level of
procedure call: the trace procedure will need to pass this flag
back to variable-related procedures like \fBTcl_GetVar\fR if it
attempts to access the variable.
-The bit TCL_TRACE_DESTROYED will be set in \fIflags\fR if the trace is
+The bit \fBTCL_TRACE_DESTROYED\fR will be set in \fIflags\fR if the trace is
about to be destroyed; this information may be useful to \fIproc\fR
so that it can clean up its own internal data structures (see
-the section TCL_TRACE_DESTROYED below for more details).
-Lastly, the bit TCL_INTERP_DESTROYED will be set if the entire
+the section \fBTCL_TRACE_DESTROYED\fR below for more details).
+Lastly, the bit \fBTCL_INTERP_DESTROYED\fR will be set if the entire
interpreter is being destroyed.
When this bit is set, \fIproc\fR must be especially careful in
-the things it does (see the section TCL_INTERP_DESTROYED below).
+the things it does (see the section \fBTCL_INTERP_DESTROYED\fR below).
The trace procedure's return value should normally be NULL; see
-ERROR RETURNS below for information on other possibilities.
+\fBERROR RETURNS\fR below for information on other possibilities.
.PP
\fBTcl_UntraceVar\fR may be used to remove a trace.
If the variable specified by \fIinterp\fR, \fIvarName\fR, and \fIflags\fR
@@ -180,14 +178,14 @@ traces set on a given variable.
The return value from \fBTcl_VarTraceInfo\fR is the \fIclientData\fR
associated with a particular trace.
The trace must be on the variable specified by the \fIinterp\fR,
-\fIvarName\fR, and \fIflags\fR arguments (only the TCL_GLOBAL_ONLY and
-TCL_NAMESPACE_ONLY bits from \fIflags\fR is used; other bits are
+\fIvarName\fR, and \fIflags\fR arguments (only the \fBTCL_GLOBAL_ONLY\fR and
+\fBTCL_NAMESPACE_ONLY\fR bits from \fIflags\fR is used; other bits are
ignored) and its trace procedure must the same as the \fIproc\fR
argument.
If the \fIprevClientData\fR argument is NULL then the return
value corresponds to the first (most recently created) matching
trace, or NULL if there are no matching traces.
-If the \fIprevClientData\fR argument isn't NULL, then it should
+If the \fIprevClientData\fR argument is not NULL, then it should
be the return value from a previous call to \fBTcl_VarTraceInfo\fR.
In this case, the new return value will correspond to the next
matching trace after the one whose \fIclientData\fR matches
@@ -195,7 +193,6 @@ matching trace after the one whose \fIclientData\fR matches
or if there are no more matching traces after it.
This mechanism makes it possible to step through all of the
traces for a given variable that have the same \fIproc\fR.
-
.SH "TWO-PART NAMES"
.PP
The procedures \fBTcl_TraceVar2\fR, \fBTcl_UntraceVar2\fR, and
@@ -204,7 +201,6 @@ The procedures \fBTcl_TraceVar2\fR, \fBTcl_UntraceVar2\fR, and
except that the name of the variable consists of two parts.
\fIName1\fR gives the name of a scalar variable or array,
and \fIname2\fR gives the name of an element within an array.
-.VS 8.1
When \fIname2\fR is NULL,
\fIname1\fR may contain both an array and an element name:
if the name contains an open parenthesis and ends with a
@@ -213,14 +209,10 @@ treated as an element name (which can have any string value) and
the characters before the first open
parenthesis are treated as the name of an array variable.
If \fIname2\fR is NULL and \fIname1\fR does not refer
-to an array element
-.VE
-it means that either the variable is
+to an array element it means that either the variable is
a scalar or the trace is to be set on the entire array rather
than an individual element (see WHOLE-ARRAY TRACES below for
more information).
-
-
.SH "ACCESSING VARIABLES DURING TRACES"
.PP
During read, write, and array traces, the
@@ -246,7 +238,6 @@ from the variable before any trace procedures are invoked.
If new traces are set by unset trace procedures, these traces
will be invoked on accesses to the variable by the trace
procedures.
-
.SH "CALLBACK TIMING"
.PP
When read tracing has been specified for a variable, the trace
@@ -286,7 +277,6 @@ When unset tracing has been specified, the trace procedure
will be invoked whenever the variable is destroyed.
The traces will be called after the variable has been
completely unset.
-
.SH "WHOLE-ARRAY TRACES"
.PP
If a call to \fBTcl_TraceVar\fR or \fBTcl_TraceVar2\fR specifies
@@ -299,7 +289,6 @@ When an array is unset, a whole-array trace will be invoked
just once, with \fIname1\fR equal to the name of the array
and \fIname2\fR NULL; it will not be invoked once for each
element.
-
.SH "MULTIPLE TRACES"
.PP
It is possible for multiple traces to exist on the same variable.
@@ -311,7 +300,6 @@ before the individual-element traces.
If a read or write trace unsets the variable then all of the unset
traces will be invoked but the remainder of the read and write traces
will be skipped.
-
.SH "ERROR RETURNS"
.PP
Under normal conditions trace procedures should return NULL, indicating
@@ -320,13 +308,11 @@ If \fIproc\fR returns a non-NULL value it signifies that an
error occurred.
The return value must be a pointer to a static character string
containing an error message,
-.VS 8.4
-unless (\fIexactly\fR one of) the TCL_TRACE_RESULT_DYNAMIC and
-TCL_TRACE_RESULT_OBJECT flags is set, which specify that the result is
+unless (\fIexactly\fR one of) the \fBTCL_TRACE_RESULT_DYNAMIC\fR and
+\fBTCL_TRACE_RESULT_OBJECT\fR flags is set, which specify that the result is
either a dynamic string (to be released with \fBckfree\fR) or a
Tcl_Obj* (cast to char* and to be released with
\fBTcl_DecrRefCount\fR) containing the error message.
-.VE 8.4
If a trace procedure returns an error, no further traces are
invoked for the access and the traced access aborts with the
given message.
@@ -340,56 +326,51 @@ The return value from \fIproc\fR is only used during read and
write tracing.
During unset traces, the return value is ignored and all relevant
trace procedures will always be invoked.
-
.SH "RESTRICTIONS"
.PP
A trace procedure can be called at any time, even when there
-is a partially-formed result in the interpreter's result area. If
+is a partially formed result in the interpreter's result area. If
the trace procedure does anything that could damage this result (such
as calling \fBTcl_Eval\fR) then it must save the original values of
the interpreter's \fBresult\fR and \fBfreeProc\fR fields and restore
them before it returns.
-
.SH "UNDEFINED VARIABLES"
.PP
It is legal to set a trace on an undefined variable.
The variable will still appear to be undefined until the
first time its value is set.
If an undefined variable is traced and then unset, the unset will fail
-with an error (``no such variable''), but the trace
-procedure will still be invoked.
-
+with an error
+.PQ "no such variable" "" ,
+but the trace procedure will still be invoked.
.SH "TCL_TRACE_DESTROYED FLAG"
.PP
-In an unset callback to \fIproc\fR, the TCL_TRACE_DESTROYED bit
+In an unset callback to \fIproc\fR, the \fBTCL_TRACE_DESTROYED\fR bit
is set in \fIflags\fR if the trace is being removed as part
of the deletion.
Traces on a variable are always removed whenever the variable
-is deleted; the only time TCL_TRACE_DESTROYED isn't set is for
+is deleted; the only time \fBTCL_TRACE_DESTROYED\fR is not set is for
a whole-array trace invoked when only a single element of an
array is unset.
-
.SH "TCL_INTERP_DESTROYED"
.PP
When an interpreter is destroyed, unset traces are called for
all of its variables.
-The TCL_INTERP_DESTROYED bit will be set in the \fIflags\fR
+The \fBTCL_INTERP_DESTROYED\fR bit will be set in the \fIflags\fR
argument passed to the trace procedures.
Trace procedures must be extremely careful in what they do if
-the TCL_INTERP_DESTROYED bit is set.
+the \fBTCL_INTERP_DESTROYED\fR bit is set.
It is not safe for the procedures to invoke any Tcl procedures
on the interpreter, since its state is partially deleted.
All that trace procedures should do under these circumstances is
to clean up and free their own internal data structures.
-
.SH BUGS
.PP
-Tcl doesn't do any error checking to prevent trace procedures
-from misusing the interpreter during traces with TCL_INTERP_DESTROYED
+Tcl does not do any error checking to prevent trace procedures
+from misusing the interpreter during traces with \fBTCL_INTERP_DESTROYED\fR
set.
.PP
-Array traces are not yet integrated with the Tcl "info exists" command,
+Array traces are not yet integrated with the Tcl \fBinfo exists\fR command,
nor is there Tcl-level access to array traces.
-
.SH KEYWORDS
clientData, trace, variable
diff --git a/doc/Translate.3 b/doc/Translate.3
index 59a64ea..d434cda 100644
--- a/doc/Translate.3
+++ b/doc/Translate.3
@@ -17,11 +17,12 @@ Tcl_TranslateFileName \- convert file name to native form and replace tilde with
char *
\fBTcl_TranslateFileName\fR(\fIinterp\fR, \fIname\fR, \fIbufferPtr\fR)
.SH ARGUMENTS
-.AS Tcl_DString *bufferPtr
+.AS Tcl_DString *bufferPtr in/out
.AP Tcl_Interp *interp in
Interpreter in which to report an error, if any.
-.AP "CONST char" *name in
-File name, which may start with a ``~''.
+.AP "const char" *name in
+File name, which may start with a
+.QW ~ .
.AP Tcl_DString *bufferPtr in/out
If needed, this dynamic string is used to store the new file name.
At the time of the call it should be uninitialized or free. The
@@ -31,9 +32,18 @@ anything stored here.
.SH DESCRIPTION
.PP
-This utility procedure translates a file name to a form suitable for
-passing to the local operating system. It converts network names into
-native form and does tilde substitution.
+This utility procedure translates a file name to a platform-specific form
+which, after being converted to the appropriate encoding, is suitable for
+passing to the local operating system. In particular, it converts
+network names into native form and does tilde substitution.
+.PP
+However, with the advent of the newer \fBTcl_FSGetNormalizedPath\fR and
+\fBTcl_GetNativePath\fR, there is no longer any need to use this
+procedure. In particular, \fBTcl_GetNativePath\fR performs all the
+necessary translation and encoding conversion, is virtual-filesystem
+aware, and caches the native result for faster repeated calls.
+Finally \fBTcl_GetNativePath\fR does not require you to free anything
+afterwards.
.PP
If
\fBTcl_TranslateFileName\fR has to do tilde substitution or translate
@@ -44,7 +54,7 @@ After \fBTcl_TranslateFileName\fR returns a non-NULL result, the caller must
eventually invoke \fBTcl_DStringFree\fR to free any information
placed in \fI*bufferPtr\fR. The caller need not know whether or
not \fBTcl_TranslateFileName\fR actually used the string; \fBTcl_TranslateFileName\fR
-initializes \fI*bufferPtr\fR even if it doesn't use it, so the call to
+initializes \fI*bufferPtr\fR even if it does not use it, so the call to
\fBTcl_DStringFree\fR will be safe in either case.
.PP
If an error occurs (e.g. because there was no user by the given
diff --git a/doc/UniCharIsAlpha.3 b/doc/UniCharIsAlpha.3
index 22b81c1..6029b2d 100644
--- a/doc/UniCharIsAlpha.3
+++ b/doc/UniCharIsAlpha.3
@@ -46,6 +46,7 @@ int
int
\fBTcl_UniCharIsWordChar\fR(\fIch\fR)
.SH ARGUMENTS
+.AS int ch
.AP int ch in
The Tcl_UniChar to be examined.
.BE
@@ -61,7 +62,7 @@ with the various routines.
Note: A Tcl_UniChar is a Unicode character represented as an unsigned,
fixed-size quantity.
-.SH CHARACTER CLASSES
+.SH "CHARACTER CLASSES"
.PP
\fBTcl_UniCharIsAlnum\fR tests if the character is an alphanumeric Unicode character.
.PP
diff --git a/doc/UpVar.3 b/doc/UpVar.3
index 95c4a9a..f1e6fe4 100644
--- a/doc/UpVar.3
+++ b/doc/UpVar.3
@@ -20,30 +20,31 @@ int
int
\fBTcl_UpVar2(\fIinterp, frameName, name1, name2, destName, flags\fB)\fR
.SH ARGUMENTS
-.AS Tcl_VarTraceProc prevClientData
+.AS "const char" *sourceName
.AP Tcl_Interp *interp in
Interpreter containing variables; also used for error reporting.
-.AP "CONST char" *frameName in
+.AP "const char" *frameName in
Identifies the stack frame containing source variable.
May have any of the forms accepted by
the \fBupvar\fR command, such as \fB#0\fR or \fB1\fR.
-.AP "CONST char" *sourceName in
+.AP "const char" *sourceName in
Name of source variable, in the frame given by \fIframeName\fR.
May refer to a scalar variable or to an array variable with a
parenthesized index.
-.AP "CONST char" *destName in
+.AP "const char" *destName in
Name of destination variable, which is to be linked to source
variable so that references to \fIdestName\fR
refer to the other variable. Must not currently exist except as
an upvar-ed variable.
.AP int flags in
-Either TCL_GLOBAL_ONLY or 0; if non-zero, then \fIdestName\fR is
-a global variable; otherwise it is a local to the current procedure
-(or global if no procedure is active).
-.AP "CONST char" *name1 in
+One of \fBTCL_GLOBAL_ONLY\fR, \fBTCL_NAMESPACE_ONLY\fR or 0; if non-zero,
+then \fIdestName\fR is a global or namespace variable; otherwise it is
+local to the current procedure (or current namespace if no procedure is
+active).
+.AP "const char" *name1 in
First part of source variable's name (scalar name, or name of array
without array index).
-.AP "CONST char" *name2 in
+.AP "const char" *name2 in
If source variable is an element of an array, gives the index of the element.
For scalar source variables, is NULL.
.BE
@@ -61,7 +62,7 @@ element name (by calling \fBTcl_UpVar2\fR).
The destination variable name is specified in a single string; it
may not be an array element.
.PP
-Both procedures return either TCL_OK or TCL_ERROR, and they
+Both procedures return either \fBTCL_OK\fR or \fBTCL_ERROR\fR, and they
leave an error message in the interpreter's result if an error occurs.
.PP
As with the \fBupvar\fR command, the source variable need not exist;
diff --git a/doc/Utf.3 b/doc/Utf.3
index af472ae..8e39fef 100644
--- a/doc/Utf.3
+++ b/doc/Utf.3
@@ -8,7 +8,7 @@
.TH Utf 3 "8.1" Tcl "Tcl Library Procedures"
.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.
+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
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
@@ -20,91 +20,91 @@ int
.sp
int
\fBTcl_UtfToUniChar\fR(\fIsrc, chPtr\fR)
-.VS 8.4
.sp
char *
-\fBTcl_UniCharToUtfDString\fR(\fIuniStr, numChars, dstPtr\fR)
+\fBTcl_UniCharToUtfDString\fR(\fIuniStr, uniLength, dsPtr\fR)
.sp
Tcl_UniChar *
-\fBTcl_UtfToUniCharDString\fR(\fIsrc, len, dstPtr\fR)
-.VE 8.4
+\fBTcl_UtfToUniCharDString\fR(\fIsrc, length, dsPtr\fR)
.sp
int
\fBTcl_UniCharLen\fR(\fIuniStr\fR)
.sp
int
-\fBTcl_UniCharNcmp\fR(\fIuniStr, uniStr, num\fR)
-.VS 8.4
+\fBTcl_UniCharNcmp\fR(\fIucs, uct, numChars\fR)
.sp
int
-\fBTcl_UniCharNcasecmp\fR(\fIuniStr, uniStr, num\fR)
+\fBTcl_UniCharNcasecmp\fR(\fIucs, uct, numChars\fR)
.sp
int
\fBTcl_UniCharCaseMatch\fR(\fIuniStr, uniPattern, nocase\fR)
-.VE 8.4
.sp
int
-\fBTcl_UtfNcmp\fR(\fIsrc, src, num\fR)
+\fBTcl_UtfNcmp\fR(\fIcs, ct, numChars\fR)
.sp
int
-\fBTcl_UtfNcasecmp\fR(\fIsrc, src, num\fR)
+\fBTcl_UtfNcasecmp\fR(\fIcs, ct, numChars\fR)
.sp
int
-\fBTcl_UtfCharComplete\fR(\fIsrc, len\fR)
+\fBTcl_UtfCharComplete\fR(\fIsrc, length\fR)
.sp
int
-\fBTcl_NumUtfChars\fR(\fIsrc, len\fR)
-.VS 8.4
+\fBTcl_NumUtfChars\fR(\fIsrc, length\fR)
.sp
-CONST char *
+const char *
\fBTcl_UtfFindFirst\fR(\fIsrc, ch\fR)
.sp
-CONST char *
+const char *
\fBTcl_UtfFindLast\fR(\fIsrc, ch\fR)
.sp
-CONST char *
+const char *
\fBTcl_UtfNext\fR(\fIsrc\fR)
.sp
-CONST char *
+const char *
\fBTcl_UtfPrev\fR(\fIsrc, start\fR)
-.VE 8.4
.sp
Tcl_UniChar
\fBTcl_UniCharAtIndex\fR(\fIsrc, index\fR)
-.VS 8.4
.sp
-CONST char *
+const char *
\fBTcl_UtfAtIndex\fR(\fIsrc, index\fR)
-.VE 8.4
.sp
int
\fBTcl_UtfBackslash\fR(\fIsrc, readPtr, dst\fR)
.SH ARGUMENTS
-.AS "CONST Tcl_UniChar" numChars in/out
+.AS "const Tcl_UniChar" *uniPattern in/out
.AP char *buf out
Buffer in which the UTF-8 representation of the Tcl_UniChar is stored. At most
-TCL_UTF_MAX bytes are stored in the buffer.
+\fBTCL_UTF_MAX\fR bytes are stored in the buffer.
.AP int ch in
The Tcl_UniChar to be converted or examined.
.AP Tcl_UniChar *chPtr out
Filled with the Tcl_UniChar represented by the head of the UTF-8 string.
-.AP "CONST char" *src in
+.AP "const char" *src in
Pointer to a UTF-8 string.
-.AP "CONST Tcl_UniChar" *uniStr in
+.AP "const char" *cs in
+Pointer to a UTF-8 string.
+.AP "const char" *ct in
+Pointer to a UTF-8 string.
+.AP "const Tcl_UniChar" *uniStr in
+A null-terminated Unicode string.
+.AP "const Tcl_UniChar" *ucs in
+A null-terminated Unicode string.
+.AP "const Tcl_UniChar" *uct in
A null-terminated Unicode string.
-.AP "CONST Tcl_UniChar" *uniPattern in
+.AP "const Tcl_UniChar" *uniPattern in
A null-terminated Unicode string.
-.AP int len in
+.AP int length in
The length of the UTF-8 string in bytes (not UTF-8 characters). If
negative, all bytes up to the first null byte are used.
-.AP int numChars in
+.AP int uniLength in
The length of the Unicode string in characters. Must be greater than or
equal to 0.
-.AP "Tcl_DString" *dstPtr in/out
-A pointer to a previously-initialized \fBTcl_DString\fR.
-.AP "unsigned long" num in
+.AP "Tcl_DString" *dsPtr in/out
+A pointer to a previously initialized \fBTcl_DString\fR.
+.AP "unsigned long" numChars in
The number of characters to compare.
-.AP "CONST char" *start in
+.AP "const char" *start in
Pointer to the beginning of a UTF-8 string.
.AP int index in
The index of a character (not byte) in the UTF-8 string.
@@ -113,12 +113,10 @@ If non-NULL, filled with the number of bytes in the backslash sequence,
including the backslash character.
.AP char *dst out
Buffer in which the bytes represented by the backslash sequence are stored.
-At most TCL_UTF_MAX bytes are stored in the buffer.
-.VS 8.4
+At most \fBTCL_UTF_MAX\fR bytes are stored in the buffer.
.AP int nocase in
Specifies whether the match should be done case-sensitive (0) or
case-insensitive (1).
-.VE 8.4
.BE
.SH DESCRIPTION
@@ -126,7 +124,7 @@ case-insensitive (1).
These routines convert between UTF-8 strings and Tcl_UniChars. A
Tcl_UniChar is a Unicode character represented as an unsigned, fixed-size
quantity. A UTF-8 character is a Unicode character represented as
-a varying-length sequence of up to TCL_UTF_MAX bytes. A multibyte UTF-8
+a varying-length sequence of up to \fBTCL_UTF_MAX\fR bytes. A multibyte UTF-8
sequence consists of a lead byte followed by some number of trail bytes.
.PP
\fBTCL_UTF_MAX\fR is the maximum number of bytes that it takes to
@@ -138,7 +136,7 @@ in \fIbuf\fR.
.PP
\fBTcl_UtfToUniChar\fR reads one UTF-8 character starting at \fIsrc\fR
and stores it as a Tcl_UniChar in \fI*chPtr\fR. The return value is the
-number of bytes read from \fIsrc\fR.. The caller must ensure that the
+number of bytes read from \fIsrc\fR. The caller must ensure that the
source buffer is long enough such that this routine does not run off the
end and dereference non-existent or random memory; if the source buffer
is known to be null-terminated, this will not happen. If the input is
@@ -147,15 +145,17 @@ byte of \fIsrc\fR in \fI*chPtr\fR as a Tcl_UniChar between 0x0000 and
0x00ff and return 1.
.PP
\fBTcl_UniCharToUtfDString\fR converts the given Unicode string
-to UTF-8, storing the result in a previously-initialized \fBTcl_DString\fR.
-You must specify the length of the given Unicode string.
+to UTF-8, storing the result in a previously initialized \fBTcl_DString\fR.
+You must specify \fIuniLength\fR, the length of the given Unicode string.
The return value is a pointer to the UTF-8 representation of the
Unicode string. Storage for the return value is appended to the
end of the \fBTcl_DString\fR.
.PP
\fBTcl_UtfToUniCharDString\fR converts the given UTF-8 string to Unicode,
-storing the result in the previously-initialized \fBTcl_DString\fR.
-you may either specify the length of the given UTF-8 string or "-1",
+storing the result in the previously initialized \fBTcl_DString\fR.
+In the argument \fIlength\fR, you may either specify the length of
+the given UTF-8 string in bytes or
+.QW \-1 ,
in which case \fBTcl_UtfToUniCharDString\fR uses \fBstrlen\fR to
calculate the length. The return value is a pointer to the Unicode
representation of the UTF-8 string. Storage for the return value
@@ -168,24 +168,22 @@ the number of Unicode characters (not bytes) in that string.
.PP
\fBTcl_UniCharNcmp\fR and \fBTcl_UniCharNcasecmp\fR correspond to
\fBstrncmp\fR and \fBstrncasecmp\fR, respectively, for Unicode characters.
-They accepts two null-terminated Unicode strings and the number of characters
-to compare. Both strings are assumed to be at least \fIlen\fR characters
+They accept two null-terminated Unicode strings and the number of characters
+to compare. Both strings are assumed to be at least \fInumChars\fR characters
long. \fBTcl_UniCharNcmp\fR compares the two strings character-by-character
according to the Unicode character ordering. It returns an integer greater
than, equal to, or less than 0 if the first string is greater than, equal
to, or less than the second string respectively. \fBTcl_UniCharNcasecmp\fR
is the Unicode case insensitive version.
.PP
-.VS 8.4
\fBTcl_UniCharCaseMatch\fR is the Unicode equivalent to
\fBTcl_StringCaseMatch\fR. It accepts a null-terminated Unicode string,
a Unicode pattern, and a boolean value specifying whether the match should
be case sensitive and returns whether the string matches the pattern.
-.VE 8.4
.PP
\fBTcl_UtfNcmp\fR corresponds to \fBstrncmp\fR for UTF-8 strings. It
accepts two null-terminated UTF-8 strings and the number of characters
-to compare. (Both strings are assumed to be at least \fIlen\fR
+to compare. (Both strings are assumed to be at least \fInumChars\fR
characters long.) \fBTcl_UtfNcmp\fR compares the two strings
character-by-character according to the Unicode character ordering.
It returns an integer greater than, equal to, or less than 0 if the
@@ -198,7 +196,7 @@ differences in case when comparing upper, lower or title case
characters.
.PP
\fBTcl_UtfCharComplete\fR returns 1 if the source UTF-8 string \fIsrc\fR
-of length \fIlen\fR bytes is long enough to be decoded by
+of \fIlength\fR bytes is long enough to be decoded by
\fBTcl_UtfToUniChar\fR, or 0 otherwise. This function does not guarantee
that the UTF-8 string is properly formed. This routine is used by
procedures that are operating on a byte at a time and need to know if a
@@ -206,7 +204,7 @@ full Tcl_UniChar has been seen.
.PP
\fBTcl_NumUtfChars\fR corresponds to \fBstrlen\fR for UTF-8 strings. It
returns the number of Tcl_UniChars that are represented by the UTF-8 string
-\fIsrc\fR. The length of the source string is \fIlen\fR bytes. If the
+\fIsrc\fR. The length of the source string is \fIlength\fR bytes. If the
length is negative, all bytes up to the first null byte are used.
.PP
\fBTcl_UtfFindFirst\fR corresponds to \fBstrchr\fR for UTF-8 strings. It
@@ -248,7 +246,7 @@ the return pointer points to the first character in the source string.
\fBTcl_UtfBackslash\fR is a utility procedure used by several of the Tcl
commands. It parses a backslash sequence and stores the properly formed
UTF-8 character represented by the backslash sequence in the output
-buffer \fIdst\fR. At most TCL_UTF_MAX bytes are stored in the buffer.
+buffer \fIdst\fR. At most \fBTCL_UTF_MAX\fR bytes are stored in the buffer.
\fBTcl_UtfBackslash\fR modifies \fI*readPtr\fR to contain the number
of bytes in the backslash sequence, including the backslash character.
The return value is the number of bytes stored in the output buffer.
diff --git a/doc/WrongNumArgs.3 b/doc/WrongNumArgs.3
index 00aa653..2175858 100644
--- a/doc/WrongNumArgs.3
+++ b/doc/WrongNumArgs.3
@@ -15,16 +15,16 @@ Tcl_WrongNumArgs \- generate standard error message for wrong number of argument
.sp
\fBTcl_WrongNumArgs\fR(\fIinterp, objc, objv, message\fR)
.SH ARGUMENTS
-.AS Tcl_Interp "*CONST objv[]"
+.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.
.AP int objc in
Number of leading arguments from \fIobjv\fR to include in error
message.
-.AP Tcl_Obj "*CONST\ objv[]" in
+.AP "Tcl_Obj *const" objv[] in
Arguments to command that had the wrong number of arguments.
-.AP "CONST char" *message in
+.AP "const char" *message in
Additional error information to print after leading arguments
from \fIobjv\fR. This typically gives the acceptable syntax
of the command. This argument may be NULL.
@@ -39,7 +39,8 @@ standard error message and stores it in the result object 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 ``\fBfileName count\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
string:
.CS
@@ -61,7 +62,7 @@ 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, lets assume that
+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
\fBTcl_GetIndexFromObj\fR. In this case the error message would be:
diff --git a/doc/after.n b/doc/after.n
index dbe0783..21961d3 100644
--- a/doc/after.n
+++ b/doc/after.n
@@ -46,8 +46,9 @@ The delayed command is formed by concatenating all the \fIscript\fR
arguments in the same fashion as the \fBconcat\fR command.
The command will be executed at global level (outside the context
of any Tcl procedure).
-If an error occurs while executing the delayed command then the
-\fBbgerror\fR mechanism is used to report the error.
+If an error occurs while executing the delayed command then
+the background error will be reported by the command
+registered with \fB interp bgerror\fR.
The \fBafter\fR command returns an identifier that can be used
to cancel the delayed command using \fBafter cancel\fR.
.TP
@@ -76,7 +77,8 @@ loop is entered and there are no events to process.
The command returns an identifier that can be used
to cancel the delayed command using \fBafter cancel\fR.
If an error occurs while executing the script then the
-\fBbgerror\fR mechanism is used to report the error.
+background error will be reported by the command
+registered with \fB interp bgerror\fR.
.TP
\fBafter info \fR?\fIid\fR?
This command returns information about existing event handlers.
@@ -134,7 +136,7 @@ doOneStep
.CE
.SH "SEE ALSO"
-bgerror(n), concat(n), update(n), vwait(n)
+concat(n), interp(n), update(n), vwait(n)
.SH KEYWORDS
cancel, delay, idle callback, sleep, time
diff --git a/doc/append.n b/doc/append.n
index 1ff43ee..dc9adbe 100644
--- a/doc/append.n
+++ b/doc/append.n
@@ -18,15 +18,18 @@ append \- Append to variable
.SH DESCRIPTION
.PP
Append all of the \fIvalue\fR arguments to the current value
-of variable \fIvarName\fR. If \fIvarName\fR doesn't exist,
+of variable \fIvarName\fR. If \fIvarName\fR does not exist,
it is given a value equal to the concatenation of all the
\fIvalue\fR arguments.
The result of this command is the new value stored in variable
\fIvarName\fR.
This command provides an efficient way to build up long
variables incrementally.
-For example, ``\fBappend a $b\fR'' is much more efficient than
-``\fBset a $a$b\fR'' if \fB$a\fR is long.
+For example,
+.QW "\fBappend a $b\fR"
+is much more efficient than
+.QW "\fBset a $a$b\fR"
+if \fB$a\fR is long.
.SH EXAMPLE
Building a string of comma-separated numbers piecemeal using a loop.
.CS
diff --git a/doc/apply.n b/doc/apply.n
new file mode 100644
index 0000000..8a38aac
--- /dev/null
+++ b/doc/apply.n
@@ -0,0 +1,96 @@
+'\"
+'\" Copyright (c) 2006 Miguel Sofer
+'\" Copyright (c) 2006 Donal K. Fellows
+'\"
+.so man.macros
+.TH apply n "" Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+apply \- Apply an anonymous function
+.SH SYNOPSIS
+\fBapply \fIfunc\fR ?\fIarg1 arg2 ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The command \fBapply\fR applies the function \fIfunc\fR to the arguments
+\fIarg1 arg2 ...\fR and returns the result.
+.PP
+The function \fIfunc\fR is a two element list \fI{args body}\fR or a three
+element list \fI{args body namespace}\fR (as if the
+\fBlist\fR command had been used).
+The first element \fIargs\fR specifies the formal arguments to
+\fIfunc\fR. The specification of the formal arguments \fIargs\fR
+is shared with the \fBproc\fR command, and is described in detail in the
+corresponding manual page.
+.PP
+The contents of \fIbody\fR are executed by the Tcl interpreter
+after the local variables corresponding to the formal arguments are given
+the values of the actual parameters \fIarg1 arg2 ...\fR.
+When \fIbody\fR is being executed, variable names normally refer to
+local variables, which are created automatically when referenced and
+deleted when \fBapply\fR returns. One local variable is automatically
+created for each of the function's arguments.
+Global variables can only be accessed by invoking
+the \fBglobal\fR command or the \fBupvar\fR command.
+Namespace variables can only be accessed by invoking
+the \fBvariable\fR command or the \fBupvar\fR command.
+.PP
+The invocation of \fBapply\fR adds a call frame to Tcl's evaluation stack
+(the stack of frames accessed via \fBuplevel\fR). The execution of \fIbody\fR
+proceeds in this call frame, in the namespace given by \fInamespace\fR or
+in the global namespace if none was specified. If given, \fInamespace\fR is
+interpreted relative to the global namespace even if its name does not start
+with
+.QW :: .
+.PP
+The semantics of \fBapply\fR can also be described by:
+.PP
+.CS
+proc apply {fun args} {
+ set len [llength $fun]
+ if {($len < 2) || ($len > 3)} {
+ error "can't interpret \e"$fun\e" as anonymous function"
+ }
+ lassign $fun argList body ns
+ set name ::$ns::[getGloballyUniqueName]
+ set body0 {
+ rename [lindex [info level 0] 0] {}
+ }
+ proc $name $argList ${body0}$body
+ set code [catch {uplevel 1 $name $args} res opt]
+ return -options $opt $res
+}
+.CE
+.SH EXAMPLES
+This shows how to make a simple general command that applies a transformation
+to each element of a list.
+.CS
+proc map {lambda list} {
+ set result {}
+ foreach item $list {
+ lappend result [\fBapply\fR $lambda $item]
+ }
+ return $result
+}
+map {x {return [string length $x]:$x}} {a bb ccc dddd}
+ \fI\(-> 1:a 2:bb 3:ccc 4:dddd\fR
+map {x {expr {$x**2 + 3*$x - 2}}} {-4 -3 -2 -1 0 1 2 3 4}
+ \fI\(-> 2 -2 -4 -4 -2 2 8 16 26\fR
+.CE
+.PP
+The \fBapply\fR command is also useful for defining callbacks for use in the
+\fBtrace\fR command:
+.CS
+set vbl "123abc"
+trace add variable vbl write {\fBapply\fR {{v1 v2 op} {
+ upvar 1 $v1 v
+ puts "updated variable to \e"$v\e""
+}}}
+set vbl 123
+set vbl abc
+.CE
+.SH "SEE ALSO"
+proc(n), uplevel(n)
+.SH KEYWORDS
+argument, procedure, anonymous function
diff --git a/doc/array.n b/doc/array.n
index 7713f8c..e112c23 100644
--- a/doc/array.n
+++ b/doc/array.n
@@ -14,7 +14,6 @@ array \- Manipulate array variables
.SH SYNOPSIS
\fBarray \fIoption arrayName\fR ?\fIarg arg ...\fR?
.BE
-
.SH DESCRIPTION
.PP
This command performs one of several operations on the
@@ -34,7 +33,7 @@ check, and must have been the return value from a previous
invocation of \fBarray startsearch\fR.
This option is particularly useful if an array has an element
with an empty name, since the return value from
-\fBarray nextelement\fR won't indicate whether the search
+\fBarray nextelement\fR will not indicate whether the search
has been completed.
.TP
\fBarray donesearch \fIarrayName searchId\fR
@@ -58,21 +57,24 @@ array are included in the result.
If \fIpattern\fR is specified, then only those elements whose names
match \fIpattern\fR (using the matching rules of
\fBstring match\fR) are included.
-If \fIarrayName\fR isn't the name of an array variable, or if
+If \fIarrayName\fR is not the name of an array variable, or if
the array contains no elements, then an empty list is returned.
+If traces on the array modify the list of elements, the elements
+returned are those that exist both before and after the call to
+\fBarray get\fR.
.TP
\fBarray names \fIarrayName\fR ?\fImode\fR? ?\fIpattern\fR?
Returns a list containing the names of all of the elements in
the array that match \fIpattern\fR. \fIMode\fR may be one of
-\fB-exact\fR, \fB-glob\fR, or \fB-regexp\fR. If specified, \fImode\fR
+\fB\-exact\fR, \fB\-glob\fR, or \fB\-regexp\fR. If specified, \fImode\fR
designates which matching rules to use to match \fIpattern\fR against
the names of the elements in the array. If not specified, \fImode\fR
-defaults to \fB-glob\fR. See the documentation for \fBstring match\fR
+defaults to \fB\-glob\fR. See the documentation for \fBstring match\fR
for information on glob style matching, and the documentation for
\fBregexp\fR for information on regexp matching.
If \fIpattern\fR is omitted then the command returns all of
the element names in the array. If there are no (matching) elements
-in the array, or if \fIarrayName\fR isn't the name of an array
+in the array, or if \fIarrayName\fR is not the name of an array
variable, then an empty string is returned.
.TP
\fBarray nextelement \fIarrayName searchId\fR
@@ -100,7 +102,7 @@ and \fIlist\fR is empty,
\fBarray size \fIarrayName\fR
Returns a decimal string giving the number of elements in the
array.
-If \fIarrayName\fR isn't the name of an array then 0 is returned.
+If \fIarrayName\fR is not the name of an array then 0 is returned.
.TP
\fBarray startsearch \fIarrayName\fR
This command initializes an element-by-element search through the
@@ -117,59 +119,55 @@ It is currently more efficient and easier to use either the \fBarray
get\fR or \fBarray names\fR, together with \fBforeach\fR, to iterate
over all but very large arrays. See the examples below for how to do
this.
-.VS 8.4
.TP
\fBarray statistics \fIarrayName\fR
Returns statistics about the distribution of data within the hashtable
that represents the array. This information includes the number of
entries in the table, the number of buckets, and the utilization of
the buckets.
-.VE 8.4
-.VS 8.3
.TP
\fBarray unset \fIarrayName\fR ?\fIpattern\fR?
Unsets all of the elements in the array that match \fIpattern\fR (using the
-matching rules of \fBstring match\fR). If \fIarrayName\fR isn't the name
+matching rules of \fBstring match\fR). If \fIarrayName\fR is not the name
of an array variable or there are no matching elements in the array, no
error will be raised. If \fIpattern\fR is omitted and \fIarrayName\fR is
an array variable, then the command unsets the entire array.
The command always returns an empty string.
-.VE 8.3
.SH EXAMPLES
.CS
\fBarray set\fR colorcount {
- red 1
- green 5
- blue 4
- white 9
+ red 1
+ green 5
+ blue 4
+ white 9
}
foreach {color count} [\fBarray get\fR colorcount] {
- puts "Color: $color Count: $count"
+ puts "Color: $color Count: $count"
}
- => Color: blue Count: 4
+ \fB\(->\fR Color: blue Count: 4
Color: white Count: 9
Color: green Count: 5
Color: red Count: 1
foreach color [\fBarray names\fR colorcount] {
- puts "Color: $color Count: $colorcount($color)"
+ puts "Color: $color Count: $colorcount($color)"
}
- => Color: blue Count: 4
+ \fB\(->\fR Color: blue Count: 4
Color: white Count: 9
Color: green Count: 5
Color: red Count: 1
-foreach color [lsort [array names colorcount]] {
- puts "Color: $color Count: $colorcount($color)"
+foreach color [lsort [\fBarray names\fR colorcount]] {
+ puts "Color: $color Count: $colorcount($color)"
}
- => Color: blue Count: 4
+ \fB\(->\fR Color: blue Count: 4
Color: green Count: 5
Color: red Count: 1
Color: white Count: 9
\fBarray statistics\fR colorcount
- => 4 entries in table, 4 buckets
+ \fB\(->\fR 4 entries in table, 4 buckets
number of buckets with 0 entries: 1
number of buckets with 1 entries: 2
number of buckets with 2 entries: 1
@@ -183,9 +181,7 @@ foreach color [lsort [array names colorcount]] {
number of buckets with 10 or more entries: 0
average search distance for entry: 1.2
.CE
-
.SH "SEE ALSO"
list(n), string(n), variable(n), trace(n), foreach(n)
-
.SH KEYWORDS
array, element names, search
diff --git a/doc/bgerror.n b/doc/bgerror.n
index 5b42766..cb91351 100644
--- a/doc/bgerror.n
+++ b/doc/bgerror.n
@@ -16,14 +16,27 @@ bgerror \- Command invoked to process background errors
.BE
.SH DESCRIPTION
+.VS 8.5
+Release 8.5 of Tcl supports the \fBinterp bgerror\fR command,
+which allows applications to register in an interpreter the command
+that will handle background errors in that interpreter. In older
+releases of Tcl, this level of control was not available, and applications
+could control the handling of background errors only by creating
+a command with the particular command name \fBbgerror\fR in the
+global namespace of an interpreter. The following documentation
+describes the interface requirements of the \fBbgerror\fR command
+an application might define to retain compatibility with pre-8.5
+releases of Tcl. Applications intending to support only
+Tcl releases 8.5 and later should simply make use of \fBinterp bgerror\fR.
+.VE 8.5
.PP
-The \fBbgerror\fR command doesn't exist as built-in part of Tcl. Instead,
+The \fBbgerror\fR command does not exist as built-in part of Tcl. Instead,
individual applications or users can define a \fBbgerror\fR
command (e.g. as a Tcl procedure) if they wish to handle background
errors.
.PP
A background error is one that occurs in an event handler or some
-other command that didn't originate with the application.
+other command that did not originate with the application.
For example, if an error occurs while executing a command specified
with the \fBafter\fR command, then it is a background error.
For a non-background error, the error can simply be returned up
@@ -34,8 +47,10 @@ unwinding ends in the Tcl library and there is no obvious way for Tcl
to report the error.
.PP
When Tcl detects a background error, it saves information about the
-error and invokes the \fBbgerror\fR command later as an idle event
-handler. Before invoking \fBbgerror\fR, Tcl restores the
+error and invokes a handler command registered by \fBinterp bgerror\fR
+later as an idle event handler. The default handler command in turn
+calls the \fBbgerror\fR command .
+Before invoking \fBbgerror\fR, Tcl restores the
\fBerrorInfo\fR and \fBerrorCode\fR variables to their values at the
time the error occurred, then it invokes \fBbgerror\fR with the error
message as its only argument. Tcl assumes that the application has
@@ -54,22 +69,6 @@ error, in the order they occurred. However, if \fBbgerror\fR returns
with a break exception, then any remaining errors are skipped without
calling \fBbgerror\fR.
.PP
-Tcl has no default implementation for \fBbgerror\fR. However, in
-applications using Tk there is a default \fBbgerror\fR procedure which
-posts a dialog box containing the error message and offers the user a
-chance to see a stack trace showing where the error occurred. In
-addition to allowing the user to view the stack trace, the dialog
-provides an additional application configurable button which may be
-used, for example, to save the stack trace to a file. By default,
-this is the behavior associated with that button. This behavior can
-be redefined by setting the option database values
-\fB*ErrorDialog.function.text\fR, to specify the caption for the
-function button, and \fB*ErrorDialog.function.command\fR, to specify
-the command to be run. The text of the stack trace is appended to the
-command when it is evaluated. If either of these options is set to
-the empty string, then the additional button will not be displayed in
-the dialog.
-.PP
If you are writing code that will be used by others as part of a
package or other kind of library, consider avoiding \fBbgerror\fR.
The reason for this is that the application programmer may also want
@@ -87,7 +86,7 @@ proc bgerror {message} {
.CE
.SH "SEE ALSO"
-after(n), tclvars(n)
+after(n), interp(n), tclvars(n)
.SH KEYWORDS
background error, reporting
diff --git a/doc/binary.n b/doc/binary.n
index fbe1a8c..6b2150e 100644
--- a/doc/binary.n
+++ b/doc/binary.n
@@ -15,17 +15,15 @@ binary \- Insert and extract fields from binary strings
.br
\fBbinary scan \fIstring formatString \fR?\fIvarName varName ...\fR?
.BE
-
.SH DESCRIPTION
.PP
This command provides facilities for manipulating binary data. The
first form, \fBbinary format\fR, creates a binary string from normal
-Tcl values. For example, given the values 16 and 22, on a 32 bit
+Tcl values. For example, given the values 16 and 22, on a 32-bit
architecture, it might produce an 8-byte binary string consisting of
two 4-byte integers, one for each of the numbers. The second form of
the command, \fBbinary scan\fR, does the opposite: it extracts data
from a binary string and returns it as ordinary Tcl string values.
-
.SH "BINARY FORMAT"
.PP
The \fBbinary format\fR command generates a binary string whose layout
@@ -34,7 +32,8 @@ the additional arguments. The resulting binary value is returned.
.PP
The \fIformatString\fR consists of a sequence of zero or more field
specifiers separated by zero or more spaces. Each field specifier is
-a single type character followed by an optional numeric \fIcount\fR.
+a single type character followed by an optional flag character followed
+by an optional numeric \fIcount\fR.
Most field specifiers consume one argument to obtain the value to be
formatted. The type character specifies how the value is to be
formatted. The \fIcount\fR typically indicates how many items of the
@@ -42,12 +41,13 @@ specified type are taken from the value. If present, the \fIcount\fR
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.
+that consume arguments, then an error is generated. The flag character
+is ignored for for \fBbinary format\fR.
.PP
Here is a small example to clarify the relation between the field
specifiers and the arguments:
.CS
-\fBbinary format d3d {1.0 2.0 3.0 4.0} 0.1\fR
+\fBbinary format\fR d3d {1.0 2.0 3.0 4.0} 0.1
.CE
.PP
The first argument is a list of four numbers, but because of the count
@@ -62,13 +62,14 @@ to just after the last byte stored. The cursor is initially at
position 0 at the beginning of the data. The type may be any one of
the following characters:
.IP \fBa\fR 5
-Stores a character string of length \fIcount\fR in the output string.
+Stores a byte string of length \fIcount\fR in the output string.
Every character is taken as modulo 256 (i.e. the low byte of every
character is used, and the high byte discarded) so when storing
-character strings not wholly expressible using the characters \\u0000-\\u00ff,
-the \fBencoding convertto\fR command should be used
-first if this truncation is not desired (i.e. if the characters are
-not part of the ISO 8859-1 character set.)
+character strings not wholly expressible using the characters \eu0000-\eu00ff,
+the \fBencoding convertto\fR command should be used first to change
+the string into an external representation
+if this truncation is not desired (i.e. if the characters are
+not part of the ISO 8859\-1 character set.)
If \fIarg\fR has fewer than \fIcount\fR bytes, then additional zero
bytes are used to pad out the field. If \fIarg\fR is longer than the
specified length, the extra characters will be ignored. If
@@ -77,16 +78,33 @@ formatted. If \fIcount\fR is omitted, then one character will be
formatted. For example,
.RS
.CS
-\fBbinary format a7a*a alpha bravo charlie\fR
+\fBbinary format\fR a7a*a alpha bravo charlie
.CE
-will return a string equivalent to \fBalpha\\000\\000bravoc\fR.
+will return a string equivalent to \fBalpha\e000\e000bravoc\fR,
+.CS
+\fBbinary format\fR a* [encoding convertto utf-8 \eu20ac]
+.CE
+will return a string equivalent to \fB\e342\e202\e254\fR (which is the
+UTF-8 byte sequence for a Euro-currency character) and
+.CS
+\fBbinary format\fR a* [encoding convertto iso8859-15 \eu20ac]
+.CE
+will return a string equivalent to \fB\e244\fR (which is the ISO
+8859\-15 byte sequence for a Euro-currency character). Contrast these
+last two with:
+.CS
+\fBbinary format\fR a* \eu20ac
+.CE
+which returns a string equivalent to \fB\e254\fR (i.e. \fB\exac\fR) by
+truncating the high-bits of the character, and which is probably not
+what is desired.
.RE
.IP \fBA\fR 5
This form is the same as \fBa\fR except that spaces are used for
padding instead of nulls. For example,
.RS
.CS
-\fBbinary format A6A*A alpha bravo charlie\fR
+\fBbinary format\fR A6A*A alpha bravo charlie
.CE
will return \fBalpha bravoc\fR.
.RE
@@ -105,25 +123,26 @@ does not end at a byte boundary, the remaining bits of the last byte
will be zeros. For example,
.RS
.CS
-\fBbinary format b5b* 11100 111000011010\fR
+\fBbinary format\fR b5b* 11100 111000011010
.CE
-will return a string equivalent to \fB\\x07\\x87\\x05\fR.
+will return a string equivalent to \fB\ex07\ex87\ex05\fR.
.RE
.IP \fBB\fR 5
This form is the same as \fBb\fR except that the bits are stored in
high-to-low order within each byte. For example,
.RS
.CS
-\fBbinary format B5B* 11100 111000011010\fR
+\fBbinary format\fR B5B* 11100 111000011010
.CE
-will return a string equivalent to \fB\\xe0\\xe1\\xa0\fR.
+will return a string equivalent to \fB\exe0\exe1\exa0\fR.
.RE
-.IP \fBh\fR 5
-Stores a string of \fIcount\fR hexadecimal digits in low-to-high
+.IP \fBH\fR 5
+Stores a string of \fIcount\fR hexadecimal digits in high-to-low
within each byte in the output string. \fIArg\fR must contain a
-sequence of characters in the set ``0123456789abcdefABCDEF''. The
-resulting bytes are emitted in first to last order with the hex digits
-being formatted in low-to-high order within each byte. If \fIarg\fR
+sequence of characters in the set
+.QW 0123456789abcdefABCDEF .
+The resulting bytes are emitted in first to last order with the hex digits
+being formatted in high-to-low order within each byte. If \fIarg\fR
has fewer than \fIcount\fR digits, then zeros will be used for the
remaining digits. If \fIarg\fR has more than the specified number of
digits, the extra digits will be ignored. If \fIcount\fR is
@@ -133,37 +152,36 @@ number of digits formatted does not end at a byte boundary, the
remaining bits of the last byte will be zeros. For example,
.RS
.CS
-\fBbinary format h3h* AB def\fR
+\fBbinary format\fR H3H*H2 ab DEF 987
.CE
-will return a string equivalent to \fB\\xba\\x00\\xed\\x0f\fR.
+will return a string equivalent to \fB\exab\ex00\exde\exf0\ex98\fR.
.RE
-.IP \fBH\fR 5
-This form is the same as \fBh\fR except that the digits are stored in
-high-to-low order within each byte. For example,
+.IP \fBh\fR 5
+This form is the same as \fBH\fR except that the digits are stored in
+low-to-high order within each byte. This is seldom required. For example,
.RS
.CS
-\fBbinary format H3H* ab DEF\fR
+\fBbinary format\fR h3h*h2 AB def 987
.CE
-will return a string equivalent to \fB\\xab\\x00\\xde\\xf0\fR.
+will return a string equivalent to \fB\exba\ex00\exed\ex0f\ex89\fR.
.RE
.IP \fBc\fR 5
Stores one or more 8-bit integer values in the output string. If no
\fIcount\fR is specified, then \fIarg\fR must consist of an integer
-value; otherwise \fIarg\fR must consist of a list containing at least
-\fIcount\fR integer elements. The low-order 8 bits of each integer
+value. If \fIcount\fR is specified, \fIarg\fR must consist of a list
+containing at least that many integers. The low-order 8 bits of each integer
are stored as a one-byte value at the cursor position. If \fIcount\fR
-is \fB*\fR, then all of the integers in the list are formatted. If
-the number of elements in the list is fewer than \fIcount\fR, then an
-error is generated. If the number of elements in the list is greater
+is \fB*\fR, then all of the integers in the list are formatted. If the
+number of elements in the list is greater
than \fIcount\fR, then the extra elements are ignored. For example,
.RS
.CS
-\fBbinary format c3cc* {3 -3 128 1} 260 {2 5}\fR
+\fBbinary format\fR c3cc* {3 -3 128 1} 260 {2 5}
.CE
will return a string equivalent to
-\fB\\x03\\xfd\\x80\\x04\\x02\\x05\fR, whereas
+\fB\ex03\exfd\ex80\ex04\ex02\ex05\fR, whereas
.CS
-\fBbinary format c {2 5}\fR
+\fBbinary format\fR c {2 5}
.CE
will generate an error.
.RE
@@ -175,10 +193,10 @@ the cursor position with the least significant byte stored first. For
example,
.RS
.CS
-\fBbinary format s3 {3 -3 258 1}\fR
+\fBbinary format\fR s3 {3 -3 258 1}
.CE
will return a string equivalent to
-\fB\\x03\\x00\\xfd\\xff\\x02\\x01\fR.
+\fB\ex03\ex00\exfd\exff\ex02\ex01\fR.
.RE
.IP \fBS\fR 5
This form is the same as \fBs\fR except that it stores one or more
@@ -186,11 +204,19 @@ This form is the same as \fBs\fR except that it stores one or more
example,
.RS
.CS
-\fBbinary format S3 {3 -3 258 1}\fR
+\fBbinary format\fR S3 {3 -3 258 1}
.CE
will return a string equivalent to
-\fB\\x00\\x03\\xff\\xfd\\x01\\x02\fR.
-.RE
+\fB\ex00\ex03\exff\exfd\ex01\ex02\fR.
+.RE
+.IP \fBt\fR 5
+.VS 8.5
+This form (mnemonically \fItiny\fR) is the same as \fBs\fR and \fBS\fR
+except that it stores the 16-bit integers in the output string in the
+native byte order of the machine where the Tcl script is running.
+To determine what the native byte order of the machine is, refer to
+the \fBbyteOrder\fR element of the \fBtcl_platform\fR array.
+.VE 8.5
.IP \fBi\fR 5
This form is the same as \fBc\fR except that it stores one or more
32-bit integers in little-endian byte order in the output string. The
@@ -199,10 +225,10 @@ the cursor position with the least significant byte stored first. For
example,
.RS
.CS
-\fBbinary format i3 {3 -3 65536 1}\fR
+\fBbinary format\fR i3 {3 -3 65536 1}
.CE
will return a string equivalent to
-\fB\\x03\\x00\\x00\\x00\\xfd\\xff\\xff\\xff\\x00\\x00\\x01\\x00\fR
+\fB\ex03\ex00\ex00\ex00\exfd\exff\exff\exff\ex00\ex00\ex01\ex00\fR
.RE
.IP \fBI\fR 5
This form is the same as \fBi\fR except that it stores one or more one
@@ -210,13 +236,21 @@ or more 32-bit integers in big-endian byte order in the output string.
For example,
.RS
.CS
-\fBbinary format I3 {3 -3 65536 1}\fR
+\fBbinary format\fR I3 {3 -3 65536 1}
.CE
will return a string equivalent to
-\fB\\x00\\x00\\x00\\x03\\xff\\xff\\xff\\xfd\\x00\\x01\\x00\\x00\fR
-.RE
+\fB\ex00\ex00\ex00\ex03\exff\exff\exff\exfd\ex00\ex01\ex00\ex00\fR
+.RE
+.IP \fBn\fR 5
+.VS 8.5
+This form (mnemonically \fInumber\fR or \fInormal\fR) is the same as
+\fBi\fR and \fBI\fR except that it stores the 32-bit integers in the
+output string in the native byte order of the machine where the Tcl
+script is running.
+To determine what the native byte order of the machine is, refer to
+the \fBbyteOrder\fR element of the \fBtcl_platform\fR array.
+.VE 8.5
.IP \fBw\fR 5
-.VS 8.4
This form is the same as \fBc\fR except that it stores one or more
64-bit integers in little-endian byte order in the output string. The
low-order 64-bits of each integer are stored as an eight-byte value at
@@ -224,7 +258,7 @@ the cursor position with the least significant byte stored first. For
example,
.RS
.CS
-\fBbinary format w 7810179016327718216\fR
+\fBbinary format\fR w 7810179016327718216
.CE
will return the string \fBHelloTcl\fR
.RE
@@ -234,14 +268,22 @@ or more 64-bit integers in big-endian byte order in the output string.
For example,
.RS
.CS
-\fBbinary format Wc 4785469626960341345 110\fR
+\fBbinary format\fR Wc 4785469626960341345 110
.CE
will return the string \fBBigEndian\fR
-.VE
.RE
+.IP \fBm\fR 5
+.VS 8.5
+This form (mnemonically the mirror of \fBw\fR) is the same as \fBw\fR
+and \fBW\fR except that it stores the 64-bit integers in the output
+string in the native byte order of the machine where the Tcl script is
+running.
+To determine what the native byte order of the machine is, refer to
+the \fBbyteOrder\fR element of the \fBtcl_platform\fR array.
+.VE 8.5
.IP \fBf\fR 5
This form is the same as \fBc\fR except that it stores one or more one
-or more single-precision floating in the machine's native
+or more single-precision floating point numbers in the machine's native
representation in the output string. This representation is not
portable across architectures, so it should not be used to communicate
floating point numbers across the network. The size of a floating
@@ -249,28 +291,54 @@ point number may vary across architectures, so the number of bytes
that are generated may vary. If the value overflows the
machine's native representation, then the value of FLT_MAX
as defined by the system will be used instead. Because Tcl uses
-double-precision floating-point numbers internally, there may be some
+double-precision floating point numbers internally, there may be some
loss of precision in the conversion to single-precision. For example,
on a Windows system running on an Intel Pentium processor,
.RS
.CS
-\fBbinary format f2 {1.6 3.4}\fR
+\fBbinary format\fR f2 {1.6 3.4}
.CE
will return a string equivalent to
-\fB\\xcd\\xcc\\xcc\\x3f\\x9a\\x99\\x59\\x40\fR.
-.RE
+\fB\excd\excc\excc\ex3f\ex9a\ex99\ex59\ex40\fR.
+.RE
+.IP \fBr\fR 5
+.VS 8.5
+This form (mnemonically \fIreal\fR) is the same as \fBf\fR except that
+it stores the single-precision floating point numbers in little-endian
+order. This conversion only produces meaningful output when used on
+machines which use the IEEE floating point representation (very
+common, but not universal.)
+.VE 8.5
+.IP \fBR\fR 5
+.VS 8.5
+This form is the same as \fBr\fR except that it stores the
+single-precision floating point numbers in big-endian order.
+.VE 8.5
.IP \fBd\fR 5
This form is the same as \fBf\fR except that it stores one or more one
-or more double-precision floating in the machine's native
+or more double-precision floating point numbers in the machine's native
representation in the output string. For example, on a
Windows system running on an Intel Pentium processor,
.RS
.CS
-\fBbinary format d1 {1.6}\fR
+\fBbinary format\fR d1 {1.6}
.CE
will return a string equivalent to
-\fB\\x9a\\x99\\x99\\x99\\x99\\x99\\xf9\\x3f\fR.
-.RE
+\fB\ex9a\ex99\ex99\ex99\ex99\ex99\exf9\ex3f\fR.
+.RE
+.IP \fBq\fR 5
+.VS 8.5
+This form (mnemonically the mirror of \fBd\fR) is the same as \fBd\fR
+except that it stores the double-precision floating point numbers in
+little-endian order. This conversion only produces meaningful output
+when used on machines which use the IEEE floating point representation
+(very common, but not universal.)
+.VE 8.5
+.IP \fBQ\fR 5
+.VS 8.5
+This form is the same as \fBq\fR except that it stores the
+double-precision floating point numbers in big-endian order.
+.VE 8.5
.IP \fBx\fR 5
Stores \fIcount\fR null bytes in the output string. If \fIcount\fR is
not specified, stores one null byte. If \fIcount\fR is \fB*\fR,
@@ -278,9 +346,9 @@ generates an error. This type does not consume an argument. For
example,
.RS
.CS
-\fBbinary format a3xa3x2a3 abc def ghi\fR
+\fBbinary format\fR a3xa3x2a3 abc def ghi
.CE
-will return a string equivalent to \fBabc\\000def\\000\\000ghi\fR.
+will return a string equivalent to \fBabc\e000def\e000\e000ghi\fR.
.RE
.IP \fBX\fR 5
Moves the cursor back \fIcount\fR bytes in the output string. If
@@ -291,7 +359,7 @@ omitted then the cursor is moved back one byte. This type does not
consume an argument. For example,
.RS
.CS
-\fBbinary format a3X*a3X2a3 abc def ghi\fR
+\fBbinary format\fR a3X*a3X2a3 abc def ghi
.CE
will return \fBdghi\fR.
.RE
@@ -306,16 +374,17 @@ the output string. If \fIcount\fR is omitted, then an error will be
generated. This type does not consume an argument. For example,
.RS
.CS
-\fBbinary format a5@2a1@*a3@10a1 abcde f ghi j\fR
+\fBbinary format\fR a5@2a1@*a3@10a1 abcde f ghi j
.CE
-will return \fBabfdeghi\\000\\000j\fR.
+will return \fBabfdeghi\e000\e000j\fR.
.RE
-
.SH "BINARY SCAN"
.PP
The \fBbinary scan\fR command parses fields from a binary string,
returning the number of conversions performed. \fIString\fR gives the
-input to be parsed and \fIformatString\fR indicates how to parse it.
+input bytes to be parsed (one byte per character, and characters not
+representable as a byte have their high bits chopped)
+and \fIformatString\fR indicates how to parse it.
Each \fIvarName\fR gives the name of a variable; when a field is
scanned from \fIstring\fR the result is assigned to the corresponding
variable.
@@ -323,7 +392,8 @@ variable.
As with \fBbinary format\fR, the \fIformatString\fR consists of a
sequence of zero or more field specifiers separated by zero or more
spaces. Each field specifier is a single type character followed by
-an optional numeric \fIcount\fR. Most field specifiers consume one
+an optional flag character followed by an optional numeric \fIcount\fR.
+Most field specifiers consume one
argument to obtain the variable into which the scanned values should
be placed. The type character specifies how the binary data is to be
interpreted. The \fIcount\fR typically indicates how many items of
@@ -335,13 +405,16 @@ position to satisfy the current field specifier, then the
corresponding variable is left untouched and \fBbinary scan\fR returns
immediately with the number of variables that were set. If there are
not enough arguments for all of the fields in the format string that
-consume arguments, then an error is generated.
+consume arguments, then an error is generated. The flag character
+.QW u
+may be given to cause some types to be read as unsigned values. The flag
+is accepted for all field types but is ignored for non-integer fields.
.PP
A similar example as with \fBbinary format\fR should explain the
relation between field specifiers and arguments in case of the binary
scan subcommand:
.CS
-\fBbinary scan $bytes s3s first second\fR
+\fBbinary scan\fR $bytes s3s first second
.CE
.PP
This command (provided the binary string in the variable \fIbytes\fR
@@ -352,31 +425,33 @@ integers), no assignment to \fIsecond\fR will be made, and if
\fIbytes\fR contains fewer than 6 bytes (i.e. three 2-byte integers),
no assignment to \fIfirst\fR will be made. Hence:
.CS
-\fBputs [binary scan abcdefg s3s first second]\fR
-\fBputs $first\fR
-\fBputs $second\fR
+puts [\fBbinary scan\fR abcdefg s3s first second]
+puts $first
+puts $second
.CE
will print (assuming neither variable is set previously):
.CS
-\fB1\fR
-\fB25185 25699 26213\fR
-\fIcan't read "second": no such variable\fR
+1
+25185 25699 26213
+can't read "second": no such variable
.CE
.PP
-It is \fBimportant\fR to note that the \fBc\fR, \fBs\fR, and \fBS\fR
+It is \fIimportant\fR to note that the \fBc\fR, \fBs\fR, and \fBS\fR
(and \fBi\fR and \fBI\fR on 64bit systems) will be scanned into
long data size values. In doing this, values that have their high
bit set (0x80 for chars, 0x8000 for shorts, 0x80000000 for ints),
will be sign extended. Thus the following will occur:
.CS
-\fBset signShort [binary format s1 0x8000]\fR
-\fBbinary scan $signShort s1 val; \fI# val == 0xFFFF8000\fR
+set signShort [\fBbinary format\fR s1 0x8000]
+\fBbinary scan\fR $signShort s1 val; \fI# val == 0xFFFF8000\fR
.CE
-If you want to produce an unsigned value, then you can mask the return
-value to the desired size. For example, to produce an unsigned short
-value:
+If you require unsigned values you can include the
+.QW u
+flag character following
+the field type. For example, to read an unsigned short value:
.CS
-\fBset val [expr {$val & 0xFFFF}]; \fI# val == 0x8000\fR
+set signShort [\fBbinary format\fR s1 0x8000]
+\fBbinary scan\fR $signShort su1 val; \fI# val == 0x00008000\fR
.CE
.PP
Each type-count pair moves an imaginary cursor through the binary data,
@@ -384,116 +459,128 @@ reading bytes from the current position. The cursor is initially
at position 0 at the beginning of the data. The type may be any one of
the following characters:
.IP \fBa\fR 5
-The data is a character string of length \fIcount\fR. If \fIcount\fR
+The data is a byte string of length \fIcount\fR. If \fIcount\fR
is \fB*\fR, then all of the remaining bytes in \fIstring\fR will be
scanned into the variable. If \fIcount\fR is omitted, then one
-character will be scanned.
-All characters scanned will be interpreted as being in the
-range \\u0000-\\u00ff so the \fBencoding convertfrom\fR command might be
-needed if the string is not an ISO 8859\-1 string.
+byte will be scanned.
+All bytes scanned will be interpreted as being characters in the
+range \eu0000-\eu00ff so the \fBencoding convertfrom\fR command will be
+needed if the string is not a binary string or a string encoded in ISO
+8859\-1.
For example,
.RS
.CS
-\fBbinary scan abcde\\000fghi a6a10 var1 var2\fR
+\fBbinary scan\fR abcde\e000fghi a6a10 var1 var2
+.CE
+will return \fB1\fR with the string equivalent to \fBabcde\e000\fR
+stored in \fIvar1\fR and \fIvar2\fR left unmodified, and
+.CS
+\fBbinary scan\fR \e342\e202\e254 a* var1
+set var2 [encoding convertfrom utf-8 $var1]
.CE
-will return \fB1\fR with the string equivalent to \fBabcde\\000\fR
-stored in \fBvar1\fR and \fBvar2\fR left unmodified.
+will store a Euro-currency character in \fIvar2\fR.
.RE
.IP \fBA\fR 5
This form is the same as \fBa\fR, except trailing blanks and nulls are stripped from
the scanned value before it is stored in the variable. For example,
.RS
.CS
-\fBbinary scan "abc efghi \\000" A* var1\fR
+\fBbinary scan\fR "abc efghi \e000" A* var1
.CE
-will return \fB1\fR with \fBabc efghi\fR stored in \fBvar1\fR.
+will return \fB1\fR with \fBabc efghi\fR stored in \fIvar1\fR.
.RE
.IP \fBb\fR 5
The data is turned into a string of \fIcount\fR binary digits in
-low-to-high order represented as a sequence of ``1'' and ``0''
+low-to-high order represented as a sequence of
+.QW 1
+and
+.QW 0
characters. The data bytes are scanned in first to last order with
the bits being taken in low-to-high order within each byte. Any extra
bits in the last byte are ignored. If \fIcount\fR is \fB*\fR, then
-all of the remaining bits in \fBstring\fR will be scanned. If
+all of the remaining bits in \fIstring\fR will be scanned. If
\fIcount\fR is omitted, then one bit will be scanned. For example,
.RS
.CS
-\fBbinary scan \\x07\\x87\\x05 b5b* var1 var2\fR
+\fBbinary scan\fR \ex07\ex87\ex05 b5b* var1 var2
.CE
-will return \fB2\fR with \fB11100\fR stored in \fBvar1\fR and
-\fB1110000110100000\fR stored in \fBvar2\fR.
+will return \fB2\fR with \fB11100\fR stored in \fIvar1\fR and
+\fB1110000110100000\fR stored in \fIvar2\fR.
.RE
.IP \fBB\fR 5
This form is the same as \fBb\fR, except the bits are taken in
high-to-low order within each byte. For example,
.RS
.CS
-\fBbinary scan \\x70\\x87\\x05 B5B* var1 var2\fR
+\fBbinary scan\fR \ex70\ex87\ex05 B5B* var1 var2
.CE
-will return \fB2\fR with \fB01110\fR stored in \fBvar1\fR and
-\fB1000011100000101\fR stored in \fBvar2\fR.
+will return \fB2\fR with \fB01110\fR stored in \fIvar1\fR and
+\fB1000011100000101\fR stored in \fIvar2\fR.
.RE
-.IP \fBh\fR 5
+.IP \fBH\fR 5
The data is turned into a string of \fIcount\fR hexadecimal digits in
-low-to-high order represented as a sequence of characters in the set
-``0123456789abcdef''. The data bytes are scanned in first to last
-order with the hex digits being taken in low-to-high order within each
-byte. Any extra bits in the last byte are ignored. If \fIcount\fR
-is \fB*\fR, then all of the remaining hex digits in \fBstring\fR will be
-scanned. If \fIcount\fR is omitted, then one hex digit will be
-scanned. For example,
+high-to-low order represented as a sequence of characters in the set
+.QW 0123456789abcdef .
+The data bytes are scanned in first to last
+order with the hex digits being taken in high-to-low order within each
+byte. Any extra bits in the last byte are ignored. If \fIcount\fR is
+\fB*\fR, then all of the remaining hex digits in \fIstring\fR will be
+scanned. If \fIcount\fR is omitted, then one hex digit will be
+scanned. For example,
.RS
.CS
-\fBbinary scan \\x07\\x86\\x05 h3h* var1 var2\fR
+\fBbinary scan\fR \ex07\exC6\ex05\ex1f\ex34 H3H* var1 var2
.CE
-will return \fB2\fR with \fB706\fR stored in \fBvar1\fR and
-\fB50\fR stored in \fBvar2\fR.
+will return \fB2\fR with \fB07c\fR stored in \fIvar1\fR and
+\fB051f34\fR stored in \fIvar2\fR.
.RE
-.IP \fBH\fR 5
-This form is the same as \fBh\fR, except the digits are taken in
-high-to-low order within each byte. For example,
+.IP \fBh\fR 5
+This form is the same as \fBH\fR, except the digits are taken in
+reverse (low-to-high) order within each byte. For example,
.RS
.CS
-\fBbinary scan \\x07\\x86\\x05 H3H* var1 var2\fR
+\fBbinary scan\fR \ex07\ex86\ex05\ex12\ex34 h3h* var1 var2
.CE
-will return \fB2\fR with \fB078\fR stored in \fBvar1\fR and
-\fB05\fR stored in \fBvar2\fR.
+will return \fB2\fR with \fB706\fR stored in \fIvar1\fR and
+\fB502143\fR stored in \fIvar2\fR.
.RE
+Note that most code that wishes to parse the hexadecimal digits from
+multiple bytes in order should use the \fBH\fR format.
.IP \fBc\fR 5
The data is turned into \fIcount\fR 8-bit signed integers and stored
in the corresponding variable as a list. If \fIcount\fR is \fB*\fR,
-then all of the remaining bytes in \fBstring\fR will be scanned. If
+then all of the remaining bytes in \fIstring\fR will be scanned. If
\fIcount\fR is omitted, then one 8-bit integer will be scanned. For
example,
.RS
.CS
-\fBbinary scan \\x07\\x86\\x05 c2c* var1 var2\fR
+\fBbinary scan\fR \ex07\ex86\ex05 c2c* var1 var2
.CE
-will return \fB2\fR with \fB7 -122\fR stored in \fBvar1\fR and \fB5\fR
-stored in \fBvar2\fR. Note that the integers returned are signed, but
+will return \fB2\fR with \fB7 -122\fR stored in \fIvar1\fR and \fB5\fR
+stored in \fIvar2\fR. Note that the integers returned are signed, but
they can be converted to unsigned 8-bit quantities using an expression
like:
.CS
-\fBexpr { $num & 0xff }\fR
+set num [expr { $num & 0xff }]
.CE
.RE
.IP \fBs\fR 5
The data is interpreted as \fIcount\fR 16-bit signed integers
represented in little-endian byte order. The integers are stored in
the corresponding variable as a list. If \fIcount\fR is \fB*\fR, then
-all of the remaining bytes in \fBstring\fR will be scanned. If
+all of the remaining bytes in \fIstring\fR will be scanned. If
\fIcount\fR is omitted, then one 16-bit integer will be scanned. For
example,
.RS
.CS
-\fBbinary scan \\x05\\x00\\x07\\x00\\xf0\\xff s2s* var1 var2\fR
+\fBbinary scan\fR \ex05\ex00\ex07\ex00\exf0\exff s2s* var1 var2
.CE
-will return \fB2\fR with \fB5 7\fR stored in \fBvar1\fR and \fB-16\fR
-stored in \fBvar2\fR. Note that the integers returned are signed, but
+will return \fB2\fR with \fB5 7\fR stored in \fIvar1\fR and \fB\-16\fR
+stored in \fIvar2\fR. Note that the integers returned are signed, but
they can be converted to unsigned 16-bit quantities using an expression
like:
.CS
-\fBexpr { $num & 0xffff }\fR
+set num [expr { $num & 0xffff }]
.CE
.RE
.IP \fBS\fR 5
@@ -502,28 +589,37 @@ as \fIcount\fR 16-bit signed integers represented in big-endian byte
order. For example,
.RS
.CS
-\fBbinary scan \\x00\\x05\\x00\\x07\\xff\\xf0 S2S* var1 var2\fR
+\fBbinary scan\fR \ex00\ex05\ex00\ex07\exff\exf0 S2S* var1 var2
.CE
-will return \fB2\fR with \fB5 7\fR stored in \fBvar1\fR and \fB-16\fR
-stored in \fBvar2\fR.
+will return \fB2\fR with \fB5 7\fR stored in \fIvar1\fR and \fB\-16\fR
+stored in \fIvar2\fR.
.RE
+.IP \fBt\fR 5
+.VS 8.5
+The data is interpreted as \fIcount\fR 16-bit signed integers
+represented in the native byte order of the machine running the Tcl
+script. It is otherwise identical to \fBs\fR and \fBS\fR.
+To determine what the native byte order of the machine is, refer to
+the \fBbyteOrder\fR element of the \fBtcl_platform\fR array.
+.VE 8.5
.IP \fBi\fR 5
The data is interpreted as \fIcount\fR 32-bit signed integers
represented in little-endian byte order. The integers are stored in
the corresponding variable as a list. If \fIcount\fR is \fB*\fR, then
-all of the remaining bytes in \fBstring\fR will be scanned. If
+all of the remaining bytes in \fIstring\fR will be scanned. If
\fIcount\fR is omitted, then one 32-bit integer will be scanned. For
example,
.RS
.CS
-\fBbinary scan \\x05\\x00\\x00\\x00\\x07\\x00\\x00\\x00\\xf0\\xff\\xff\\xff i2i* var1 var2\fR
+set str \ex05\ex00\ex00\ex00\ex07\ex00\ex00\ex00\exf0\exff\exff\exff
+\fBbinary scan\fR $str i2i* var1 var2
.CE
-will return \fB2\fR with \fB5 7\fR stored in \fBvar1\fR and \fB-16\fR
-stored in \fBvar2\fR. Note that the integers returned are signed, but
+will return \fB2\fR with \fB5 7\fR stored in \fIvar1\fR and \fB\-16\fR
+stored in \fIvar2\fR. Note that the integers returned are signed, but
they can be converted to unsigned 32-bit quantities using an expression
like:
.CS
-\fBexpr { $num & 0xffffffff }\fR
+set num [expr { $num & 0xffffffff }]
.CE
.RE
.IP \fBI\fR 5
@@ -532,25 +628,34 @@ as \fIcount\fR 32-bit signed integers represented in big-endian byte
order. For example,
.RS
.CS
-\fBbinary scan \\x00\\x00\\x00\\x05\\x00\\x00\\x00\\x07\\xff\\xff\\xff\\xf0 I2I* var1 var2\fR
+set str \ex00\ex00\ex00\ex05\ex00\ex00\ex00\ex07\exff\exff\exff\exf0
+\fBbinary scan\fR $str I2I* var1 var2
.CE
-will return \fB2\fR with \fB5 7\fR stored in \fBvar1\fR and \fB-16\fR
-stored in \fBvar2\fR.
+will return \fB2\fR with \fB5 7\fR stored in \fIvar1\fR and \fB\-16\fR
+stored in \fIvar2\fR.
.RE
+.IP \fBn\fR 5
+.VS 8.5
+The data is interpreted as \fIcount\fR 32-bit signed integers
+represented in the native byte order of the machine running the Tcl
+script. It is otherwise identical to \fBi\fR and \fBI\fR.
+To determine what the native byte order of the machine is, refer to
+the \fBbyteOrder\fR element of the \fBtcl_platform\fR array.
+.VE 8.5
.IP \fBw\fR 5
-.VS 8.4
The data is interpreted as \fIcount\fR 64-bit signed integers
represented in little-endian byte order. The integers are stored in
the corresponding variable as a list. If \fIcount\fR is \fB*\fR, then
-all of the remaining bytes in \fBstring\fR will be scanned. If
+all of the remaining bytes in \fIstring\fR will be scanned. If
\fIcount\fR is omitted, then one 64-bit integer will be scanned. For
example,
.RS
.CS
-\fBbinary scan \\x05\\x00\\x00\\x00\\x07\\x00\\x00\\x00\\xf0\\xff\\xff\\xff wi* var1 var2\fR
+set str \ex05\ex00\ex00\ex00\ex07\ex00\ex00\ex00\exf0\exff\exff\exff
+\fBbinary scan\fR $str wi* var1 var2
.CE
-will return \fB2\fR with \fB30064771077\fR stored in \fBvar1\fR and
-\fB-16\fR stored in \fBvar2\fR. Note that the integers returned are
+will return \fB2\fR with \fB30064771077\fR stored in \fIvar1\fR and
+\fB\-16\fR stored in \fIvar2\fR. Note that the integers returned are
signed and cannot be represented by Tcl as unsigned values.
.RE
.IP \fBW\fR 5
@@ -559,18 +664,26 @@ as \fIcount\fR 64-bit signed integers represented in big-endian byte
order. For example,
.RS
.CS
-\fBbinary scan \\x00\\x00\\x00\\x05\\x00\\x00\\x00\\x07\\xff\\xff\\xff\\xf0 WI* var1 var2\fR
+set str \ex00\ex00\ex00\ex05\ex00\ex00\ex00\ex07\exff\exff\exff\exf0
+\fBbinary scan\fR $str WI* var1 var2
.CE
-will return \fB2\fR with \fB21474836487\fR stored in \fBvar1\fR and \fB-16\fR
-stored in \fBvar2\fR.
-.VE
+will return \fB2\fR with \fB21474836487\fR stored in \fIvar1\fR and \fB\-16\fR
+stored in \fIvar2\fR.
.RE
+.IP \fBm\fR 5
+.VS 8.5
+The data is interpreted as \fIcount\fR 64-bit signed integers
+represented in the native byte order of the machine running the Tcl
+script. It is otherwise identical to \fBw\fR and \fBW\fR.
+To determine what the native byte order of the machine is, refer to
+the \fBbyteOrder\fR element of the \fBtcl_platform\fR array.
+.VE 8.5
.IP \fBf\fR 5
The data is interpreted as \fIcount\fR single-precision floating point
numbers in the machine's native representation. The floating point
numbers are stored in the corresponding variable as a list. If
\fIcount\fR is \fB*\fR, then all of the remaining bytes in
-\fBstring\fR will be scanned. If \fIcount\fR is omitted, then one
+\fIstring\fR will be scanned. If \fIcount\fR is omitted, then one
single-precision floating point number will be scanned. The size of a
floating point number may vary across architectures, so the number of
bytes that are scanned may vary. If the data does not represent a
@@ -579,11 +692,25 @@ compiler dependent. For example, on a Windows system running on an
Intel Pentium processor,
.RS
.CS
-\fBbinary scan \\x3f\\xcc\\xcc\\xcd f var1\fR
+\fBbinary scan\fR \ex3f\excc\excc\excd f var1
.CE
will return \fB1\fR with \fB1.6000000238418579\fR stored in
-\fBvar1\fR.
+\fIvar1\fR.
.RE
+.IP \fBr\fR 5
+.VS 8.5
+This form is the same as \fBf\fR except that the data is interpreted
+as \fIcount\fR single-precision floating point number in little-endian
+order. This conversion is not portable to the minority of systems not
+using IEEE floating point representations.
+.VE 8.5
+.IP \fBR\fR 5
+.VS 8.5
+This form is the same as \fBf\fR except that the data is interpreted
+as \fIcount\fR single-precision floating point number in big-endian
+order. This conversion is not portable to the minority of systems not
+using IEEE floating point representations.
+.VE 8.5
.IP \fBd\fR 5
This form is the same as \fBf\fR except that the data is interpreted
as \fIcount\fR double-precision floating point numbers in the
@@ -591,23 +718,37 @@ machine's native representation. For example, on a Windows system
running on an Intel Pentium processor,
.RS
.CS
-\fBbinary scan \\x9a\\x99\\x99\\x99\\x99\\x99\\xf9\\x3f d var1\fR
+\fBbinary scan\fR \ex9a\ex99\ex99\ex99\ex99\ex99\exf9\ex3f d var1
.CE
will return \fB1\fR with \fB1.6000000000000001\fR
-stored in \fBvar1\fR.
-.RE
+stored in \fIvar1\fR.
+.RE
+.IP \fBq\fR 5
+.VS 8.5
+This form is the same as \fBd\fR except that the data is interpreted
+as \fIcount\fR double-precision floating point number in little-endian
+order. This conversion is not portable to the minority of systems not
+using IEEE floating point representations.
+.VE 8.5
+.IP \fBQ\fR 5
+.VS 8.5
+This form is the same as \fBd\fR except that the data is interpreted
+as \fIcount\fR double-precision floating point number in big-endian
+order. This conversion is not portable to the minority of systems not
+using IEEE floating point representations.
+.VE 8.5
.IP \fBx\fR 5
Moves the cursor forward \fIcount\fR bytes in \fIstring\fR. If
\fIcount\fR is \fB*\fR or is larger than the number of bytes after the
-current cursor cursor position, then the cursor is positioned after
+current cursor position, then the cursor is positioned after
the last byte in \fIstring\fR. If \fIcount\fR is omitted, then the
cursor is moved forward one byte. Note that this type does not
consume an argument. For example,
.RS
.CS
-\fBbinary scan \\x01\\x02\\x03\\x04 x2H* var1\fR
+\fBbinary scan\fR \ex01\ex02\ex03\ex04 x2H* var1
.CE
-will return \fB1\fR with \fB0304\fR stored in \fBvar1\fR.
+will return \fB1\fR with \fB0304\fR stored in \fIvar1\fR.
.RE
.IP \fBX\fR 5
Moves the cursor back \fIcount\fR bytes in \fIstring\fR. If
@@ -618,10 +759,10 @@ is omitted then the cursor is moved back one byte. Note that this
type does not consume an argument. For example,
.RS
.CS
-\fBbinary scan \\x01\\x02\\x03\\x04 c2XH* var1 var2\fR
+\fBbinary scan\fR \ex01\ex02\ex03\ex04 c2XH* var1 var2
.CE
-will return \fB2\fR with \fB1 2\fR stored in \fBvar1\fR and \fB020304\fR
-stored in \fBvar2\fR.
+will return \fB2\fR with \fB1 2\fR stored in \fIvar1\fR and \fB020304\fR
+stored in \fIvar2\fR.
.RE
.IP \fB@\fR 5
Moves the cursor to the absolute location in the data string specified
@@ -631,21 +772,23 @@ by \fIcount\fR. Note that position 0 refers to the first byte in
\fIcount\fR is omitted, then an error will be generated. For example,
.RS
.CS
-\fBbinary scan \\x01\\x02\\x03\\x04 c2@1H* var1 var2\fR
+\fBbinary scan\fR \ex01\ex02\ex03\ex04 c2@1H* var1 var2
.CE
-will return \fB2\fR with \fB1 2\fR stored in \fBvar1\fR and \fB020304\fR
-stored in \fBvar2\fR.
+will return \fB2\fR with \fB1 2\fR stored in \fIvar1\fR and \fB020304\fR
+stored in \fIvar2\fR.
.RE
-.SH "PLATFORM ISSUES"
-Sometimes it is desirable to format or scan integer values in the
-native byte order for the machine. Refer to the \fBbyteOrder\fR
-element of the \fBtcl_platform\fR array to decide which type character
-to use when formatting or scanning integers.
+.SH "PORTABILITY ISSUES"
+The \fBr\fR, \fBR\fR, \fBq\fR and \fBQ\fR conversions will only work
+reliably for transferring data between computers which are all using
+IEEE floating point representations. This is very common, but not
+universal. To transfer floating-point numbers portably between all
+architectures, use their textual representation (as produced by
+\fBformat\fR) instead.
.SH EXAMPLES
This is a procedure to write a Tcl string to a binary-encoded channel as
UTF-8 data preceded by a length word:
.CS
-proc writeString {channel string} {
+proc \fIwriteString\fR {channel string} {
set data [encoding convertto utf-8 $string]
puts -nonewline [\fBbinary format\fR Ia* \e
[string length $data] $data]
@@ -653,9 +796,9 @@ proc writeString {channel string} {
.CE
.PP
This procedure reads a string from a channel that was written by the
-previously presented \fBwriteString\fR procedure:
+previously presented \fIwriteString\fR procedure:
.CS
-proc readString {channel} {
+proc \fIreadString\fR {channel} {
if {![\fBbinary scan\fR [read $channel 4] I length]} {
error "missing length"
}
@@ -663,9 +806,7 @@ proc readString {channel} {
return [encoding convertfrom utf-8 $data]
}
.CE
-
.SH "SEE ALSO"
format(n), scan(n), tclvars(n)
-
.SH KEYWORDS
binary, format, scan
diff --git a/doc/catch.n b/doc/catch.n
index f2d5533..0e2ec04 100644
--- a/doc/catch.n
+++ b/doc/catch.n
@@ -1,18 +1,19 @@
'\"
'\" Copyright (c) 1993-1994 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Contributions from Don Porter, NIST, 2003. (not subject to US copyright)
'\"
'\" 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.0" Tcl "Tcl Built-In Commands"
+.TH catch n "8.5" Tcl "Tcl Built-In Commands"
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
catch \- Evaluate script and trap exceptional returns
.SH SYNOPSIS
-\fBcatch\fI script \fR?\fIvarName\fR?
+\fBcatch\fI script \fR?\fIresultVarName\fR? ?\fIoptionsVarName\fR?
.BE
.SH DESCRIPTION
@@ -35,44 +36,61 @@ new commands that return other integer values as return codes as well,
and scripts that make use of the \fBreturn -code\fR command can also
have return codes other than the five defined by Tcl.
.PP
-If the \fIvarName\fR argument is given, then the variable it names is
+If the \fIresultVarName\fR argument is given, then the variable it names is
set to the result of the script evaluation. When the return code from
-the script is 1 (\fBTCL_ERROR\fR), the value stored in \fIvarName\fR is an error
+the script is 1 (\fBTCL_ERROR\fR), the value stored in \fIresultVarName\fR is an error
message. When the return code from the script is 0 (\fBTCL_OK\fR), the value
stored in \fIresultVarName\fR is the value returned from \fIscript\fR.
.PP
-If \fIscript\fR does not raise an error, \fBcatch\fR will return 0
-(\fBTCL_OK\fR) and set the variable to the value returned from \fIscript\fR.
+.VS 8.5
+If the \fIoptionsVarName\fR argument is given, then the variable it
+names is set to a dictionary of return options returned by evaluation
+of \fIscript\fR. Tcl specifies two entries that are always
+defined in the dictionary: \fB\-code\fR and \fB\-level\fR. When
+the return code from evaluation of \fIscript\fR is not \fBTCL_RETURN\fR,
+the value of the \fB\-level\fR entry will be 0, and the value
+of the \fB\-code\fR entry will be the same as the return code.
+Only when the return code is \fBTCL_RETURN\fR will the values of
+the \fB\-level\fR and \fB\-code\fR entries be something else, as
+further described in the documentation for the \fBreturn\fR command.
.PP
-Note that \fBcatch\fR catches all exceptions, including those
-generated by \fBbreak\fR and \fBcontinue\fR as well as errors. The
-only errors that are not caught are syntax errors found when the
-script is compiled. This is because the catch command only catches
-errors during runtime. When the catch statement is compiled, the
-script is compiled as well and any syntax errors will generate a Tcl
-error.
-
+When the return code from evaluation of \fIscript\fR is \fBTCL_ERROR\fR,
+three additional entries are defined in the dictionary of return options
+stored in \fIoptionsVarName\fR: \fB\-errorinfo\fR, \fB\-errorcode\fR,
+and \fB\-errorline\fR. The value of the \fB\-errorinfo\fR entry
+is a formatted stack trace containing more information about
+the context in which the error happened. The formatted stack
+trace is meant to be read by a person. The value of
+the \fB\-errorcode\fR entry is additional information about the
+error stored as a list. The \fB\-errorcode\fR value is meant to
+be further processed by programs, and may not be particularly
+readable by people. The value of the \fB\-errorline\fR entry
+is an integer indicating which line of \fIscript\fR was being
+evaluated when the error occurred. The values of the \fB\-errorinfo\fR
+and \fB\-errorcode\fR entries of the most recent error are also
+available as values of the global variables \fB::errorInfo\fR
+and \fB::errorCode\fR respectively.
+.PP
+Tcl packages may provide commands that set other entries in the
+dictionary of return options, and the \fBreturn\fR command may be
+used by scripts to set return options in addition to those defined
+above.
+.VE 8.5
.SH EXAMPLES
The \fBcatch\fR command may be used in an \fBif\fR to branch based on
the success of a script.
.CS
if { [\fBcatch\fR {open $someFile w} fid] } {
- puts stderr "Could not open $someFile for writing\\n$fid"
+ puts stderr "Could not open $someFile for writing\en$fid"
exit 1
}
.CE
.PP
-The \fBcatch\fR command will not catch compiled syntax errors. The
-first time proc \fBfoo\fR is called, the body will be compiled and a
-Tcl error will be generated.
-.CS
-proc foo {} {
- \fBcatch\fR {expr {1 +- }}
-}
-.CE
+There are more complex examples of \fBcatch\fR usage in the
+documentation for the \fBreturn\fR command.
.SH "SEE ALSO"
-break(n), continue(n), error(n), return(n), tclvars(n)
+break(n), continue(n), dict(n), error(n), return(n), tclvars(n)
.SH KEYWORDS
catch, error
diff --git a/doc/chan.n b/doc/chan.n
new file mode 100644
index 0000000..f5d3d54
--- /dev/null
+++ b/doc/chan.n
@@ -0,0 +1,736 @@
+'\"
+'\" Copyright (c) 2005-2006 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 chan n 8.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+chan \- Read, write and manipulate channels
+.SH SYNOPSIS
+\fBchan \fIoption\fR ?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command provides several operations for reading from, writing to
+and otherwise manipulating open channels (such as have been created
+with the \fBopen\fR and \fBsocket\fR commands, or the default named
+channels \fBstdin\fR, \fBstdout\fR or \fBstderr\fR which correspond to
+the process's standard input, output and error streams respectively).
+\fIOption\fR indicates what to do with the channel; any unique
+abbreviation for \fIoption\fR is acceptable. Valid options are:
+.TP
+\fBchan blocked \fIchannelId\fR
+.
+This tests whether the last input operation on the channel called
+\fIchannelId\fR failed because it would have otherwise caused the
+process to block, and returns 1 if that was the case. It returns 0
+otherwise. Note that this only ever returns 1 when the channel has
+been configured to be non-blocking; all Tcl channels have blocking
+turned on by default.
+.TP
+\fBchan close \fIchannelId\fR
+.
+Close and destroy the channel called \fIchannelId\fR. Note that this
+deletes all existing file-events registered on the channel.
+.RS
+.PP
+As part of closing the channel, all buffered output is flushed to the
+channel's output device, any buffered input is discarded, the
+underlying operating system resource is closed and \fIchannelId\fR
+becomes unavailable for future use.
+.PP
+If the channel is blocking, 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 command returns
+immediately; output will be flushed in the background and the channel
+will be closed when all the flushing is complete.
+.PP
+If \fIchannelId\fR is a blocking channel for a command pipeline then
+\fBchan close\fR waits for the child processes to complete.
+.PP
+If the channel is shared between interpreters, then \fBchan close\fR
+makes \fIchannelId\fR unavailable in the invoking interpreter but has
+no other effect until all of the sharing interpreters have closed the
+channel. When the last interpreter in which the channel is registered
+invokes \fBchan close\fR (or \fBclose\fR), the cleanup actions
+described above occur. See the \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.
+.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
+pipeline created with \fBopen\fR returns an error, \fBchan close\fR
+generates an error (similar to the \fBexec\fR command.)
+.RE
+.TP
+\fBchan configure \fIchannelId\fR ?\fIoptionName\fR? ?\fIvalue\fR? ?\fIoptionName value\fR?...
+.
+Query or set the configuration options of the channel named
+\fIchannelId\fR.
+.RS
+.PP
+If no \fIoptionName\fR or \fIvalue\fR arguments are supplied, the
+command returns a list containing alternating option names and values
+for the channel. If \fIoptionName\fR is supplied but no \fIvalue\fR
+then the command returns the current value of the given option. If
+one or more pairs of \fIoptionName\fR and \fIvalue\fR are supplied,
+the command sets each of the named options to the corresponding
+\fIvalue\fR; in this case the return value is an empty string.
+.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
+example, see the manual entry for the \fBsocket\fR command for its
+additional options.
+.TP
+\fB\-blocking\fR \fIboolean\fR
+.
+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
+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
+work correctly, the application must be using the Tcl event loop
+(e.g. by calling \fBTcl_DoOneEvent\fR or invoking the \fBvwait\fR
+command).
+.TP
+\fB\-buffering\fR \fInewValue\fR
+.
+If \fInewValue\fR is \fBfull\fR then the I/O system will buffer output
+until its internal buffer is full or until the \fBchan flush\fR
+command is invoked. If \fInewValue\fR is \fBline\fR, then the I/O
+system will automatically flush output for the channel whenever a
+newline character is output. If \fInewValue\fR is \fBnone\fR, the I/O
+system will flush automatically after every output operation. The
+default is for \fB\-buffering\fR to be set to \fBfull\fR except for
+channels that connect to terminal-like devices; for these channels the
+initial setting is \fBline\fR. Additionally, \fBstdin\fR and
+\fBstdout\fR are initially set to \fBline\fR, and \fBstderr\fR is set
+to \fBnone\fR.
+.TP
+\fB\-buffersize\fR \fInewSize\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 a number of no more than one
+million, allowing buffers of up to one million bytes in size.
+.TP
+\fB\-encoding\fR \fIname\fR
+.
+This option is used to specify the encoding of the channel as one of
+the named encodings returned by \fBencoding names\fR or the special
+value \fBbinary\fR, so that the data can be converted to and from
+Unicode for use in Tcl. For instance, in order for Tcl to read
+characters from a Japanese file in \fBshiftjis\fR and properly process
+and display the contents, the encoding would be set to \fBshiftjis\fR.
+Thereafter, when reading from the channel, the bytes in the Japanese
+file would be converted to Unicode as they are read. Writing is also
+supported \- as Tcl strings are written to the channel they will
+automatically be converted to the specified encoding on output.
+.RS
+.PP
+If a file contains pure binary data (for instance, a JPEG image), the
+encoding for the channel should be configured to be \fBbinary\fR. Tcl
+will then assign no interpretation to the data in the file and simply
+read or write raw bytes. The Tcl \fBbinary\fR command can be used to
+manipulate this byte-oriented data. It is usually better to set the
+\fB\-translation\fR option to \fBbinary\fR when you want to transfer
+binary data, as this turns off the other automatic interpretations of
+the bytes in the stream as well.
+.PP
+The default encoding for newly opened channels is the same platform-
+and locale-dependent system encoding used for interfacing with the
+operating system, as returned by \fBencoding system\fR.
+.RE
+.TP
+\fB\-eofchar\fR \fIchar\fR
+.TP
+\fB\-eofchar\fR \fB{\fIinChar outChar\fB}\fR
+.
+This option supports DOS file systems that use Control-z (\ex1a) as an
+end of file marker. If \fIchar\fR is not an empty string, then this
+character signals end-of-file when it is encountered during input.
+For output, the end-of-file character is output when the channel is
+closed. If \fIchar\fR is the empty string, then there is no special
+end of file character marker. For read-write channels, a two-element
+list specifies the end of file marker for input and output,
+respectively. As a convenience, when setting the end-of-file
+character for a read-write channel you can specify a single value that
+will apply to both reading and writing. When querying the end-of-file
+character of a read-write channel, a two-element list will always be
+returned. The default value for \fB\-eofchar\fR is the empty string
+in all cases except for files under Windows. In that case the
+\fB\-eofchar\fR is Control-z (\ex1a) for reading and the empty string
+for writing.
+The acceptable range for \fB\-eofchar\fR values is \ex01 - \ex7f;
+attempting to set \fB\-eofchar\fR to a value outside of this range will
+generate an error.
+.TP
+\fB\-translation\fR \fImode\fR
+.TP
+\fB\-translation\fR \fB{\fIinMode outMode\fB}\fR
+.
+In Tcl scripts the end of a line is always represented using a single
+newline character (\en). However, in actual files and devices the end
+of a line may be represented differently on different platforms, or
+even for different devices on the same platform. For example, under
+UNIX newlines are used in files, whereas carriage-return-linefeed
+sequences are normally used in network connections. On input (i.e.,
+with \fBchan gets\fR and \fBchan read\fR) the Tcl I/O system
+automatically translates the external end-of-line representation into
+newline characters. Upon output (i.e., with \fBchan puts\fR), the I/O
+system translates newlines to the external end-of-line representation.
+The default translation mode, \fBauto\fR, handles all the common cases
+automatically, but the \fB\-translation\fR option provides explicit
+control over the end of line translations.
+.RS
+.PP
+The value associated with \fB\-translation\fR is a single item for
+read-only and write-only channels. The value is a two-element list for
+read-write channels; the read translation mode is the first element of
+the list, and the write translation mode is the second element. As a
+convenience, when setting the translation mode for a read-write channel
+you can specify a single value that will apply to both reading and
+writing. When querying the translation mode of a read-write channel, a
+two-element list will always be returned. The following values are
+currently supported:
+.TP
+\fBauto\fR
+.
+As the input translation mode, \fBauto\fR treats any of newline
+(\fBlf\fR), carriage return (\fBcr\fR), or carriage return followed by
+a newline (\fBcrlf\fR) as the end of line representation. The end of
+line representation can even change from line-to-line, and all cases
+are translated to a newline. As the output translation mode,
+\fBauto\fR chooses a platform specific representation; for sockets on
+all platforms Tcl chooses \fBcrlf\fR, for all Unix flavors, it chooses
+\fBlf\fR, and for the various flavors of Windows it chooses
+\fBcrlf\fR. The default setting for \fB\-translation\fR is \fBauto\fR
+for both input and output.
+.TP
+\fBbinary\fR
+.
+No end-of-line translations are performed. This is nearly identical
+to \fBlf\fR mode, except that in addition \fBbinary\fR mode also sets
+the end-of-file character to the empty string (which disables it) and
+sets the encoding to \fBbinary\fR (which disables encoding filtering).
+See the description of \fB\-eofchar\fR and \fB\-encoding\fR for more
+information.
+.TP
+\fBcr\fR
+.
+The end of a line in the underlying file or device is represented by a
+single carriage return character. As the input translation mode,
+\fBcr\fR mode converts carriage returns to newline characters. As the
+output translation mode, \fBcr\fR mode translates newline characters
+to carriage returns.
+.TP
+\fBcrlf\fR
+.
+The end of a line in the underlying file or device is represented by a
+carriage return character followed by a linefeed character. As the
+input translation mode, \fBcrlf\fR mode converts
+carriage-return-linefeed sequences to newline characters. As the
+output translation mode, \fBcrlf\fR mode translates newline characters
+to carriage-return-linefeed sequences. This mode is typically used on
+Windows platforms and for network connections.
+.TP
+\fBlf\fR
+.
+The end of a line in the underlying file or device is represented by a
+single newline (linefeed) character. In this mode no translations
+occur during either input or output. This mode is typically used on
+UNIX platforms.
+.RE
+.RE
+.TP
+\fBchan copy \fIinputChan outputChan\fR ?\fB\-size \fIsize\fR? ?\fB\-command \fIcallback\fR?
+.
+Copy data from the channel \fIinputChan\fR, which must have been
+opened for reading, to the channel \fIoutputChan\fR, which must have
+been opened for writing. The \fBchan copy\fR command leverages the
+buffering in the Tcl I/O system to avoid extra copies and to avoid
+buffering too much data in main memory when copying large files to
+slow destinations like network sockets.
+.RS
+.PP
+The \fBchan copy\fR command transfers data from \fIinputChan\fR until
+end of file or \fIsize\fR bytes have been transferred. If no
+\fB\-size\fR argument is given, then the copy goes until end of file.
+All the data read from \fIinputChan\fR is copied to \fIoutputChan\fR.
+Without the \fB\-command\fR option, \fBchan copy\fR blocks until the
+copy is complete and returns the number of bytes written to
+\fIoutputChan\fR.
+.PP
+The \fB\-command\fR argument makes \fBchan copy\fR work in the
+background. In this case it returns immediately and the
+\fIcallback\fR is invoked later when the copy completes. The
+\fIcallback\fR is called with one or two additional arguments that
+indicates how many bytes were written to \fIoutputChan\fR. If an
+error occurred during the background copy, the second argument is the
+error string associated with the error. With a background copy, it is
+not necessary to put \fIinputChan\fR or \fIoutputChan\fR into
+non-blocking mode; the \fBchan copy\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 \fIinputChan\fR or
+\fIoutputChan\fR during a background \fBchan copy\fR. If either
+\fIinputChan\fR or \fIoutputChan\fR get closed while the copy is in
+progress, the current copy is stopped and the command callback is
+\fInot\fR made. If \fIinputChan\fR is closed, then all data already
+queued for \fIoutputChan\fR is written out.
+.PP
+Note that \fIinputChan\fR can become readable during a background
+copy. You should turn off any \fBchan event\fR or \fBfileevent\fR
+handlers during a background copy so those handlers do not interfere
+with the copy. Any I/O attempted by a \fBchan event\fR or
+\fBfileevent\fR handler will get a
+.QW "channel busy"
+error.
+.PP
+\fBChan copy\fR translates end-of-line sequences in \fIinputChan\fR
+and \fIoutputChan\fR according to the \fB\-translation\fR option for
+these channels (see \fBchan configure\fR above). The translations
+mean that the number of bytes read from \fIinputChan\fR can be
+different than the number of bytes written to \fIoutputChan\fR. Only
+the number of bytes written to \fIoutputChan\fR is reported, either as
+the return value of a synchronous \fBchan copy\fR or as the argument
+to the callback for an asynchronous \fBchan copy\fR.
+.PP
+\fBChan copy\fR obeys the encodings and character translations
+configured for the channels. This means that the incoming characters
+are converted internally first UTF-8 and then into the encoding of the
+channel \fBchan copy\fR writes to (see \fBchan configure\fR above for
+details on the \fB\-encoding\fR and \fB\-translation\fR options). No
+conversion is done if both channels are set to encoding \fBbinary\fR
+and have matching translations. If only the output channel is set to
+encoding \fBbinary\fR the system will write the internal UTF-8
+representation of the incoming characters. If only the input channel
+is set to encoding \fBbinary\fR the system will assume that the
+incoming bytes are valid UTF-8 characters and convert them according
+to the output encoding. The behaviour of the system for bytes which
+are not valid UTF-8 characters is undefined in this case.
+.RE
+.TP
+\fBchan create \fImode cmdPrefix\fR
+.
+This subcommand creates a new script level channel using the command
+prefix \fIcmdPrefix\fR as its handler. Any such channel is called a
+\fBreflected\fR channel. The specified command prefix, \fBcmdPrefix\fR,
+must be a non-empty list, and should provide the API described in the
+\fBreflectedchan\fR manual page. The handle of the new channel is
+returned as the result of the \fBchan create\fR command, and the
+channel is open. Use either \fBclose\fR or \fBchan close\fR to remove
+the channel.
+.RS
+.PP
+The argument \fImode\fR specifies if the new channel is opened for
+reading, writing, or both. It has to be a list containing any of the
+strings
+.QW \fBread\fR
+or
+.QW \fBwrite\fR .
+The list must have at least one
+element, as a channel you can neither write to nor read from makes no
+sense. The handler command for the new channel must support the chosen
+mode, or an error is thrown.
+.PP
+The command prefix is executed in the global namespace, at the top of
+call stack, following the appending of arguments as described in the
+\fBreflectedchan\fR manual page. Command resolution happens at the
+time of the call. Renaming the command, or destroying it means that
+the next call of a handler method may fail, causing the channel
+command invoking the handler to fail as well. Depending on the
+subcommand being invoked, the error message may not be able to explain
+the reason for that failure.
+.PP
+Every channel created with this subcommand knows which interpreter it
+was created in, and only ever executes its handler command in that
+interpreter, even if the channel was shared with and/or was moved into
+a different interpreter. Each reflected channel also knows the thread
+it was created in, and executes its handler command only in that
+thread, even if the channel was moved into a different thread. To this
+end all invocations of the handler are forwarded to the original
+thread by posting special events to it. This means that the original
+thread (i.e. the thread that executed the \fBchan create\fR command)
+must have an active event loop, i.e. it must be able to process such
+events. Otherwise the thread sending them will \fIblock
+indefinitely\fR. Deadlock may occur.
+.PP
+Note that this permits the creation of a channel whose two endpoints
+live in two different threads, providing a stream-oriented bridge
+between these threads. In other words, we can provide a way for
+regular stream communication between threads instead of having to send
+commands.
+.PP
+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
+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
+handles.
+.PP
+This subcommand is \fBsafe\fR and made accessible to safe
+interpreters. While it arranges for the execution of arbitrary Tcl
+code the system also makes sure that the code is always executed
+within the safe interpreter.
+.RE
+.TP
+\fBchan eof \fIchannelId\fR
+.
+Test whether the last input operation on the channel called
+\fIchannelId\fR failed because the end of the data stream was reached,
+returning 1 if end-of-file was reached, and 0 otherwise.
+.TP
+\fBchan event \fIchannelId event\fR ?\fIscript\fR?
+.
+Arrange for the Tcl script \fIscript\fR to be installed as a \fIfile
+event handler\fR to be called whenever the channel called
+\fIchannelId\fR enters the state described by \fIevent\fR (which must
+be either \fBreadable\fR or \fBwritable\fR); only one such handler may
+be installed per event per channel at a time. If \fIscript\fR is the
+empty string, the current handler is deleted (this also happens if the
+channel is closed or the interpreter deleted). If \fIscript\fR is
+omitted, the currently installed script is returned (or an empty
+string if no such handler is installed). The callback is only
+performed if the event loop is being serviced (e.g. via \fBvwait\fR or
+\fBupdate\fR).
+.RS
+.PP
+A file event handler is a binding between a channel and a script, such
+that the script is evaluated whenever the channel becomes readable or
+writable. File event handlers are most commonly used to allow data to
+be received from another process on an event-driven basis, so that the
+receiver can continue to interact with the user or with other channels
+while waiting for the data to arrive. If an application invokes
+\fBchan gets\fR or \fBchan read\fR on a blocking channel when there is
+no input data available, the process will block; until the input data
+arrives, it will not be able to service other events, so it will
+appear to the user to
+.QW "freeze up" .
+With \fBchan event\fR, the
+process can tell when data is present and only invoke \fBchan gets\fR
+or \fBchan read\fR when they will not block.
+.PP
+A channel is considered to be readable if there is unread data
+available on the underlying device. A channel is also considered to
+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
+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
+there is no special check for end of file, an infinite loop may occur
+where \fIscript\fR reads no data, returns, and is immediately invoked
+again.
+.PP
+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.
+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
+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
+gets\fR never block.
+.PP
+The script for a file event is executed at global level (outside the
+context of any Tcl procedure) in the interpreter in which the \fBchan
+event\fR command was invoked. If an error occurs while executing the
+script then the command registered with \fBinterp bgerror\fR is used
+to report the error. In addition, the file event handler is deleted
+if it ever returns an error; this is done in order to prevent infinite
+loops due to buggy handlers.
+.RE
+.TP
+\fBchan flush \fIchannelId\fR
+.
+Ensures that all pending output for the channel called \fIchannelId\fR
+is written.
+.RS
+.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
+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.
+.RE
+.TP
+\fBchan gets \fIchannelId\fR ?\fIvarName\fR?
+.
+Reads the next line from the channel called \fIchannelId\fR. If
+\fIvarName\fR is not specified, the result of the command will be the
+line that has been read (without a trailing newline character) or an
+empty string upon end-of-file or, in non-blocking mode, if the data
+available is exhausted. If \fIvarName\fR is specified, the line that
+has been read will be written to the variable called \fIvarName\fR and
+result will be the number of characters that have been read or -1 if
+end-of-file was reached or, in non-blocking mode, if the data
+available is exhausted.
+.RS
+.PP
+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
+\fBchan blocked\fR command.
+.RE
+.TP
+\fBchan names\fR ?\fIpattern\fR?
+.
+Produces a list of all channel names. If \fIpattern\fR is specified,
+only those channel names that match it (according to the rules of
+\fBstring match\fR) will be returned.
+.TP
+\fBchan pending \fImode channelId\fR
+.
+Depending on whether \fImode\fR is \fBinput\fR or \fBoutput\fR,
+returns the number of
+bytes of input or output (respectively) currently buffered
+internally for \fIchannelId\fR (especially useful in a readable event
+callback to impose application-specific limits on input line lengths to avoid
+a potential denial-of-service attack where a hostile user crafts
+an extremely long line that exceeds the available memory to buffer it).
+Returns -1 if the channel was not opened for the mode in question.
+.TP
+\fBchan postevent \fIchannelId eventSpec\fR
+.
+This subcommand is used by command handlers specified with \fBchan
+create\fR. It notifies the channel represented by the handle
+\fIchannelId\fR that the event(s) listed in the \fIeventSpec\fR have
+occurred. The argument has to be a list containing any of the strings
+\fBread\fR and \fBwrite\fR. The list must contain at least one
+element as it does not make sense to invoke the command if there are
+no events to post.
+.RS
+.PP
+Note that this subcommand can only be used with channel handles that
+were created/opened by \fBchan create\fR. All other channels will
+cause this subcommand to report an error.
+.PP
+As only the Tcl level of a channel, i.e. its command handler, should
+post events to it we also restrict the usage of this command to the
+interpreter that created the channel. In other words, posting events
+to a reflected channel from an interpreter that does not contain it's
+implementation is not allowed. Attempting to post an event from any
+other interpreter will cause this subcommand to report an error.
+.PP
+Another restriction is that it is not possible to post events that the
+I/O core has not registered an interest in. Trying to do so will cause
+the method to throw an error. See the command handler method
+\fBwatch\fR described in \fBreflectedchan\fR, the document specifying
+the API of command handlers for reflected channels.
+.PP
+This command is \fBsafe\fR and made accessible to safe interpreters.
+It can trigger the execution of \fBchan event\fR handlers, whether in the
+current interpreter or in other interpreters or other threads, even
+where the event is posted from a safe interpreter and listened for by
+a trusted interpreter. \fBChan event\fR handlers are \fIalways\fR
+executed in the interpreter that set them up.
+.RE
+.TP
+\fBchan puts\fR ?\fB\-nonewline\fR? ?\fIchannelId\fR? \fIstring\fR
+.
+Writes \fIstring\fR to the channel named \fIchannelId\fR followed by a
+newline character. A trailing newline character is written unless the
+optional flag \fB\-nonewline\fR is given. If \fIchannelId\fR is
+omitted, the string is written to the standard output channel,
+\fBstdout\fR.
+.RS
+.PP
+Newline characters in the output are translated by \fBchan puts\fR to
+platform-specific end-of-line sequences according to the currently
+configured value of the \fB\-translation\fR option for the channel
+(for example, on PCs newlines are normally replaced with
+carriage-return-linefeed sequences; see \fBchan configure\fR above for
+details).
+.PP
+Tcl buffers output internally, so characters written with \fBchan
+puts\fR may not appear immediately on the output file or device; Tcl
+will normally delay output until the buffer is full or the channel is
+closed. You can force output to appear immediately with the \fBchan
+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
+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
+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
+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).
+.RE
+.TP
+\fBchan read \fIchannelId\fR ?\fInumChars\fR?
+.TP
+\fBchan read \fR?\fB\-nonewline\fR? \fIchannelId\fR
+.
+In the first form, the result will be the next \fInumChars\fR
+characters read from the channel named \fIchannelId\fR; if
+\fInumChars\fR is omitted, all characters up to the point when the
+channel would signal a failure (whether an end-of-file, blocked or
+other error condition) are read. In the second form (i.e. when
+\fInumChars\fR has been omitted) the flag \fB\-nonewline\fR may be
+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
+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
+multi-byte encoding, then there may actually be some bytes remaining
+in the internal buffers that do not form a complete character. These
+bytes will not be returned until a complete character is available or
+end-of-file is reached. The \fB\-nonewline\fR switch is ignored if
+the command returns before reaching the end of the file.
+.PP
+\fBChan read\fR translates end-of-line sequences in the input into
+newline characters according to the \fB\-translation\fR option for the
+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:
+.CS
+\fBchan configure \fIchannelId \fB\-blocking \fI0\fR.
+.CE
+Then \fBchan read\fR behaves much like described above. Note that
+most serial ports are comparatively slow; it is entirely possible to
+get a \fBreadable\fR event for each character read from them. Care
+must be taken when using \fBchan read\fR on blocking serial ports:
+.TP
+\fBchan read \fIchannelId numChars\fR
+.
+In this form \fBchan read\fR blocks until \fInumChars\fR have been
+received from the serial port.
+.TP
+\fBchan read \fIchannelId\fR
+.
+In this form \fBchan read\fR blocks until the reception of the
+end-of-file character, see \fBchan configure -eofchar\fR. If there no
+end-of-file character has been configured for the channel, then
+\fBchan read\fR will block forever.
+.RE
+.TP
+\fBchan seek \fIchannelId offset\fR ?\fIorigin\fR?
+.
+Sets the current access position within the underlying data stream for
+the channel named \fIchannelId\fR to be \fIoffset\fR bytes relative to
+\fIorigin\fR. \fIOffset\fR must be an integer (which may be negative)
+and \fIorigin\fR must be one of the following:
+.RS
+.TP 10
+\fBstart\fR
+.
+The new access position will be \fIoffset\fR bytes from the start
+of the underlying file or device.
+.TP 10
+\fBcurrent\fR
+.
+The new access position will be \fIoffset\fR bytes from the current
+access position; a negative \fIoffset\fR moves the access position
+backwards in the underlying file or device.
+.TP 10
+\fBend\fR
+.
+The new access position will be \fIoffset\fR bytes from the end of the
+file or device. A negative \fIoffset\fR places the access position
+before the end of file, and a positive \fIoffset\fR places the access
+position after the end of file.
+.PP
+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
+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.
+.PP
+Note that \fIoffset\fR values are byte offsets, not character offsets.
+Both \fBchan seek\fR and \fBchan tell\fR operate in terms of bytes,
+not characters, unlike \fBchan read\fR.
+.RE
+.TP
+\fBchan tell \fIchannelId\fR
+.
+Returns a number giving the current access position within the
+underlying data stream for the channel named \fIchannelId\fR. This
+value returned is a byte offset that can be passed to \fBchan seek\fR
+in order to set the channel to a particular position. Note that this
+value is in terms of bytes, not characters like \fBchan read\fR. The
+value returned is -1 for channels that do not support seeking.
+.TP
+\fBchan truncate \fIchannelId\fR ?\fIlength\fR?
+.
+Sets the byte length of the underlying data stream for the channel
+named \fIchannelId\fR to be \fIlength\fR (or to the current byte
+offset within the underlying data stream if \fIlength\fR is
+omitted). The channel is flushed before truncation.
+.SH EXAMPLE
+This opens a file using a known encoding (CP1252, a very common encoding
+on Windows), searches for a string, rewrites that part, and truncates the
+file after a further two lines.
+.PP
+.CS
+set f [open somefile.txt r+]
+\fBchan configure\fR $f -encoding cp1252
+set offset 0
+
+\fI# Search for string "FOOBAR" in the file\fR
+while {[\fBchan gets\fR $f line] >= 0} {
+ set idx [string first FOOBAR $line]
+ if {$idx > -1} {
+ \fI# Found it; rewrite line\fR
+
+ \fBchan seek\fR $f [expr {$offset + $idx}]
+ \fBchan puts\fR -nonewline $f BARFOO
+
+ \fI# Skip to end of following line, and truncate\fR
+ \fBchan gets\fR $f
+ \fBchan gets\fR $f
+ \fBchan truncate\fR $f
+
+ \fI# Stop searching the file now\fR
+ break
+ }
+
+ \fI# Save offset of start of next line for later\fR
+ set offset [\fBchan tell\fR $f]
+}
+\fBchan close\fR $f
+.CE
+.SH "SEE ALSO"
+close(n), eof(n), fblocked(n), fconfigure(n), fcopy(n), file(n),
+fileevent(n), flush(n), gets(n), open(n), puts(n), read(n), seek(n),
+socket(n), tell(n), refchan(n)
+.SH KEYWORDS
+channel, input, output, events, offset
diff --git a/doc/clock.n b/doc/clock.n
index 8e00c43..600722b 100644
--- a/doc/clock.n
+++ b/doc/clock.n
@@ -1,259 +1,890 @@
'\"
-'\" Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans.
-'\" Copyright (c) 1995-1997 Sun Microsystems, Inc.
-'\" Copyright (c) 1998-1999 Scriptics Corporation
-'\" Copyright (c) 2002 ActiveState Corporation
+'\" Generated from file './doc/clock.dt' by tcllib/doctools with format 'nroff'
+'\" Copyright (c) 2004 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
'\"
-'\" This documentation is derived from the time and date facilities of
-'\" TclX, by Mark Diekhans and Karl Lehenbauer.
-'\"
-'\" 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 clock n 8.4 Tcl "Tcl Built-In Commands"
+.TH "clock" n 8.5 Tcl "Tcl Built-In Commands"
.BS
-'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
-clock \- Obtain and manipulate time
-.SH SYNOPSIS
-\fBclock \fIoption\fR ?\fIarg arg ...\fR?
+clock \- Obtain and manipulate dates and times
+.SH "SYNOPSIS"
+package require \fBTcl 8.5\fR
+.sp
+\fBclock add\fR \fItimeVal\fR ?\fIcount unit...\fR? ?\fI\-option value\fR?
+.sp
+\fBclock clicks\fR ?\fI\-option\fR?
+.sp
+\fBclock format\fR \fItimeVal\fR ?\fI\-option value\fR...?
+.sp
+\fBclock microseconds\fR
+.sp
+\fBclock milliseconds\fR
+.sp
+\fBclock scan\fR \fIinputString\fR ?\fI\-option value\fR...?
+.sp
+\fBclock seconds\fR
+.sp
.BE
-
-.SH DESCRIPTION
-.PP
-This command performs one of several operations that may obtain
-or manipulate strings or values that represent some notion of
-time. The \fIoption\fR argument determines what action is carried
-out by the command. The legal \fIoptions\fR (which may be
-abbreviated) are:
-.VS 8.3
-.TP
-\fBclock clicks\fR ?\fB\-milliseconds\fR?
-Return a high-resolution time value as a system-dependent integer
-value. The unit of the value is system-dependent but should be the
-highest resolution clock available on the system such as a CPU cycle
-counter. If \fB\-milliseconds\fR is specified, then the value is
-guaranteed to be of millisecond granularity.
-This value should only be used for the relative measurement
-of elapsed time.
-.VE 8.3
-.TP
-\fBclock format \fIclockValue\fR ?\fB\-format \fIstring\fR? ?\fB\-gmt \fIboolean\fR?
-Converts an integer time value, typically returned by
-\fBclock seconds\fR, \fBclock scan\fR, or the \fBatime\fR or \fBmtime\fR
-options of the \fBfile\fR command, to human-readable
-form. If the \fB\-format\fR argument is present the next argument is a
-string that describes how the date and time are to be formatted.
-Field descriptors consist of a \fB%\fR followed by a field
-descriptor character. All other characters are copied into the result.
-Valid field descriptors are:
+.SH "DESCRIPTION"
+.PP
+The \fBclock\fR command performs several operations that obtain and
+manipulate values that represent times. The command supports several
+subcommands that determine what action is carried out by the command.
+.TP
+\fBclock add\fR \fItimeVal\fR ?\fIcount unit...\fR? ?\fI\-option value\fR?
+Adds a (possibly negative) offset to a time that is expressed as an
+integer number of seconds. See \fBCLOCK ARITHMETIC\fR for a full description.
+.TP
+\fBclock clicks\fR ?\fI\-option\fR?
+If no \fI\-option\fR argument is supplied, returns a high-resolution
+time value as a system-dependent integer value. The unit of the value
+is system-dependent but should be the highest resolution clock available
+on the system such as a CPU cycle counter. See \fBHIGH RESOLUTION TIMERS\fR for a full description.
.RS
-.IP \fB%%\fR
-Insert a %.
-.IP \fB%a\fR
-Abbreviated weekday name (Mon, Tue, etc.).
-.IP \fB%A\fR
-Full weekday name (Monday, Tuesday, etc.).
-.IP \fB%b\fR
-Abbreviated month name (Jan, Feb, etc.).
-.IP \fB%B\fR
-Full month name.
-.VS 8.4
-.IP \fB%c\fR
-Locale specific date and time. The format for date and time
-in the default "C" locale on Unix/Mac is "%a %b %d %H:%M:%S %Y".
-On Windows, this value is the locale specific long date and time, as
-specified in the Regional Options control panel settings.
-.IP \fB%C\fR
-First two digits of the four-digit year (19 or 20).
-.VE 8.4
-.IP \fB%d\fR
-Day of month (01 - 31).
-.VS 8.4
-'\" Since the inclusion of compat/strftime.c, %D, %e, %h should work on all
-'\" platforms.
-.IP \fB%D\fR
-Date as %m/%d/%y.
-.IP \fB%e\fR
-Day of month (1 - 31), no leading zeros.
-.IP \fB%g\fR
-The ISO8601 year number corresponding to the ISO8601 week (%V), expressed
-as a two-digit year-of-the-century, with leading zero if necessary.
-.IP \fB%G\fR
-The ISO8601 year number corresponding to the ISO8601 week (%V), expressed
-as a four-digit number.
-.IP \fB%h\fR
-Abbreviated month name.
-.VE 8.4
-.IP \fB%H\fR
-Hour in 24-hour format (00 - 23).
-.VS 8.4
-.IP \fB%I\fR
-Hour in 12-hour format (01 - 12).
-.VE 8.4
-.IP \fB%j\fR
-Day of year (001 - 366).
-.VS 8.4
-.IP \fB%k\fR
-Hour in 24-hour format, without leading zeros (0 - 23).
-.IP \fB%l\fR
-Hour in 12-hour format, without leading zeros (1 - 12).
-.VE 8.4
-.IP \fB%m\fR
-Month number (01 - 12).
-.IP \fB%M\fR
-Minute (00 - 59).
-.VS 8.4
-.IP \fB%n\fR
-Insert a newline.
-.VE 8.4
-.IP \fB%p\fR
-AM/PM indicator.
-.VS 8.4
-.IP \fB%r\fR
-Time in a locale-specific "meridian" format. The "meridian"
-format in the default "C" locale is "%I:%M:%S %p".
-.IP \fB%R\fR
-Time as %H:%M.
-.IP \fB%s\fR
-Count of seconds since the epoch, expressed as a decimal integer.
-.VE 8.4
-.IP \fB%S\fR
-Seconds (00 - 59).
-.VS 8.4
-.IP \fB%t\fR
-Insert a tab.
-.IP \fB%T\fR
-Time as %H:%M:%S.
-.IP \fB%u\fR
-Weekday number (Monday = 1, Sunday = 7).
-.VE 8.4
-.IP \fB%U\fR
-Week of year (00 - 52), Sunday is the first day of the week.
-.VS 8.4
-.IP \fB%V\fR
-Week of year according to ISO-8601 rules. Week 1 of a given
-year is the week containing 4 January.
-.IP \fB%w\fR
-Weekday number (Sunday = 0, Saturday = 6).
-.VE 8.4
-.IP \fB%W\fR
-Week of year (00 - 52), Monday is the first day of the week.
-.VS 8.4
-.IP \fB%x\fR
-Locale specific date format. The format for a date in the default "C"
-locale for Unix/Mac is "%m/%d/%y".
-On Windows, this value is the locale specific short date format, as
-specified in the Regional Options control panel settings.
-.IP \fB%X\fR
-Locale specific 24-hour time format. The format for a
-24-hour time in the default "C" locale for Unix/Mac is "%H:%M:%S".
-On Windows, this value is the locale specific time format, as
-specified in the Regional Options control panel settings.
-.VE 8.4
-.IP \fB%y\fR
-Year without century (00 - 99).
-.IP \fB%Y\fR
-Year with century (e.g. 1990)
-.IP \fB%Z\fR
-Time zone name.
+.PP
+If the \fI\-option\fR argument is \fI\-milliseconds\fR, then the command
+is synonymous with \fBclock milliseconds\fR (see below). This
+usage is obsolete, and \fBclock milliseconds\fR is to be
+considered the preferred way of obtaining a count of milliseconds.
+.PP
+If the \fI\-option\fR argument is \fI\-microseconds\fR, then the command
+is synonymous with \fBclock microseconds\fR (see below). This
+usage is obsolete, and \fBclock microseconds\fR is to be
+considered the preferred way of obtaining a count of microseconds.
.RE
-.VS 8.4
-.sp
-'\" All the field descriptors should be portable now that
-'\" compat/strftime.c is in place, with the possible exception
-'\" of the time zone name.
-'\".RS
-'\"In addition, the following field descriptors may be supported on some
-'\"systems (e.g. Unix but not Windows):
-'\".IP \fB%D\fR
-'\"Date as %m/%d/%y.
-'\".IP \fB%e\fR
-'\"Day of month (1 - 31), no leading zeros.
-'\".IP \fB%h\fR
-'\"Abbreviated month name.
-'\".IP \fB%n\fR
-'\"Insert a newline.
-'\".IP \fB%r\fR
-'\"Time as %I:%M:%S %p.
-'\".IP \fB%R\fR
-'\"Time as %H:%M.
-'\".IP \fB%t\fR
-'\"Insert a tab.
-'\".IP \fB%T\fR
-'\"Time as %H:%M:%S.
-'\".RE
-'\".sp
-.VE 8.4
+.TP
+\fBclock format\fR \fItimeVal\fR ?\fI\-option value\fR...?
+Formats a time that is expressed as an integer number of seconds into a format
+intended for consumption by users or external programs.
+See \fBFORMATTING TIMES\fR for a full description.
+.TP
+\fBclock microseconds\fR
+Returns the current time as an integer number of microseconds. See \fBHIGH RESOLUTION TIMERS\fR for a full description.
+.TP
+\fBclock milliseconds\fR
+Returns the current time as an integer number of milliseconds. See \fBHIGH RESOLUTION TIMERS\fR for a full description.
+.TP
+\fBclock scan\fR \fIinputString\fR ?\fI\-option value\fR...?
+Scans a time that is expressed as a character string and produces an
+integer number of seconds.
+See \fBSCANNING TIMES\fR for a full description.
+.TP
+\fBclock seconds\fR
+Returns the current time as an integer number of seconds.
+.SS "PARAMETERS"
+.TP
+\fIcount\fR
+An integer representing a count of some unit of time. See
+\fBCLOCK ARITHMETIC\fR for the details.
+.TP
+\fItimeVal\fR
+An integer value passed to the \fBclock\fR command that represents an
+absolute time as a number of seconds from the \fIepoch time\fR of
+1 January 1970, 00:00 UTC. Note that the count of seconds does not
+include any leap seconds; seconds are counted as if each UTC day has
+exactly 86400 seconds. Tcl responds to leap seconds by speeding or
+slowing its clock by a tiny fraction for some minutes until it is
+back in sync with UTC; its data model does not represent minutes that
+have 59 or 61 seconds.
+.TP
+\fIunit\fR
+One of the words, \fBseconds\fR, \fBminutes\fR, \fBhours\fR,
+\fBdays\fR, \fBweeks\fR, \fBmonths\fR, or \fByears\fR, or
+any unique prefix of such a word. Used in conjunction with \fIcount\fR
+to identify an interval of time, for example, \fI3 seconds\fR or
+\fI1 year\fR.
+.SS "OPTIONS"
+.TP
+\fB\-base\fR time
+Specifies that any relative times present in a \fBclock scan\fR command
+are to be given relative to \fItime\fR. \fItime\fR must be expressed as
+a count of nominal seconds from the epoch time of 1 January 1970, 00:00 UTC.
+.TP
+\fB\-format\fR format
+Specifies the desired output format for \fBclock format\fR or the
+expected input format for \fBclock scan\fR. The \fIformat\fR string consists
+of any number of characters other than the per-cent sign
+.PQ \fB%\fR
+interspersed with any number of \fIformat groups\fR, which are two-character
+sequences beginning with the per-cent sign. The permissible format groups,
+and their interpretation, are described under \fBFORMAT GROUPS\fR.
+.RS
+.PP
+On \fBclock format\fR, the default format is
+.CS
+%a %b %d %H:%M:%S %z %Y
+.CE
+.PP
+On \fBclock scan\fR, the lack of a \fI\-format\fR option indicates that a
+.QW "free format scan"
+is requested; see \fBFREE FORM SCAN\fR for a description of what happens.
+.RE
+.TP
+\fB\-gmt\fR boolean
+If \fIboolean\fR is true, specifies that a time specified to \fBclock add\fR,
+\fBclock format\fR or \fBclock scan\fR should be processed in
+UTC. If \fIboolean\fR is false, the processing defaults to the local time
+zone. This usage is obsolete; the correct current usage is to
+specify the UTC time zone with
+.QW "\fB\-timezone\fR \fI:UTC\fR"
+or any of the equivalent ways to specify it.
+.TP
+\fB\-locale\fR localeName
+Specifies that locale-dependent scanning and formatting (and date arithmetic
+for dates preceding the adoption of the Gregorian calendar) is to be done in
+the locale identified by \fIlocaleName\fR. The locale name may be any of
+the locales acceptable to the \fBmsgcat\fR package, or it may be the special
+name \fIsystem\fR, which represents the current locale of the process, or
+the null string, which represents Tcl's default locale.
+.RS
+.PP
+The effect of locale on scanning and formatting is discussed in the
+descriptions of the individual format groups under \fBFORMAT GROUPS\fR.
+The effect of locale on clock arithmetic is discussed under
+\fBCLOCK ARITHMETIC\fR.
+.RE
+.TP
+\fB\-timezone\fR zoneName
+Specifies that clock arithmetic, formatting, and scanning are to be done
+according to the rules for the time zone specified by \fIzoneName\fR.
+The permissible values, and their interpretation, are discussed under
+\fBTIME ZONES\fR.
+On subcommands that expect a \fB\-timezone\fR argument, the default
+is to use the \fIcurrent time zone\fR. The current time zone is
+determined, in order of preference, by:
.RS
-If the \fB\-format\fR argument is not specified, the format string
-\fB"%a %b %d %H:%M:%S %Z %Y"\fR is used. If the \fB\-gmt\fR argument
-is present the next argument must be a boolean which if true specifies
-that the time will be formatted as Greenwich Mean Time. If false
-then the local timezone will be used as defined by the operating
-environment.
+.IP [1]
+the environment variable \fBTCL_TZ\fR.
+.IP [2]
+the environment variable \fBTZ\fR.
+.IP [3]
+on Windows systems, the time zone settings from the Control Panel.
.RE
+If none of these is present, the C \fBlocaltime\fR and \fBmktime\fR
+functions are used to attempt to convert times between local and
+Greenwich. On 32-bit systems, this approach is likely to have bugs,
+particularly for times that lie outside the window (approximately the
+years 1902 to 2037) that can be represented in a 32-bit integer.
+.SH "CLOCK ARITHMETIC"
+The \fBclock add\fR command performs clock arithmetic on a value
+(expressed as nominal seconds from the epoch time of 1 January 1970, 00:00 UTC)
+given as its first argument. The remaining arguments (other than the
+possible \fB\-timezone\fR, \fB\-locale\fR and \fB\-gmt\fR options)
+are integers and keywords in alternation, where the keywords are chosen
+from \fBseconds\fR, \fBminutes\fR, \fBhours\fR,
+\fBdays\fR, \fBweeks\fR, \fBmonths\fR, or \fByears\fR, or
+any unique prefix of such a word.
+.PP
+Addition of seconds, minutes and hours is fairly straightforward;
+the given time increment (times sixty for minutes, or 3600 for hours)
+is simply added to the \fItimeVal\fR given
+to the \fBclock add\fR command. The result is interpreted as
+a nominal number of seconds from the Epoch.
+.PP
+Surprising results
+may be obtained when crossing a point at which a leap second is
+inserted or removed; the \fBclock add\fR command simply ignores
+leap seconds and therefore assumes that times come in sequence,
+23:59:58, 23:59:59, 00:00:00. (This assumption is handled by
+the fact that Tcl's model of time reacts to leap seconds by speeding
+or slowing the clock by a minuscule amount until Tcl's time
+is back in step with the world.
+.PP
+The fact that adding and subtracting hours is defined in terms of
+absolute time means that it will add fixed amounts of time in time zones
+that observe summer time (Daylight Saving Time). For example,
+the following code sets the value of \fBx\fR to \fB04:00:00\fR because
+the clock has changed in the interval in question.
+.CS
+set s [\fBclock scan\fR {2004-10-30 05:00:00} \e
+ -format {%Y-%m-%d %H:%M:%S} \e
+ -timezone :America/New_York]
+set a [\fBclock add\fR $s 24 hours -timezone :America/New_York]
+set x [\fBclock format\fR $a \e
+ -format {%H:%M:%S} -timezone :America/New_York]
+.CE
+.PP
+Adding and subtracting days and weeks is accomplished by converting
+the given time to a calendar day and time of day in the appropriate
+time zone and locale. The requisite number of days (weeks are converted
+to days by multiplying by seven) is added to the calendar day, and
+the date and time are then converted back to a count of seconds from
+the epoch time.
+.PP
+Adding and subtracting a given number of days across the point that
+the time changes at the start or end of summer time (Daylight Saving Time)
+results in the \fIsame local time\fR on the day in question. For
+instance, the following code sets the value of \fBx\fR to \fB05:00:00\fR.
+.CS
+set s [\fBclock scan\fR {2004-10-30 05:00:00} \e
+ -format {%Y-%m-%d %H:%M:%S} \e
+ -timezone :America/New_York]
+set a [\fBclock add\fR $s 1 day -timezone :America/New_York]
+set x [\fBclock format\fR $a \e
+ -format {%H:%M:%S} -timezone :America/New_York]
+.CE
+.PP
+In cases of ambiguity, where the same local time happens twice
+on the same day, the earlier time is used. In cases where the conversion
+yields an impossible time (for instance, 02:30 during the Spring
+Daylight Saving Time change using US rules), the time is converted
+as if the clock had not changed. Thus, the following code
+will set the value of \fBx\fR to \fB03:30:00\fR.
+.CS
+set s [\fBclock scan\fR {2004-04-03 02:30:00} \e
+ -format {%Y-%m-%d %H:%M:%S} \e
+ -timezone :America/New_York]
+set a [\fBclock add\fR $s 1 day -timezone :America/New_York]
+set x [\fBclock format\fR $a \e
+ -format {%H:%M:%S} -timezone :America/New_York]
+.CE
+.PP
+Adding a given number of days or weeks works correctly across the conversion
+between the Julian and Gregorian calendars; the omitted days are skipped.
+The following code sets \fBz\fR to \fB1752-09-14\fR.
+.CS
+set x [\fBclock scan\fR 1752-09-02 -format %Y-%m-%d -locale en_US]
+set y [\fBclock add\fR $x 1 day -locale en_US]
+set z [\fBclock format\fR $y -format %Y-%m-%d -locale en_US]
+.CE
+.PP
+In the bizarre case that adding the given number of days yields a date
+that does not exist because it falls within the dropped days of the
+Julian-to-Gregorian conversion, the date is converted as if it was
+on the Julian calendar.
+.PP
+Adding a number of months, or a number of years, is similar; it
+converts the given time to a calendar date and time of day. It then
+adds the requisite number of months or years, and reconverts the resulting
+date and time of day to an absolute time.
+.PP
+If the resulting date is impossible because the month has too few days
+(for example, when adding 1 month to 31 January), the last day of the
+month is substituted. Thus, adding 1 month to 31 January will result in
+28 February in a common year or 29 February in a leap year.
+.PP
+The rules for handling anomalies relating to summer time and to the
+Gregorian calendar are the same when adding/subtracting months and
+years as they are when adding/subtracting days and weeks.
+.PP
+If multiple \fIcount unit\fR pairs are present on the command, they
+are evaluated consecutively, from left to right.
+.SH "HIGH RESOLUTION TIMERS"
+Most of the subcommands supported by the \fBclock\fR command deal with
+times represented as a count of seconds from the epoch time, and this is the
+representation that \fBclock seconds\fR returns. There are three exceptions,
+which are all intended for use where higher-resolution times are required.
+\fBclock milliseconds\fR returns the count of milliseconds from the
+epoch time, and \fBclock microseconds\fR returns the count of microseconds
+from the epoch time. In addition, there is a \fBclock clicks\fR command
+that returns a platform-dependent high-resolution timer. Unlike
+\fBclock seconds\fR and \fBclock milliseconds\fR, the value
+of \fBclock clicks\fR is not guaranteed to be tied to any fixed
+epoch; it is simply intended to be the most precise interval timer
+available, and is intended only for relative timing studies such as
+benchmarks.
+.SH "FORMATTING TIMES"
+The \fBclock format\fR command produces times for display to a user
+or writing to an external medium. The command accepts times that are
+expressed in seconds from the epoch time of 1 January 1970, 00:00 UTC,
+as returned by \fBclock seconds\fR, \fBclock scan\fR, \fBclock add\fR,
+\fBfile atime\fR or \fBfile mtime\fR.
+.PP
+If a \fB\-format\fR option is present, the following argument is
+a string that specifies how the date and time are to be formatted.
+The string consists
+of any number of characters other than the per-cent sign
+.PQ \fB%\fR
+interspersed with any number of \fIformat groups\fR, which are two-character
+sequences beginning with the per-cent sign. The permissible format groups,
+and their interpretation, are described under \fBFORMAT GROUPS\fR.
+.PP
+If a \fB\-timezone\fR option is present, the following
+argument is a string that specifies the time zone in which the date and time
+are to be formatted. As an alternative to
+.QW "\fB\-timezone\fR \fI:UTC\fR" ,
+the obsolete usage
+.QW "\fB\-gmt\fR \fItrue\fR"
+may be used. See
+\fBTIME ZONES\fR for the permissible variants for the time zone.
+.PP
+If a \fB\-locale\fR option is present, the following argument is
+a string that specifies the locale in which the time is to be formatted,
+in the same format that is used for the \fBmsgcat\fR package. Note
+that the default, if \fB\-locale\fR is not specified, is the root locale
+\fB{}\fR rather than the current locale. The current locale may
+be obtained by using \fB\-locale\fR \fBcurrent\fR.
+In addition, some platforms support a \fBsystem\fR locale that
+reflects the user's current choices. For instance, on Windows, the
+format that the user has selected from dates and times in the Control
+Panel can be obtained by using the \fBsystem\fR locale. On
+platforms that do not define a user selection of date and time formats
+separate from \fBLC_TIME\fR, \fB\-locale\fR \fBsystem\fR is
+synonymous with \fB\-locale\fR \fBcurrent\fR.
+.SH "SCANNING TIMES"
+The \fBclock scan\fR command accepts times that are formatted as
+strings and converts them to counts of seconds from the epoch time
+of 1 January 1970, 00:00 UTC. It normally takes a \fB\-format\fR
+option that is followed by a string describing
+the expected format of the input. (See
+\fBFREE FORM SCAN\fR for the effect of \fBclock scan\fR
+without such an argument.) The string consists of any number of
+characters other than the per-cent sign
+.PQ \fB%\fR "" ,
+interspersed with any number of \fIformat groups\fR, which are two-character
+sequences beginning with the per-cent sign. The permissible format groups,
+and their interpretation, are described under \fBFORMAT GROUPS\fR.
+.PP
+If a \fB\-timezone\fR option is present, the following
+argument is a string that specifies the time zone in which the date and time
+are to be interpreted. As an alternative to \fB\-timezone\fR \fI:UTC\fR,
+the obsolete usage \fB\-gmt\fR \fItrue\fR may be used. See
+\fBTIME ZONES\fR for the permissible variants for the time zone.
+.PP
+If a \fB\-locale\fR option is present, the following argument is
+a string that specifies the locale in which the time is to be interpreted,
+in the same format that is used for the \fBmsgcat\fR package. Note
+that the default, if \fB\-locale\fR is not specified, is the root locale
+\fB{}\fR rather than the current locale. The current locale may
+be obtained by using \fB\-locale\fR \fBcurrent\fR.
+In addition, some platforms support a \fBsystem\fR locale that
+reflects the user's current choices. For instance, on Windows, the
+format that the user has selected from dates and times in the Control
+Panel can be obtained by using the \fBsystem\fR locale. On
+platforms that do not define a user selection of date and time formats
+separate from \fBLC_TIME\fR, \fB\-locale\fR \fBsystem\fR is
+synonymous with \fB\-locale\fR \fBcurrent\fR.
+.PP
+If a \fB\-base\fR option is present, the following argument is
+a time (expressed in seconds from the epoch time) that is used as
+a \fIbase time\fR for interpreting relative times. If no
+\fB\-base\fR option is present, the base time is the current time.
+.PP
+Scanning of times in fixed format works by determining three things:
+the date, the time of day, and the time zone. These three are then
+combined into a point in time, which is returned as the number of seconds
+from the epoch.
+.PP
+Before scanning begins, the format string is preprocessed
+to replace \fB%c\fR, \fB%Ec\fR, \fB%x\fR, \fB%Ex\fR,
+\fB%X\fR. \fB%Ex\fR, \fB%r\fR, \fB%R\fR, \fB%T\fR,
+\fB%D\fR, \fB%EY\fR and \fB%+\fR format groups with counterparts
+that are appropriate to the current locale and contain none of the
+above groups. For instance, \fB%D\fR will (in the \fBen_US\fR locale)
+be replaced with \fB%m/%d/%Y\fR.
+.PP
+The date is determined according to the fields that are present in the
+preprocessed format string. In order of preference:
+.IP [1]
+If the string contains a \fB%s\fR format group, representing
+seconds from the epoch, that group is used to determine the date.
+.IP [2]
+If the string contains a \fB%J\fR format group, representing
+the Julian Day Number, that group is used to determine the date.
+.IP [3]
+If the string contains a complete set of format groups specifying
+century, year, month, and day of month; century, year, and day of year;
+or ISO8601 fiscal year, week of year, and day of week; those groups are
+combined and used to determine the date. If more than one complete
+set is present, the one at the rightmost position in the string is
+used.
+.IP [4]
+If the string lacks a century but contains a set of format
+groups specifying year of century, month and day of month; year of
+century and day of year; or two-digit ISO8601 fiscal year, week of year,
+and day of week; those groups are
+combined and used to determine the date. If more than one complete
+set is present, the one at the rightmost position in the string is
+used. The year is presumed to lie in the range 1938 to 2037 inclusive.
+.IP [5]
+If the string entirely lacks any specification for the year
+(or contains the year only on the locale's alternative calendar)
+and contains a set of format groups specifying month and day of month,
+day of year, or week of year and day of week, those groups are
+combined and used to determine the date. If more than one complete
+set is present, the one at the rightmost position in the string is
+used. The year is determined by interpreting the base time in the given
+time zone.
+.IP [6]
+If the string contains none of the above sets, but has a day
+of the month or day of the week, the day of the month or day of the week
+are used to determine the date by interpreting the base time in the
+given time zone and returning the given day of the current week or month.
+(The week runs from Monday to Sunday, ISO8601-fashion.) If both day
+of month and day of week are present, the day of the month takes
+priority.
+.IP [7]
+If none of the above rules results in a usable date, the date
+of the base time in the given time zone is used.
+.PP
+The time is also determined according to the fields that are present in the
+preprocessed format string. In order of preference:
+.IP [1]
+If the string contains a \fB%s\fR format group, representing
+seconds from the epoch, that group determines the time of day.
+.IP [2]
+If the string contains either an hour on the 24-hour clock
+or an hour on the 12-hour clock plus an AM/PM indicator, that hour determines
+the hour of the day. If the string further contains a group specifying
+the minute of the hour, that group combines with the hour. If the string
+further contains a group specifying the second of the minute, that group
+combines with the hour and minute.
+.IP [3]
+If the string contains neither a \fB%s\fR format group nor
+a group specifying the hour of the day, then midnight (\fB00:00\fR, the start
+of the given date) is used.
+The time zone is determined by either the \fB\-timezone\fR or \fB\-gmt\fR
+options, or by using the current time zone.
+.PP
+If a format string lacks a \fB%z\fR or \fB%Z\fR format group,
+it is possible for the time to be ambiguous because it appears twice
+in the same day, once without and once with Daylight Saving Time.
+If this situation occurs, the first occurrence of the time is chosen.
+(For this reason, it is wise to have the input string contain the
+time zone when converting local times. This caveat does not apply to
+UTC times.)
+.SH "FORMAT GROUPS"
+The following format groups are recognized by the \fBclock scan\fR and
+\fBclock format\fR commands.
+.TP
+\fB%a\fR
+On output, receives an abbreviation (\fIe.g.,\fR \fBMon\fR) for the day
+of the week in the given locale. On input, matches the name of the day
+of the week in the given locale (in either abbreviated or full form, or
+any unique prefix of either form).
+.TP
+\fB%A\fR
+On output, receives the full name (\fIe.g.,\fR \fBMonday\fR) of the day
+of the week in the given locale. On input, matches the name of the day
+of the week in the given locale (in either abbreviated or full form, or
+any unique prefix of either form).
+.TP
+\fB%b\fR
+On output, receives an abbreviation (\fIe.g.,\fR \fBJan\fR) for the name
+of the month in the given locale. On input, matches the name of the month
+in the given locale (in either abbreviated or full form, or
+any unique prefix of either form).
+.TP
+\fB%B\fR
+On output, receives the full name (\fIe.g.,\fR \fBJanuary\fR)
+of the month in the given locale. On input, matches the name of the month
+in the given locale (in either abbreviated or full form, or
+any unique prefix of either form).
+.TP
+\fB%c\fR
+On output, receives a localized representation of date and time of day;
+the localized representation is expected to use the Gregorian calendar.
+On input, matches whatever \fB%c\fR produces.
.TP
-\fBclock scan \fIdateString\fR ?\fB\-base \fIclockVal\fR? ?\fB\-gmt \fIboolean\fR?
-Convert \fIdateString\fR to an integer clock value (see \fBclock seconds\fR).
-This command can parse and convert virtually any standard date and/or time
-string, which can include standard time zone mnemonics. If only a time is
-specified, the current date is assumed. If the string does not contain a
-time zone mnemonic, the local time zone is assumed, unless the \fB\-gmt\fR
+\fB%C\fR
+On output, receives the number of the century in Indo-Arabic numerals.
+On input, matches one or two digits, possibly with leading whitespace,
+that are expected to be the number of the century.
+.TP
+\fB%d\fR
+On output, produces the number of the day of the month, as two decimal
+digits. On input, matches one or two digits, possibly with leading
+whitespace, that are expected to be the number of the day of the month.
+.TP
+\fB%D\fR
+This format group is synonymous with \fB%m/%d/%Y\fR. It should be
+used only in exchanging data within the \fBen_US\fR locale, since
+other locales typically do not use this order for the fields of the date.
+.TP
+\fB%e\fR
+On output, produces the number of the day of the month, as one or
+two decimal digits (with a leading blank for one-digit dates).
+On input, matches one or two digits, possibly with leading
+whitespace, that are expected to be the number of the day of the month.
+.TP
+\fB%Ec\fR
+On output, produces a locale-dependent representation of the date and
+time of day in the locale's alternative calendar. On input, matches
+whatever \fB%Ec\fR produces. The locale's alternative calendar need not
+be the Gregorian calendar.
+.TP
+\fB%EC\fR
+On output, produces a locale-dependent name of an era in the locale's
+alternative calendar. On input, matches the name of the era or any
+unique prefix.
+.TP
+\fB%EE\fR
+On output, produces the string \fBB.C.E.\fR or \fBC.E.\fR, or a
+string of the same meaning in the locale, to indicate whether \fB%Y\fR refers
+to years before or after Year 1 of the Common Era. On input, accepts
+the string \fBB.C.E.\fR, \fBB.C.\fR, \fBC.E.\fR, \fBA.D.\fR, or the
+abbreviation appropriate to the current locale, and uses it to fix
+whether \fB%Y\fR refers to years before or after Year 1 of the
+Common Era.
+.TP
+\fB%Ex\fR
+On output, produces a locale-dependent representation of the date
+in the locale's alternative calendar. On input, matches
+whatever \fB%Ex\fR produces. The locale's alternative calendar need not
+be the Gregorian calendar.
+.TP
+\fB%EX\fR
+On output, produces a locale-dependent representation of the
+time of day in the locale's alternative numerals. On input, matches
+whatever \fB%EX\fR produces.
+.TP
+\fB%Ey\fR
+On output, produces a locale-dependent number of the year of the era
+in the locale's alternative calendar and numerals. On input, matches
+such a number.
+.TP
+\fB%EY\fR
+On output, produces a representation of the year in the locale's
+alternative calendar and numerals. On input, matches what \fB%EY\fR
+produces. Often synonymous with \fB%EC%Ey\fR.
+.TP
+\fB%g\fR
+On output, produces a two-digit year number suitable for use with
+the week-based ISO8601 calendar; that is, the year number corresponds
+to the week number produced by \fB%V\fR. On input, accepts such
+a two-digit year number, possibly with leading whitespace.
+.TP
+\fB%G\fR
+On output, produces a four-digit year number suitable for use with
+the week-based ISO8601 calendar; that is, the year number corresponds
+to the week number produced by \fB%V\fR. On input, accepts such
+a four-digit year number, possibly with leading whitespace.
+.TP
+\fB%h\fR
+This format group is synonymous with \fB%b\fR.
+.TP
+\fB%H\fR
+On output, produces a two-digit number giving the hour of the day
+(00-23) on a 24-hour clock. On input, accepts such a number.
+.TP
+\fB%I\fR
+On output, produces a two-digit number giving the hour of the day
+(12-11) on a 12-hour clock. On input, accepts such a number.
+.TP
+\fB%j\fR
+On output, produces a three-digit number giving the day of the year
+(001-366). On input, accepts such a number.
+.TP
+\fB%J\fR
+On output, produces a string of digits giving the Julian Day Number.
+On input, accepts a string of digits and interprets it as a Julian Day Number.
+The Julian Day Number is a count of the number of calendar days
+that have elapsed since 1 January, 4713 BCE of the proleptic
+Julian calendar. The epoch time of 1 January 1970 corresponds
+to Julian Day Number 2440588.
+.TP
+\fB%k\fR
+On output, produces a one- or two-digit number giving the hour of the day
+(0-23) on a 24-hour clock. On input, accepts such a number.
+.TP
+\fB%l\fR
+On output, produces a one- or two-digit number giving the hour of the day
+(12-11) on a 12-hour clock. On input, accepts such a number.
+.TP
+\fB%m\fR
+On output, produces the number of the month (01-12) with exactly two
+digits. On input, accepts two digits and interprets them as the number
+of the month.
+.TP
+\fB%M\fR
+On output, produces the number of the minute of the hour (00-59)
+with exactly two digits. On input, accepts two digits and interprets them
+as the number of the minute of the hour.
+.TP
+\fB%N\fR
+On output, produces the number of the month (1-12) with one or two digits,
+and a leading blank for one-digit dates.
+On input, accepts one or two digits, possibly with leading whitespace,
+and interprets them as the number of the month.
+.TP
+\fB%Od\fR, \fB%Oe\fR, \fB%OH\fR, \fB%OI\fR, \fB%Ok\fR, \fB%Ol\fR, \fB%Om\fR, \fB%OM\fR, \fB%OS\fR, \fB%Ou\fR, \fB%Ow\fR, \fB%Oy\fR
+All of these format groups are synonymous with their counterparts
+without the
+.QW \fBO\fR ,
+except that the string is produced and parsed in the
+locale-dependent alternative numerals.
+.TP
+\fB%p\fR
+On output, produces an indicator for the part of the day, \fBAM\fR
+or \fBPM\fR, appropriate to the given locale. If the script of the
+given locale supports multiple letterforms, lowercase is preferred.
+On input, matches the representation \fBAM\fR or \fBPM\fR in
+the given locale, in either case.
+.TP
+\fB%P\fR
+On output, produces an indicator for the part of the day, \fBam\fR
+or \fBpm\fR, appropriate to the given locale. If the script of the
+given locale supports multiple letterforms, uppercase is preferred.
+On input, matches the representation \fBAM\fR or \fBPM\fR in
+the given locale, in either case.
+.TP
+\fB%Q\fR
+This format group is reserved for internal use within the Tcl library.
+.TP
+\fB%r\fR
+On output, produces a locale-dependent time of day representation on a
+12-hour clock. On input, accepts whatever \fB%r\fR produces.
+.TP
+\fB%R\fR
+On output, produces a locale-dependent time of day representation on a
+24-hour clock. On input, accepts whatever \fB%R\fR produces.
+.TP
+\fB%s\fR
+On output, simply formats the \fItimeVal\fR argument as a decimal
+integer and inserts it into the output string. On input, accepts
+a decimal integer and uses is as the time value without any further
+processing. Since \fB%s\fR uniquely determines a point in time, it
+overrides all other input formats.
+.TP
+\fB%S\fR
+On output, produces a two-digit number of the second of the minute
+(00-59). On input, accepts two digits and uses them as the second of the
+minute.
+.TP
+\fB%t\fR
+On output, produces a TAB character. On input, matches a TAB character.
+.TP
+\fB%T\fR
+Synonymous with \fB%H:%M:%S\fR.
+.TP
+\fB%u\fR
+On output, produces the number of the day of the week
+(\fB1\fR\(->Monday, \fB7\fR\(->Sunday). On input, accepts a single digit and
+interprets it as the day of the week. Sunday may be either \fB0\fR or
+\fB7\fR.
+.TP
+\fB%U\fR
+On output, produces the ordinal number of the week of the year
+(00-53). The first Sunday of the year is the first day of week 01. On
+input accepts two digits which are otherwise ignored. This format
+group is never used in determining an input date. This interpretation
+of the week of the year was once common in US banking but is now
+largely obsolete. See \fB%V\fR for the ISO8601 week number.
+.TP
+\fB%V\fR
+On output, produces the number of the ISO8601 week as a two digit
+number (01-53). Week 01 is the week containing January 4; or the first
+week of the year containing at least 4 days; or the week containing
+the first Thursday of the year (the three statements are
+equivalent). Each week begins on a Monday. On input, accepts the
+ISO8601 week number.
+.TP
+\fB%w\fR
+On output, produces the ordinal number of the day of the week
+(Sunday==0; Saturday==6). On input, accepts a single digit and
+interprets it as the day of the week; Sunday may be represented as
+either 0 or 7. Note that \fB%w\fR is not the ISO8601 weekday number,
+which is produced and accepted by \fB%u\fR.
+.TP
+\fB%W\fR
+On output, produces a week number (00-53) within the year; week 01
+begins on the first Monday of the year. On input, accepts two digits,
+which are otherwise ignored. This format group is never used in
+determining an input date. It is not the ISO8601 week number; that
+week is produced and accepted by \fB%V\fR.
+.TP
+\fB%x\fR
+On output, produces the date in a locale-dependent representation. On
+input, accepts whatever \fB%x\fR produces and is used to determine
+calendar date.
+.TP
+\fB%X\fR
+On output, produces the time of day in a locale-dependent
+representation. On input, accepts whatever \fB%X\fR produces and is used
+to determine time of day.
+.TP
+\fB%y\fR
+On output, produces the two-digit year of the century. On input,
+accepts two digits, and is used to determine calendar date. The
+date is presumed to lie between 1938 and 2037 inclusive. Note
+that \fB%y\fR does not yield a year appropriate for use with the ISO8601
+week number \fB%V\fR; programs should use \fB%g\fR for that purpose.
+.TP
+\fB%Y\fR
+On output, produces the four-digit calendar year. On input,
+accepts four digits and may be used to determine calendar date. Note
+that \fB%Y\fR does not yield a year appropriate for use with the ISO8601
+week number \fB%V\fR; programs should use \fB%G\fR for that purpose.
+.TP
+\fB%z\fR
+On output, produces the current time zone, expressed in hours and
+minutes east (+hhmm) or west (\-hhmm) of Greenwich. On input, accepts a
+time zone specifier (see \fBTIME ZONES\fR below) that will be used to
+determine the time zone.
+.TP
+\fB%Z\fR
+On output, produces the current time zone's name, possibly
+translated to the given locale. On input, accepts a time zone
+specifier (see \fBTIME ZONES\fR below) that will be used to determine the
+time zone. This option should, in general, be used on input only when
+parsing RFC822 dates. Other uses are fraught with ambiguity; for
+instance, the string \fBBST\fR may represent British Summer Time or
+Brazilian Standard Time. It is recommended that date/time strings for
+use by computers use numeric time zones instead.
+.TP
+\fB%%\fR
+On output, produces a literal
+.QW \fB%\fR
+character. On input, matches a literal
+.QW \fB%\fR
+character.
+.TP
+\fB%+\fR
+Synonymous with
+.QW "\fB%a %b %e %H:%M:%S %Z %Y\fR" .
+.SH "TIME ZONES"
+When the \fBclock\fR command is processing a local time, it has several
+possible sources for the time zone to use. In order of preference, they
+are:
+.IP [1]
+A time zone specified inside a string being parsed and matched by a \fB%z\fR
+or \fB%Z\fR format group.
+.IP [2]
+A time zone specified with the \fB\-timezone\fR option to the \fBclock\fR
+command (or, equivalently, by \fB\-gmt\fR \fB1\fR).
+.IP [3]
+A time zone specified in an environment variable \fBTCL_TZ\fR.
+.IP [4]
+A time zone specified in an environment variable \fBTZ\fR.
+.IP [5]
+The local time zone from the Control Panel on Windows systems.
+.IP [6]
+The C library's idea of the local time zone, as defined by the
+\fBmktime\fR and \fBlocaltime\fR functions.
+.PP
+In case [1] \fIonly,\fR the string is tested to see if it is one
+of the strings:
+.CS
+ gmt ut utc bst wet wat at
+ nft nst ndt ast adt est edt
+ cst cdt mst mdt pst pdt yst
+ ydt hst hdt cat ahst nt idlw
+ cet cest met mewt mest swt sst
+ eet eest bt it zp4 zp5 ist
+ zp6 wast wadt jt cct jst cast
+ cadt east eadt gst nzt nzst nzdt
+ idle
+.CE
+If it is a string in the above list, it designates a known
+time zone, and is interpreted as such.
+.PP
+For time zones in case [1] that do not match any of the above strings,
+and always for cases [2]-[6], the following rules apply.
+.PP
+If the time zone begins with a colon, it is one of a
+standardized list of names like \fB:America/New_York\fR
+that give the rules for various locales. A complete list
+of the location names is too lengthy to be listed here.
+On most Tcl installations, the definitions of the locations
+are to be found in named files in the directory
+.QW "\fI/no_backup/tools/lib/tcl8.5/clock/tzdata\fR" .
+On some Unix systems, these files are omitted, and the definitions are
+instead obtained from system files in
+.QW "\fI/usr/share/zoneinfo\fR" ,
+.QW "\fI/usr/share/lib/zoneinfo\fR"
+or
+.QW "\fI/usr/local/etc/zoneinfo\fR" .
+As a special case, the name \fB:localtime\fR refers to
+the local time zone as defined by the C library.
+.PP
+A time zone string consisting of a plus or minus sign followed by
+four or six decimal digits is interpreted as an offset in
+hours, minutes, and seconds (if six digits are present) from
+UTC. The plus sign denotes a sign east of Greenwich;
+the minus sign one west of Greenwich.
+.PP
+A time zone string conforming to the Posix specification of the \fBTZ\fR
+environment variable will be recognized. The specification
+may be found at
+\fIhttp://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html\fR.
+.PP
+Any other time zone string is processed by prefixing a colon and attempting
+to use it as a location name, as above.
+.SH "LOCALIZATION"
+Developers wishing to localize the date and time formatting and parsing
+are referred to \fIhttp://tip.tcl.tk/173\fR for a
+specification.
+.SH "FREE FORM SCAN"
+If the \fBclock scan\fR command is invoked without a \fB\-format\fR
+option, then it requests a \fIfree-form scan.\fR \fI
+This form of scan is deprecated.\fR The reason for the deprecation
+is that there are too many ambiguities. (Does the string
+.QW 2000
+represent a year, a time of day, or a quantity?) No set of rules
+for interpreting free-form dates and times has been found to
+give unsurprising results in all cases.
+.PP
+If free-form scan is used, only the \fB\-base\fR and \fB\-gmt\fR
+options are accepted. The \fB\-timezone\fR and \fB\-locale\fR
+options will result in an error if \fB\-format\fR is not supplied.
+.PP
+For the benefit of users who need to understand legacy code that
+uses free-form scan, the documentation for how free-form scan
+interprets a string is included here:
+.PP
+If only a time is
+specified, the current date is assumed. If the \fIinputString\fR
+does not contain a
+time zone mnemonic, the local time zone is assumed, unless the \fB\-gmt\fR
argument is true, in which case the clock value is calculated assuming
that the specified time is relative to Greenwich Mean Time.
-\fB-gmt\fR, if specified, affects only the computed time value; it does not
-impact the interpretation of \fB-base\fR.
-.sp
+\fB\-gmt\fR, if specified, affects only the computed time value; it does not
+impact the interpretation of \fB\-base\fR.
+.PP
If the \fB\-base\fR flag is specified, the next argument should contain
an integer clock value. Only the date in this value is used, not the
time. This is useful for determining the time on a specific day or
doing other date-relative conversions.
-.sp
-The \fIdateString\fR consists of zero or more specifications of the
+.PP
+The \fIinputString\fR argument consists of zero or more specifications of the
following form:
-.RS
.TP
\fItime\fR
-A time of day, which is of the form: \fIhh\fR?\fI:mm\fR?\fI:ss\fR??
-?\fImeridian\fR? ?\fIzone\fR? or \fIhhmm \fR?\fImeridian\fR?
-?\fIzone\fR?. If no meridian is specified, \fIhh\fR is interpreted on
+A time of day, which is of the form: \fBhh?:mm?:ss?? ?meridian? ?zone?\fR
+or \fBhhmm ?meridian? ?zone?\fR
+If no meridian is specified, \fBhh\fR is interpreted on
a 24-hour clock.
.TP
\fIdate\fR
A specific month and day with optional year. The
-acceptable formats are \fImm/dd\fR?\fI/yy\fR?, \fImonthname dd\fR
-?, \fIyy\fR?, \fIdd monthname \fR?\fIyy\fR?, \fIday, dd monthname
-yy\fR, \fI?CC?yymmdd\fR, \fI?CC?yy-mm-dd\fR, \fIdd-monthname-?CC?yy\fR.
+acceptable formats are
+.QW "\fBmm/dd\fR?\fB/yy\fR?" ,
+.QW "\fBmonthname dd\fR?\fB, yy\fR?" ,
+.QW "\fBday, dd monthname \fR?\fByy\fR?" ,
+.QW "\fBdd monthname yy\fR" ,
+.QW "?\fBCC\fR?\fByymmdd\fR" ,
+and
+.QW "\fBdd-monthname-\fR?\fBCC\fR?\fByy\fR" .
The default year is the current year. If the year is less
-.VS
than 100, we treat the years 00-68 as 2000-2068 and the years 69-99
as 1969-1999. Not all platforms can represent the years 38-70, so
an error may result if these years are used.
-.VE
.TP
\fIISO 8601 point-in-time\fR
-An ISO 8601 point-in-time specification, such as \fICCyymmddThhmmss\fR, where
-T is the literal T, \fICCyymmdd hhmmss\fR, or
-\fICCyymmddThh:mm:ss\fR. Note that only these three formats are accepted.
+An ISO 8601 point-in-time specification, such as
+.QW \fICCyymmdd\fBT\fIhhmmss\fR,
+where \fBT\fR is the literal
+.QW T ,
+.QW "\fICCyymmdd hhmmss\fR" ,
+or
+.QW \fICCyymmdd\fBT\fIhh:mm:ss\fR .
+Note that only these three formats are accepted.
The command does \fInot\fR accept the full range of point-in-time
specifications specified in ISO8601. Other formats can be recognized by
-using commands such as \fBregexp\fR to extract their fields and reorganize
-them into a form accepted by the \fBclock scan\fR command.
+giving an explicit \fI\-format\fR option to the \fBclock scan\fR command.
.TP
\fIrelative time\fR
-A specification relative to the current time. The format is \fInumber
-unit\fR acceptable units are \fByear\fR, \fBfortnight\fR, \fBmonth\fR, \fBweek\fR, \fBday\fR,
+A specification relative to the current time. The format is \fBnumber
+unit\fR. Acceptable units are \fByear\fR, \fBfortnight\fR,
+\fBmonth\fR, \fBweek\fR, \fBday\fR,
\fBhour\fR, \fBminute\fR (or \fBmin\fR), and \fBsecond\fR (or \fBsec\fR). The
unit can be specified as a singular or plural, as in \fB3 weeks\fR.
These modifiers may also be specified:
\fBtomorrow\fR, \fByesterday\fR, \fBtoday\fR, \fBnow\fR,
\fBlast\fR, \fBthis\fR, \fBnext\fR, \fBago\fR.
-.RE
-.sp
-.RS
+.PP
The actual date is calculated according to the following steps.
+.PP
First, any absolute date and/or time is processed and converted.
Using that time as the base, day-of-week specifications are added.
Next, relative specifications are used. If a date or day is
@@ -262,29 +893,9 @@ used. Finally, a correction is applied so that the correct hour of
the day is produced after allowing for daylight savings time
differences and the correct date is given when going from the end
of a long month to a short month.
-.sp
-Daylight savings time correction is applied only when the relative time
-is specified in units of days or more, ie, days, weeks, fortnights, months or
-years. This means that when crossing the daylight savings time boundary,
-different results will be given for \fBclock scan "1 day"\fR and
-\fBclock scan "24 hours"\fR:
-.CS
-.ta 6c
-% \fBclock scan\fR "1 day" -base [\fBclock scan\fR 1999-10-31]
-941443200
-% \fBclock scan\fR "24 hours" -base [\fBclock scan\fR 1999-10-31]
-941439600
-.CE
-.RE
-.TP
-\fBclock seconds\fR
-Return the current date and time as a system-dependent integer value. The
-unit of the value is seconds, allowing it to be used for relative time
-calculations. The value is usually defined as total elapsed time from
-an ``epoch''. You shouldn't assume the value of the epoch.
-
.SH "SEE ALSO"
-date(1), time(n)
-
+msgcat(n)
.SH KEYWORDS
clock, date, time
+.SH "COPYRIGHT"
+Copyright (c) 2004 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
diff --git a/doc/close.n b/doc/close.n
index a1c5f01..4ef3c7d 100644
--- a/doc/close.n
+++ b/doc/close.n
@@ -10,7 +10,7 @@
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
-close \- Close an open channel.
+close \- Close an open channel
.SH SYNOPSIS
\fBclose \fIchannelId\fR
.BE
@@ -19,17 +19,14 @@ close \- Close an open channel.
.PP
Closes the channel given by \fIchannelId\fR.
.PP
-.VS
\fIChannelId\fR must be an identifier for an open channel such as a
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.
-.VE
.PP
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.
-.VS "" br
.PP
If the channel is blocking, the command does not return until all output
is flushed.
@@ -37,11 +34,9 @@ If the channel is nonblocking 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.
-.VE
.PP
If \fIchannelId\fR is a blocking channel for a command pipeline then
\fBclose\fR waits for the child processes to complete.
-.VS "" br
.PP
If the channel is shared between interpreters, then \fBclose\fR
makes \fIchannelId\fR unavailable in the invoking interpreter but has no
@@ -54,7 +49,6 @@ When the last interpreter in which the channel is registered invokes
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.
-.VE
.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
diff --git a/doc/concat.n b/doc/concat.n
index e52d978..f7317c4 100644
--- a/doc/concat.n
+++ b/doc/concat.n
@@ -24,27 +24,33 @@ into a single list.
It permits any number of arguments;
if no \fIarg\fRs are supplied, the result is an empty string.
.SH EXAMPLES
-Although \fBconcat\fR will concatenate lists (so the command:
+Although \fBconcat\fR will concatenate lists, flattening them in the process
+(so giving the following interactive session):
+.PP
.CS
-\fBconcat\fR a b {c d e} {f {g h}}
+\fI%\fR \fBconcat\fR a b {c d e} {f {g h}}
+\fIa b c d e f {g h}\fR
.CE
-will return "\fBa b c d e f {g h}\fR" as its result), it will also
-concatenate things that are not lists, and hence the command:
+.PP
+it will also concatenate things that are not lists, as can be seen from this
+session:
+.PP
.CS
-\fBconcat\fR " a b {c " d " e} f"
+\fI%\fR \fBconcat\fR " a b {c " d " e} f"
+\fIa b {c d e} f\fR
.CE
-will return "\fBa b {c d e} f\fR" as its result.
.PP
-Note that the concatenation does not remove spaces from the middle of
-its arguments, so the command:
+Note also that the concatenation does not remove spaces from the middle of
+values, as can be seen here:
+.PP
.CS
-\fBconcat\fR "a b c" { d e f }
+\fI%\fR \fBconcat\fR "a b c" { d e f }
+\fIa b c d e f\fR
.CE
-will return "\fBa b c d e f\fR" (i.e. with three spaces between
-the \fBa\fR, the \fBb\fR and the \fBc\fR).
-
+.PP
+(i.e., there are three spaces between each of the \fBa\fR, the \fBb\fR and the
+\fBc\fR).
.SH "SEE ALSO"
-append(n), eval(n)
-
+append(n), eval(n), join(n)
.SH KEYWORDS
concatenate, join, lists
diff --git a/doc/dde.n b/doc/dde.n
index 7222f51..ce00aee 100644
--- a/doc/dde.n
+++ b/doc/dde.n
@@ -6,26 +6,26 @@
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.so man.macros
-.TH dde n 1.2 dde "Tcl Bundled Packages"
+.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.2\fR
+\fBpackage require dde 1.3\fR
.sp
-\fBdde eval\fR ?\fB\-async\fR? \fIservice cmd\fR ?\fIarg ...\fR?
+\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
.sp
-\fBdde poke \fIservice topic item data\fR
-.sp
-\fBdde request\fR ?\fB\-binary\fR? \fIservice topic data\fR
+\fBdde poke\fR \fIservice topic item data\fR
.sp
-\fBdde servername\fR ?\fItopic\fR?
+\fBdde request\fR ?\fB\-binary\fR? \fIservice topic item\fR
.sp
\fBdde services \fIservice topic\fR
+.sp
+\fBdde eval\fR ?\fB\-async\fR? \fItopic cmd \fR?\fIarg arg ...\fR?
.BE
.SH DESCRIPTION
@@ -37,23 +37,40 @@ transaction needs a \fIservice name\fR and a \fItopic\fR. Both the
\fIservice name\fR and \fItopic\fR are application defined; Tcl uses
the service name \fBTclEval\fR, while the topic name is the name of the
interpreter given by \fBdde servername\fR. Other applications have their
-own \fIservice name\fRs and \fItopic\fRs. For instance, Microsoft Excel
+own \fIservice names\fR and \fItopics\fR. For instance, Microsoft Excel
has the service name \fBExcel\fR.
.PP
-The \fBeval\fR and \fBexecute\fR commands accept the option \fB\-async\fR:
-
.SH "DDE COMMANDS"
.PP
The following commands are a subset of the full Dynamic Data Exchange
set of commands.
.TP
-\fBdde servername \fR?\fItopic\fR?
+\fBdde servername \fR?\fB\-force\fR? ?\fB\-handler \fIproc\fR? ?\fB\-\|\-\fR? ?\fItopic\fR?
+.
\fBdde servername\fR registers the interpreter as a DDE server with
the service name \fBTclEval\fR and the topic name specified by \fItopic\fR.
If no \fItopic\fR is given, \fBdde servername\fR returns the name
-of the current topic or the empty string if it is not registered as a service.
+of the current topic or the empty string if it is not registered as a
+service. If the given \fItopic\fR name is already in use, then a
+suffix of the form
+.QW " #2"
+or
+.QW " #3"
+is appended to the name to make it
+unique. The command's result will be the name actually used. The
+\fB\-force\fR option is used to force registration of precisely the
+given \fItopic\fR name.
+.RS
+.PP
+The \fB\-handler\fR option specifies a Tcl procedure that will be called to
+process calls to the dde server. If the package has been loaded into a
+safe interpreter then a \fB\-handler\fR procedure must be defined. The
+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 takes the \fIdata\fR and sends it to the server indicated
by \fIservice\fR with the topic indicated by \fItopic\fR. Typically,
\fIservice\fR is the name of an application, and \fItopic\fR is a file to
@@ -65,6 +82,7 @@ script did not run, unless the \fB\-async\fR flag was used, in which case
the command returns immediately with no error.
.TP
\fBdde poke \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,
\fIservice\fR is the name of an application. \fItopic\fR is application
@@ -74,6 +92,7 @@ it must always be non-null. The \fIdata\fR field is given to the remote
application.
.TP
\fBdde request\fR ?\fB\-binary\fR? \fIservice topic item\fR
+.
\fBdde request\fR is typically used to get the value of something; the
value of a cell in Microsoft Excel or the text of a selection in
Microsoft Word. \fIservice\fR is typically the name of an application,
@@ -84,24 +103,25 @@ string with terminating null. If \fB\-binary\fR is specified, the
result is returned as a byte array.
.TP
\fBdde services \fIservice topic\fR
+.
\fBdde services\fR returns a list of service-topic pairs that
currently exist on the machine. If \fIservice\fR and \fItopic\fR are
-both null strings ({}), then all service-topic pairs currently
-available on the system are returned. If \fIservice\fR is null and
+both empty strings ({}), then all service-topic pairs currently
+available on the system are returned. If \fIservice\fR is empty and
\fItopic\fR is not, then all services with the specified topic are
-returned. If \fIservice\fR is not null and \fItopic\fR is, all topics
-for a given service are returned. If both are not null, if that
-service-topic pair currently exists, it is returned; otherwise, null
-is returned.
+returned. If \fIservice\fR is non-empty and \fItopic\fR is, all topics
+for a given service are returned. If both are non-empty, if that
+service-topic pair currently exists, it is returned; otherwise, an
+empty string is returned.
.TP
\fBdde eval\fR ?\fB\-async\fR? \fItopic cmd \fR?\fIarg arg ...\fR?
+.
\fBdde eval\fR evaluates a command and its arguments using the interpreter
specified by \fItopic\fR. The DDE service must be the \fBTclEval\fR
service. 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. This command can be used to replace \fBsend\fR on Windows.
-
+with no error. This command can be used to replace send on Windows.
.SH "DDE AND TCL"
A Tcl interpreter always has a service name of \fBTclEval\fR. Each
different interpreter of all running Tcl applications must be
@@ -134,7 +154,6 @@ without adding the \fB&\fR to place the process in the background).
If for any reason the event queue is not flushed, DDE commands may
hang until the event queue is flushed. This can create a deadlock
situation.
-
.SH EXAMPLE
This asks Internet Explorer (which must already be running) to go to a
particularly important website:
@@ -142,9 +161,7 @@ particularly important website:
package require dde
\fBdde execute\fR iexplore WWW_OpenURL http://www.tcl.tk/
.CE
-
.SH "SEE ALSO"
tk(n), winfo(n), send(n)
-
.SH KEYWORDS
application, dde, name, remote execution
diff --git a/doc/dict.n b/doc/dict.n
new file mode 100644
index 0000000..28c4f7c
--- /dev/null
+++ b/doc/dict.n
@@ -0,0 +1,389 @@
+'\"
+'\" Copyright (c) 2003 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 dict n 8.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+dict \- Manipulate dictionaries
+.SH SYNOPSIS
+\fBdict \fIoption arg \fR?\fIarg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+Performs one of several operations on dictionary values or variables
+containing dictionary values (see the \fBDICTIONARY VALUES\fR section
+below for a description), depending on \fIoption\fR. The legal
+\fIoption\fRs (which may be abbreviated) are:
+.TP
+\fBdict append \fIdictionaryVariable key \fR?\fIstring ...\fR?
+This appends the given string (or strings) to the value that the given
+key maps to in the dictionary value contained in the given variable,
+writing the resulting dictionary value back to that variable.
+Non-existent keys are treated as if they map to an empty string.
+.TP
+\fBdict create \fR?\fIkey value ...\fR?
+Create a new dictionary that contains each of the key/value mappings
+listed as arguments (keys and values alternating, with each key being
+followed by its associated value.)
+.TP
+\fBdict exists \fIdictionaryValue key \fR?\fIkey ...\fR?
+This returns a boolean value indicating whether the given key (or path
+of keys through a set of nested dictionaries) exists in the given
+dictionary value. This returns a true value exactly when \fBdict
+get\fR on that path will succeed.
+.TP
+\fBdict filter \fIdictionaryValue filterType arg \fR?\fIarg ...\fR?
+This takes a dictionary value and returns a new dictionary that
+contains just those key/value pairs that match the specified filter
+type (which may be abbreviated.) Supported filter types are:
+.RS
+.TP
+\fBdict filter \fIdictionaryValue \fBkey \fIglobPattern\fR
+The key rule only matches those key/value pairs whose keys match the
+given pattern (in the style of \fBstring match\fR.)
+.TP
+\fBdict filter \fIdictionaryValue \fBscript {\fIkeyVar valueVar\fB} \fIscript\fR
+The script rule tests for matching by assigning the key to the
+\fIkeyVar\fR and the value to the \fIvalueVar\fR, and then evaluating
+the given script which should return a boolean value (with the
+key/value pair only being included in the result of the \fBdict
+filter\fR when a true value is returned.) Note that the first
+argument after the rule selection word is a two-element list. If the
+\fIscript\fR returns with a condition of \fBTCL_BREAK\fR, no further
+key/value pairs are considered for inclusion in the resulting
+dictionary, and a condition of \fBTCL_CONTINUE\fR is equivalent to a false
+result. The key/value pairs are tested in the order in which the keys
+were inserted into the dictionary.
+.TP
+\fBdict filter \fIdictionaryValue \fBvalue \fIglobPattern\fR
+The value rule only matches those key/value pairs whose values match
+the given pattern (in the style of \fBstring match\fR.)
+.RE
+.TP
+\fBdict for {\fIkeyVar valueVar\fB} \fIdictionaryValue body\fR
+This command takes three arguments, the first 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 \fBforeach\fR.)
+The result of the command is an empty string. If any evaluation of the
+body generates a \fBTCL_BREAK\fR result, no further pairs from the
+dictionary will be iterated over and the \fBdict for\fR command will
+terminate successfully immediately. If any evaluation of the body
+generates a \fBTCL_CONTINUE\fR result, this shall be treated exactly like a
+normal \fBTCL_OK\fR result. The order of iteration is the order in
+which the keys were inserted into the dictionary.
+.TP
+\fBdict get \fIdictionaryValue \fR?\fIkey ...\fR?
+Given a dictionary value (first argument) and a key (second argument),
+this will retrieve the value for that key. Where several keys are
+supplied, the behaviour of the command shall be as if the result of
+\fBdict get $dictVal $key\fR was passed as the first argument to
+\fBdict get\fR with the remaining arguments as second (and possibly
+subsequent) arguments. This facilitates lookups in nested
+dictionaries. For example, the following two commands are equivalent:
+.RS
+.PP
+.CS
+dict get $dict foo bar spong
+dict get [dict get [dict get $dict foo] bar] spong
+.CE
+.PP
+If no keys are provided, \fBdict get\fR will return a list containing pairs of
+elements in a manner similar to \fBarray get\fR. That is, the first
+element of each pair would be the key and the second element would be
+the value for that key.
+.PP
+It is an error to attempt to retrieve a value for a key that is not
+present in the dictionary.
+.RE
+.TP
+\fBdict incr \fIdictionaryVariable key \fR?\fIincrement\fR?
+This adds the given increment value (an integer that defaults to 1 if
+not specified) to the value that the given key maps to in the
+dictionary value contained in the given variable, writing the
+resulting dictionary value back to that variable. Non-existent keys
+are treated as if they map to 0. It is an error to increment a value
+for an existing key if that value is not an integer.
+.TP
+\fBdict info \fIdictionaryValue\fR
+This returns information (intended for display to people) about the
+given dictionary though the format of this data is dependent on the
+implementation of the dictionary. For dictionaries that are
+implemented by hash tables, it is expected that this will return the
+string produced by \fBTcl_HashStats\fR, similar to \fBarray statistics\fR.
+.TP
+\fBdict keys \fIdictionaryValue \fR?\fIglobPattern\fR?
+Return a list of all keys in the given dictionary value. If a pattern
+is supplied, only those keys that match it (according to the rules of
+\fBstring match\fR) will be returned. The returned keys will be in the
+order that they were inserted into the dictionary.
+.TP
+\fBdict lappend \fIdictionaryVariable key \fR?\fIvalue ...\fR?
+This appends the given items to the list value that the given key maps
+to in the dictionary value contained in the given variable, writing
+the resulting dictionary value back to that variable. Non-existent
+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 merge \fR?\fIdictionaryValue ...\fR?
+Return a dictionary that contains the contents of each of the
+\fIdictionaryValue\fR arguments. Where two (or more) dictionaries
+contain a mapping for the same key, the resulting dictionary maps that
+key to the value according to the last dictionary on the command line
+containing a mapping for that key.
+.TP
+\fBdict remove \fIdictionaryValue \fR?\fIkey ...\fR?
+Return a new dictionary that is a copy of an old one passed in as
+first argument except without mappings for each of the keys listed.
+It is legal for there to be no keys to remove, and it also legal for
+any of the keys to be removed to not be present in the input
+dictionary in the first place.
+.TP
+\fBdict replace \fIdictionaryValue \fR?\fIkey value ...\fR?
+Return a new dictionary that is a copy of an old one passed in as
+first argument except with some values different or some extra
+key/value pairs added. It is legal for this command to be called with
+no key/value pairs, but illegal for this command to be called with a
+key but no value.
+.TP
+\fBdict set \fIdictionaryVariable key \fR?\fIkey ...\fR? \fIvalue\fR
+This operation takes the name of a variable containing a dictionary
+value and places an updated dictionary value in that variable
+containing a mapping from the given key to the given value. When
+multiple keys are present, this operation creates or updates a chain
+of nested dictionaries.
+.TP
+\fBdict size \fIdictionaryValue\fR
+Return the number of key/value mappings in the given dictionary value.
+.TP
+\fBdict unset \fIdictionaryVariable key \fR?\fIkey ...\fR?
+This operation (the companion to \fBdict set\fR) takes the name of a
+variable containing a dictionary value and places an updated
+dictionary value in that variable that does not contain a mapping for
+the given key. Where multiple keys are present, this describes a path
+through nested dictionaries to the mapping to remove. At least one key
+must be specified, but the last key on the key-path need not exist.
+All other components on the path must exist.
+.TP
+\fBdict update \fIdictionaryVariable key varName \fR?\fIkey varName ...\fR? \fIbody\fR
+Execute the Tcl script in \fIbody\fR with the value for each \fIkey\fR
+(as found by reading the dictionary value in \fIdictionaryVariable\fR)
+mapped to the variable \fIvarName\fR. There may be multiple
+\fIkey\fR/\fIvarName\fR pairs. If a \fIkey\fR does not have a mapping,
+that corresponds to an unset \fIvarName\fR. When \fIbody\fR
+terminates, any changes made to the \fIvarName\fRs is reflected back
+to the dictionary within \fIdictionaryVariable\fR (unless
+\fIdictionaryVariable\fR itself becomes unreadable, when all updates
+are silently discarded), even if the result of \fIbody\fR is an error
+or some other kind of exceptional exit. The result of \fBdict
+update\fR is (unless some kind of error occurs) the result of the
+evaluation of \fIbody\fR.
+.RS
+.PP
+Each \fIvarName\fR is mapped in the scope enclosing the \fBdict update\fR;
+it is recommended that this command only be used in a local scope
+(\fBproc\fRedure or lambda term for \fBapply\fR). Because of
+this, the variables set by \fBdict update\fR will continue to
+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.
+.RE
+.TP
+\fBdict values \fIdictionaryValue \fR?\fIglobPattern\fR?
+Return a list of all values in the given dictionary value. If a
+pattern is supplied, only those values that match it (according to the
+rules of \fBstring match\fR) will be returned. The returned values
+will be in the order of that the keys associated with those values
+were inserted into the dictionary.
+.TP
+\fBdict with \fIdictionaryVariable \fR?\fIkey ...\fR? \fIbody\fR
+Execute the Tcl script in \fIbody\fR with the value for each key in
+\fIdictionaryVariable\fR mapped (in a manner similarly to \fBdict
+update\fR) to a variable with the same name. Where one or more
+\fIkey\fRs are available, these indicate a chain of nested
+dictionaries, with the innermost dictionary being the one opened out
+for the execution of \fIbody\fR. As with \fBdict update\fR, making
+\fIdictionaryVariable\fR unreadable will make the updates to the
+dictionary be discarded, and this also happens if the contents of
+\fIdictionaryVariable\fR are adjusted so that the chain of
+dictionaries no longer exists. The result of \fBdict with\fR is
+(unless some kind of error occurs) the result of the evaluation of
+\fIbody\fR.
+.RS
+.PP
+The variables are mapped in the scope enclosing the \fBdict with\fR;
+it is recommended that this command only be used in a local scope
+(\fBproc\fRedure or lambda term for \fBapply\fR). Because of
+this, the variables set by \fBdict with\fR will continue to
+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
+Dictionaries are values that contain an efficient, order-preserving
+mapping from arbitrary keys to arbitrary values.
+Each key in the dictionary maps to a single value.
+They have a textual format that is exactly that of any list with an
+even number of elements, with each mapping in the dictionary being
+represented as two items in the list. When a command takes a
+dictionary and produces a new dictionary based on it (either returning
+it or writing it back into the variable that the starting dictionary
+was read from) the new dictionary will have the same order of keys,
+modulo any deleted keys and with new keys added on to the end.
+When a string is interpreted as a dictionary and it would otherwise
+have duplicate keys, only the last value for a particular key is used;
+the others are ignored, meaning that,
+.QW "apple banana"
+and
+.QW "apple carrot apple banana"
+are equivalent dictionaries (with different string representations).
+.PP
+Operations that derive a new dictionary from an old one (e.g., updates
+like \fBdict set\fR and \fBdict unset\fR) preserve the order of keys
+in the dictionary. The exceptions to this are for any new keys they
+add, which are appended to the sequence, and any keys that are
+removed, which are excised from the order.
+.SH EXAMPLES
+.PP
+Basic dictionary usage:
+.PP
+.CS
+# Make a dictionary to map extensions to descriptions
+set filetypes [\fBdict create\fR .txt "Text File" .tcl "Tcl File"]
+
+# Add/update the dictionary
+\fBdict set\fR filetypes .tcl "Tcl Script"
+\fBdict set\fR filetypes .tm "Tcl Module"
+\fBdict set\fR filetypes .gif "GIF Image"
+\fBdict set\fR filetypes .png "PNG Image"
+
+# Simple read from the dictionary
+set ext ".tcl"
+set desc [\fBdict get\fR $filetypes $ext]
+puts "$ext is for a $desc"
+
+# Somewhat more complex, with existence test
+foreach filename [glob *] {
+ set ext [file extension $filename]
+ if {[\fBdict exists\fR $filetypes $ext]} {
+ puts "$filename is a [\fBdict get\fR $filetypes $ext]"
+ }
+}
+.CE
+.PP
+Constructing and using nested dictionaries:
+.PP
+.CS
+# Data for one employee
+\fBdict set\fR employeeInfo 12345-A forenames "Joe"
+\fBdict set\fR employeeInfo 12345-A surname "Schmoe"
+\fBdict set\fR employeeInfo 12345-A street "147 Short Street"
+\fBdict set\fR employeeInfo 12345-A city "Springfield"
+\fBdict set\fR employeeInfo 12345-A phone "555-1234"
+# Data for another employee
+\fBdict set\fR employeeInfo 98372-J forenames "Anne"
+\fBdict set\fR employeeInfo 98372-J surname "Other"
+\fBdict set\fR employeeInfo 98372-J street "32995 Oakdale Way"
+\fBdict set\fR employeeInfo 98372-J city "Springfield"
+\fBdict set\fR employeeInfo 98372-J phone "555-8765"
+# The above data probably ought to come from a database...
+
+# Print out some employee info
+set i 0
+puts "There are [\fBdict size\fR $employeeInfo] employees"
+\fBdict for\fR {id info} $employeeInfo {
+ puts "Employee #[incr i]: $id"
+ \fBdict with\fR info {
+ puts " Name: $forenames $surname"
+ puts " Address: $street, $city"
+ puts " Telephone: $phone"
+ }
+}
+# Another way to iterate and pick out names...
+foreach id [\fBdict keys\fR $employeeInfo] {
+ puts "Hello, [\fBdict get\fR $employeeInfo $id forenames]!"
+}
+.CE
+.PP
+A localizable version of \fBstring toupper\fR:
+.PP
+.CS
+# Set up the basic C locale
+set capital [\fBdict create\fR C [\fBdict create\fR]]
+foreach c [split {abcdefghijklmnopqrstuvwxyz} ""] {
+ \fBdict set\fR capital C $c [string toupper $c]
+}
+
+# English locales can luckily share the "C" locale
+\fBdict set\fR capital en [\fBdict get\fR $capital C]
+\fBdict set\fR capital en_US [\fBdict get\fR $capital C]
+\fBdict set\fR capital en_GB [\fBdict get\fR $capital C]
+
+# ... and so on for other supported languages ...
+
+# Now get the mapping for the current locale and use it.
+set upperCaseMap [\fBdict get\fR $capital $env(LANG)]
+set upperCase [string map $upperCaseMap $string]
+.CE
+.PP
+Showing the detail of \fBdict with\fR:
+.PP
+.CS
+proc sumDictionary {varName} {
+ upvar 1 $varName vbl
+ foreach key [\fBdict keys\fR $vbl] {
+ # Manufacture an entry in the subdictionary
+ \fBdict set\fR vbl $key total 0
+ # Add the values and remove the old
+ \fBdict with\fR vbl $key {
+ set total [expr {$x + $y + $z}]
+ unset x y z
+ }
+ }
+ puts "last total was $total, for key $key"
+}
+
+set myDict {
+ a {x 1 y 2 z 3}
+ b {x 6 y 5 z 4}
+}
+
+sumDictionary myDict
+# prints: \fIlast total was 15, for key b\fR
+
+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)
+.SH KEYWORDS
+dictionary, create, update, lookup, iterate, filter
diff --git a/doc/encoding.n b/doc/encoding.n
index 5950246..f8f3d54 100644
--- a/doc/encoding.n
+++ b/doc/encoding.n
@@ -39,6 +39,19 @@ 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.
.TP
+\fBencoding dirs\fR ?\fIdirectoryList\fR?
+.VS 8.5
+Tcl can load encoding data files from the file system that describe
+additional encodings for it to work with. This command sets the search
+path for \fB*.enc\fR encoding data files to the list of directories
+\fIdirectoryList\fR. If \fIdirectoryList\fR is omitted then the
+command returns the current list of directories that make up the
+search path. It is an error for \fIdirectoryList\fR to not be a valid
+list. If, when a search for an encoding data file is happening, an
+element in \fIdirectoryList\fR does not refer to a readable,
+searchable directory, that element is ignored.
+.VE 8.5
+.TP
\fBencoding names\fR
Returns a list containing the names of all of the encodings that are
currently available.
@@ -67,10 +80,11 @@ of the original string. The \fBencoding\fR command can be used to
convert this string to the expected Japanese Unicode characters. For
example,
.CS
-set s [\fBencoding convertfrom\fR euc-jp "\\xA4\\xCF"]
+set s [\fBencoding convertfrom\fR euc-jp "\exA4\exCF"]
.CE
-would return the Unicode string "\\u306F", which is the Hiragana
-letter HA.
+would return the Unicode string
+.QW "\eu306F" ,
+which is the Hiragana letter HA.
.SH "SEE ALSO"
Tcl_GetEncoding(3)
diff --git a/doc/error.n b/doc/error.n
index 8c47ba3..77391e5 100644
--- a/doc/error.n
+++ b/doc/error.n
@@ -21,36 +21,42 @@ Returns a \fBTCL_ERROR\fR code, which causes command interpretation to be
unwound. \fIMessage\fR is a string that is returned to the application
to indicate what went wrong.
.PP
-If the \fIinfo\fR argument is provided and is non-empty,
-it is used to initialize the global variable \fBerrorInfo\fR.
-\fBerrorInfo\fR is used to accumulate a stack trace of what
-was in progress when an error occurred; as nested commands unwind,
-the Tcl interpreter adds information to \fBerrorInfo\fR. If the
-\fIinfo\fR argument is present, it is used to initialize
-\fBerrorInfo\fR and the first increment of unwind information
-will not be added by the Tcl interpreter. In other
+The \fB\-errorinfo\fR return option of an interpreter is used
+to accumulate a stack trace of what was in progress when an
+error occurred; as nested commands unwind,
+the Tcl interpreter adds information to the \fB\-errorinfo\fR
+return option. If the \fIinfo\fR argument is present, it is
+used to initialize the \fB\-errorinfo\fR return options and
+the first increment of unwind information
+will not be added by the Tcl interpreter.
+In other
words, the command containing the \fBerror\fR command will not appear
-in \fBerrorInfo\fR; in its place will be \fIinfo\fR.
-This feature is most useful in conjunction with the \fBcatch\fR command:
+in the stack trace; in its place will be \fIinfo\fR.
+Historically, this feature had been most useful in conjunction
+with the \fBcatch\fR command:
if a caught error cannot be handled successfully, \fIinfo\fR can be used
to return a stack trace reflecting the original point of occurrence
of the error:
.CS
\fBcatch {...} errMsg
-set savedInfo $errorInfo
+set savedInfo $::errorInfo
\&...
error $errMsg $savedInfo\fR
.CE
+When working with Tcl 8.5 or later, the following code
+should be used instead:
+.CS
+\fBcatch {...} errMsg options
+\&...
+return -options $options $errMsg\fR
+.CE
.PP
If the \fIcode\fR argument is present, then its value is stored
-in the \fBerrorCode\fR global variable. This variable is intended
-to hold a machine-readable description of the error in cases where
-such information is available; see the \fBtclvars\fR manual
-page for information on the proper format for the variable.
-If the \fIcode\fR argument is not
-present, then \fBerrorCode\fR is automatically reset to
-``NONE'' by the Tcl interpreter as part of processing the
-error generated by the command.
+in the \fB\-errorcode\fR return option. The \fB\-errorcode\fR
+return option is intended to hold a machine-readable description
+of the error in cases where such information is available; see
+the \fBreturn\fR manual page for information on the proper format
+for this option's value.
.SH EXAMPLE
Generate an error if a basic mathematical operation fails:
.CS
@@ -60,7 +66,7 @@ if {1+2 != 3} {
.CE
.SH "SEE ALSO"
-catch(n), return(n), tclvars(n)
+catch(n), return(n)
.SH KEYWORDS
-error, errorCode, errorInfo
+error
diff --git a/doc/eval.n b/doc/eval.n
index 81b9b1f..a642d23 100644
--- a/doc/eval.n
+++ b/doc/eval.n
@@ -25,10 +25,39 @@ Tcl interpreter recursively, and returns the result of that
evaluation (or any error generated by it).
Note that the \fBlist\fR command quotes sequences of words in such a
way that they are not further expanded by the \fBeval\fR command.
-.SH EXAMPLE
-This procedure acts in a way that is analogous to the \fBlappend\fR
-command, except it inserts the argument values at the start of the
-list in the variable:
+.SH EXAMPLES
+Often, it is useful to store a fragment of a script in a variable and
+execute it later on with extra values appended. This technique is used
+in a number of places throughout the Tcl core (e.g. in \fBfcopy\fR,
+\fBlsort\fR and \fBtrace\fR command callbacks). This example shows how
+to do this using core Tcl commands:
+.CS
+set script {
+ puts "logging now"
+ lappend $myCurrentLogVar
+}
+set myCurrentLogVar log1
+# Set up a switch of logging variable part way through!
+after 20000 set myCurrentLogVar log2
+
+for {set i 0} {$i<10} {incr i} {
+ # Introduce a random delay
+ after [expr {int(5000 * rand())}]
+ update ;# Check for the asynch log switch
+ \fBeval\fR $script $i [clock clicks]
+}
+.CE
+.PP
+.VS 8.5
+Note that in the most common case (where the script fragment is
+actually just a list of words forming a command prefix), it is better
+to use \fB{*}$script\fR when doing this sort of invocation
+pattern. It is less general than the \fBeval\fR command, and hence
+easier to make robust in practice.
+.VE 8.5
+The following procedure acts in a way that is analogous to the
+\fBlappend\fR command, except it inserts the argument values at the
+start of the list in the variable:
.CS
proc lprepend {varName args} {
upvar 1 $varName var
@@ -38,9 +67,16 @@ proc lprepend {varName args} {
set var [\fBeval\fR [list linsert $var 0] $args]
}
.CE
+.VS 8.5
+However, the last line would now normally be written without
+\fBeval\fR, like this:
+.CS
+set var [linsert $var 0 {*}$args]
+.CE
+.VE 8.5
+
+.SH "SEE ALSO"
+catch(n), concat(n), error(n), interp(n), list(n), namespace(n), subst(n), tclvars(n), uplevel(n)
.SH KEYWORDS
concatenate, evaluate, script
-
-.SH "SEE ALSO"
-catch(n), concat(n), error(n), list(n), subst(n), tclvars(n)
diff --git a/doc/exec.n b/doc/exec.n
index 3f85fd6..fd4e9cf 100644
--- a/doc/exec.n
+++ b/doc/exec.n
@@ -1,12 +1,13 @@
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2006 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 exec n 7.6 Tcl "Tcl Built-In Commands"
+.TH exec n 8.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -28,6 +29,12 @@ they are treated as command-line switches and are not part
of the pipeline specification. The following switches are
currently supported:
.TP 13
+\fB\-ignorestderr\fR
+.VS 8.5
+Stops the \fBexec\fR command from treating the output of messages to the
+pipeline's standard error channel as an error case.
+.VE 8.5
+.TP 13
\fB\-keepnewline\fR
Retains a trailing newline in the pipeline's output.
Normally a trailing newline will be deleted.
@@ -40,76 +47,84 @@ If an \fIarg\fR (or pair of \fIarg\fRs) has one of the forms
described below then it is used by \fBexec\fR to control the
flow of input and output among the subprocess(es).
Such arguments will not be passed to the subprocess(es). In forms
-such as ``< \fIfileName\fR'' \fIfileName\fR may either be in a
-separate argument from ``<'' or in the same argument with no
-intervening space (i.e. ``<\fIfileName\fR'').
+such as
+.QW "\fB<\fR \fIfileName\fR" ,
+\fIfileName\fR may either be in a separate argument from
+.QW \fB<\fR
+or in the same argument with no intervening space (i.e.
+.QW \fB<\fIfileName\fR ).
.TP 15
-|
+\fB|\fR
Separates distinct commands in the pipeline. The standard output
of the preceding command will be piped into the standard input
of the next command.
.TP 15
-|&
+\fB|&\fR
Separates distinct commands in the pipeline. Both standard output
and standard error of the preceding command will be piped into
the standard input of the next command.
This form of redirection overrides forms such as 2> and >&.
.TP 15
-<\0\fIfileName\fR
+\fB<\0\fIfileName\fR
The file named by \fIfileName\fR is opened and used as the standard
input for the first command in the pipeline.
.TP 15
-<@\0\fIfileId\fR
+\fB<@\0\fIfileId\fR
\fIFileId\fR must be the identifier for an open file, such as the return
value from a previous call to \fBopen\fR.
It is used as the standard input for the first command in the pipeline.
\fIFileId\fR must have been opened for reading.
.TP 15
-<<\0\fIvalue\fR
+\fB<<\0\fIvalue\fR
\fIValue\fR is passed to the first command as its standard input.
.TP 15
->\0\fIfileName\fR
+\fB>\0\fIfileName\fR
Standard output from the last command is redirected to the file named
\fIfileName\fR, overwriting its previous contents.
.TP 15
-2>\0\fIfileName\fR
+\fB2>\0\fIfileName\fR
Standard error from all commands in the pipeline is redirected to the
file named \fIfileName\fR, overwriting its previous contents.
.TP 15
->&\0\fIfileName\fR
+\fB>&\0\fIfileName\fR
Both standard output from the last command and standard error from all
commands are redirected to the file named \fIfileName\fR, overwriting
its previous contents.
.TP 15
->>\0\fIfileName\fR
+\fB>>\0\fIfileName\fR
Standard output from the last command is
redirected to the file named \fIfileName\fR, appending to it rather
than overwriting it.
.TP 15
-2>>\0\fIfileName\fR
+\fB2>>\0\fIfileName\fR
Standard error from all commands in the pipeline is
redirected to the file named \fIfileName\fR, appending to it rather
than overwriting it.
.TP 15
->>&\0\fIfileName\fR
+\fB>>&\0\fIfileName\fR
Both standard output from the last command and standard error from
all commands are redirected to the file named \fIfileName\fR,
appending to it rather than overwriting it.
.TP 15
->@\0\fIfileId\fR
+\fB>@\0\fIfileId\fR
\fIFileId\fR must be the identifier for an open file, such as the return
value from a previous call to \fBopen\fR.
Standard output from the last command is redirected to \fIfileId\fR's
file, which must have been opened for writing.
.TP 15
-2>@\0\fIfileId\fR
+\fB2>@\0\fIfileId\fR
\fIFileId\fR must be the identifier for an open file, such as the return
value from a previous call to \fBopen\fR.
Standard error from all commands in the pipeline is
redirected to \fIfileId\fR's file.
The file must have been opened for writing.
.TP 15
->&@\0\fIfileId\fR
+\fB2>@1\0\fR
+Standard error from all commands in the pipeline is redirected to the
+command result. This operator is only valid at the end of the command
+pipeline.
+.TP 15
+\fB>&@\0\fIfileId\fR
\fIFileId\fR must be the identifier for an open file, such as the return
value from a previous call to \fBopen\fR.
Both standard output from the last command and standard error from
@@ -118,15 +133,23 @@ The file must have been opened for writing.
.PP
If standard output has not been redirected then the \fBexec\fR
command returns the standard output from the last command
-in the pipeline.
+in the pipeline,
+.VS 8.5
+unless
+.QW 2>@1
+was specified, in which case standard error is included as well.
+.VE 8.5
If any of the commands in the pipeline exit abnormally or
are killed or suspended, then \fBexec\fR will return an error
and the error message will include the pipeline's output followed by
error messages describing the abnormal terminations; the
-\fBerrorCode\fR variable will contain additional information
+\fB\-errorcode\fR return option will contain additional information
about the last abnormal termination encountered.
If any of the commands writes to its standard error file and that
-standard error isn't redirected,
+standard error is not redirected
+.VS 8.5
+and \fB\-ignorestderr\fR is not specified,
+.VE 8.5
then \fBexec\fR will return an error; the error message
will include the pipeline's standard output, followed by messages
about abnormal terminations (if any), followed by the standard error
@@ -135,22 +158,27 @@ output.
If the last character of the result or error message
is a newline then that character is normally deleted
from the result or error message.
-This is consistent with other Tcl return values, which don't
+This is consistent with other Tcl return values, which do not
normally end with newlines.
However, if \fB\-keepnewline\fR is specified then the trailing
newline is retained.
.PP
-If standard input isn't redirected with ``<'' or ``<<''
-or ``<@'' then the standard input for the first command in the
+If standard input is not redirected with
+.QW < ,
+.QW <<
+or
+.QW <@
+then the standard input for the first command in the
pipeline is taken from the application's current standard input.
.PP
-If the last \fIarg\fR is ``&'' then the pipeline will be
-executed in background.
+If the last \fIarg\fR is
+.QW &
+then the pipeline will be executed in background.
In this case the \fBexec\fR command will return a list whose
elements are the process identifiers for all of the subprocesses
in the pipeline.
The standard output from the last command in the pipeline will
-go to the application's standard output if it hasn't been
+go to the application's standard output if it has not been
redirected, and error output from all of
the commands in the pipeline will go to the application's
standard error file unless redirected.
@@ -162,26 +190,28 @@ in the PATH environment variable are searched for
an executable by the given name.
If the name contains a slash then it must refer to an executable
reachable from the current directory.
-No ``glob'' expansion or other shell-like substitutions
+No
+.QW glob
+expansion or other shell-like substitutions
are performed on the arguments to commands.
-
-.VS
.SH "PORTABILITY ISSUES"
.TP
\fBWindows\fR (all versions)
.
-Reading from or writing to a socket, using the ``\fB@\0\fIfileId\fR''
+Reading from or writing to a socket, using the
+.QW \fB@\0\fIfileId\fR
notation, does not work. When reading from a socket, a 16-bit DOS
application will hang and a 32-bit application will return immediately with
end-of-file. When either type of application writes to a socket, the
information is instead sent to the console, if one is present, or is
discarded.
-.sp
+.RS
+.PP
The Tk console text widget does not provide real standard IO capabilities.
Under Tk, when redirecting from standard input, all applications will see an
immediate end-of-file; information redirected to standard output or standard
error will be discarded.
-.sp
+.PP
Either forward or backward slashes are accepted as path separators for
arguments to Tcl commands. When executing an application, the path name
specified for the application may also contain forward or backward slashes
@@ -192,12 +222,16 @@ path name with forward slashes will not automatically be converted to use
the backslash character. If an argument contains forward slashes as the
path separator, it may or may not be recognized as a path name, depending on
the program.
-.sp
+.PP
Additionally, when calling a 16-bit DOS or Windows 3.X application, all path
-names must use the short, cryptic, path format (e.g., using ``applba~1.def''
-instead of ``applbakery.default''), which can be obtained with the
-\fBfile attributes $fileName -shortname\fR command.
-.sp
+names must use the short, cryptic, path format (e.g., using
+.QW applba~1.def
+instead of
+.QW applbakery.default ),
+which can be obtained with the
+.QW "\fBfile attributes \fIfileName \fB\-shortname\fR"
+command.
+.PP
Two or more forward or backward slashes in a row in a path refer to a
network path. For example, a simple concatenation of the root directory
\fBc:/\fR with a subdirectory \fB/windows/system\fR will yield
@@ -206,25 +240,25 @@ point called \fBsystem\fR on the machine called \fBwindows\fR (and the
\fBc:/\fR is ignored), and is not equivalent to \fBc:/windows/system\fR,
which describes a directory on the current computer. The \fBfile join\fR
command should be used to concatenate path components.
-.sp
-.RS
+.PP
Note that there are two general types of Win32 console applications:
.RS
-1) CLI -- CommandLine Interface, simple stdio exchange. \fBnetstat.exe\fR for
+.IP [1]
+CLI \(em CommandLine Interface, simple stdio exchange. \fBnetstat.exe\fR for
example.
-.br
-2) TUI -- Textmode User Interface, any application that accesses the console
+.IP [2]
+TUI \(em Textmode User Interface, any application that accesses the console
API for doing such things as cursor movement, setting text color, detecting
key presses and mouse movement, etc. An example would be \fBtelnet.exe\fR
from Windows 2000. These types of applications are not common in a windows
environment, but do exist.
.RE
+.PP
\fBexec\fR will not work well with TUI applications when a console is not
present, as is done when launching applications under wish. It is desirable
to have console applications hidden and detached. This is a designed-in
limitation as \fBexec\fR wants to communicate over pipes. The Expect
extension addresses this issue when communicating with a TUI application.
-.sp
.RE
.TP
\fBWindows NT\fR
@@ -235,26 +269,24 @@ the name as it was specified. Then, in order, \fB.com\fR, \fB.exe\fR, and
for the longer name. If a directory name was not specified as part of the
application name, the following directories are automatically searched in
order when attempting to locate the application:
-.sp
-.RS
.RS
+.IP \(bu
The directory from which the Tcl executable was loaded.
-.br
+.IP \(bu
The current directory.
-.br
+.IP \(bu
The Windows NT 32-bit system directory.
-.br
+.IP \(bu
The Windows NT 16-bit system directory.
-.br
+.IP \(bu
The Windows NT home directory.
-.br
+.IP \(bu
The directories listed in the path.
-.RE
-.sp
+.PP
In order to execute shell built-in commands like \fBdir\fR and \fBcopy\fR,
-the caller must prepend the desired command with ``\fBcmd.exe /c\0\fR''
+the caller must prepend the desired command with
+.QW "\fBcmd.exe /c\0\fR"
because built-in commands are not implemented using executables.
-.sp
.RE
.TP
\fBWindows 9x\fR
@@ -265,39 +297,42 @@ the name as it was specified. Then, in order, \fB.com\fR, \fB.exe\fR, and
for the longer name. If a directory name was not specified as part of the
application name, the following directories are automatically searched in
order when attempting to locate the application:
-.sp
-.RS
.RS
+.IP \(bu
The directory from which the Tcl executable was loaded.
-.br
+.IP \(bu
The current directory.
-.br
+.IP \(bu
The Windows 9x system directory.
-.br
+.IP \(bu
The Windows 9x home directory.
-.br
+.IP \(bu
The directories listed in the path.
.RE
-.sp
+.RS
+.PP
In order to execute shell built-in commands like \fBdir\fR and \fBcopy\fR,
-the caller must prepend the desired command with ``\fBcommand.com /c\0\fR''
+the caller must prepend the desired command with
+.QW "\fBcommand.com /c\0\fR"
because built-in commands are not implemented using executables.
-.sp
+.PP
Once a 16-bit DOS application has read standard input from a console and
then quit, all subsequently run 16-bit DOS applications will see the
standard input as already closed. 32-bit applications do not have this
problem and will run correctly, even after a 16-bit DOS application thinks
that standard input is closed. There is no known workaround for this bug
at this time.
-.sp
+.PP
Redirection between the \fBNUL:\fR device and a 16-bit application does not
always work. When redirecting from \fBNUL:\fR, some applications may hang,
-others will get an infinite stream of ``0x01'' bytes, and some will actually
+others will get an infinite stream of
+.QW 0x01
+bytes, and some will actually
correctly get an immediate end-of-file; the behavior seems to depend upon
something compiled into the application itself. When redirecting greater than
4K or so to \fBNUL:\fR, some applications will hang. The above problems do not
happen with 32-bit applications.
-.sp
+.PP
All DOS 16-bit applications are run synchronously. All standard input from
a pipe to a 16-bit DOS application is collected into a temporary file; the
other end of the pipe must be closed before the 16-bit DOS application
@@ -307,7 +342,7 @@ must terminate before the temporary files are redirected to the next stage
of the pipeline. This is due to a workaround for a Windows 95 bug in the
implementation of pipes, and is how the standard Windows 95 DOS shell
handles pipes itself.
-.sp
+.PP
Certain applications, such as \fBcommand.com\fR, should not be executed
interactively. Applications which directly access the console window,
rather than reading from their standard input and writing to their standard
@@ -315,12 +350,8 @@ output may fail, hang Tcl, or even hang the system if their own private
console window is not available to them.
.RE
.TP
-\fBMacintosh\fR
-The \fBexec\fR command is not implemented and does not exist under Macintosh.
-.TP
\fBUnix\fR\0\0\0\0\0\0\0
The \fBexec\fR command is fully functional and works as described.
-
.SH "UNIX EXAMPLES"
Here are some examples of the use of the \fBexec\fR command on Unix.
.PP
@@ -330,13 +361,14 @@ To execute a simple program and get its result:
.CE
.PP
To execute a program that can return a non-zero result, you should
-wrap the call to \fBexec\fR in \fBcatch\fR and check what the contents
-of the global \fBerrorCode\fR variable is if you have an error:
+wrap the call to \fBexec\fR in \fBcatch\fR and check the contents
+of the \fB\-errorcode\fR return option if you have an error:
.CS
set status 0
-if {[catch {\fBexec\fR grep foo bar.txt} results]} {
- if {[lindex $::errorCode 0] eq "CHILDSTATUS"} {
- set status [lindex $::errorCode 2]
+if {[catch {\fBexec\fR grep foo bar.txt} results options]} {
+ set details [dict get $options -errorcode]
+ if {[lindex $details 0] eq "CHILDSTATUS"} {
+ set status [lindex $details 2]
} else {
# Some kind of unexpected failure
}
@@ -359,9 +391,8 @@ remember that Tcl does not handle globbing or expand things into
multiple arguments by default. Instead you should write things like
this:
.CS
-eval [list \fBexec\fR ls -l] [glob *.tcl]
+\fBexec\fR ls -l {*}[glob *.tcl]
.CE
-.PP
.SH "WINDOWS EXAMPLES"
Here are some examples of the use of the \fBexec\fR command on Windows.
.PP
@@ -395,15 +426,15 @@ differences in behaviour between \fBexec\fR and DOS batch files.
.PP
When in doubt, use the command \fBauto_execok\fR: it will return the
complete path to the program as seen by the \fBexec\fR command. This
-applies especially when you want to run "internal" commands like
+applies especially when you want to run
+.QW internal
+commands like
\fIdir\fR from a Tcl script (if you just want to list filenames, use
the \fBglob\fR command.) To do that, use this:
.CS
-eval [list \fBexec\fR] [auto_execok dir] [list *.tcl]
+\fBexec\fR {*}[auto_execok dir] *.tcl
.CE
-
.SH "SEE ALSO"
error(n), open(n)
-
.SH KEYWORDS
execute, pipeline, redirection, subprocess
diff --git a/doc/exit.n b/doc/exit.n
index 5d1dc0b..eccd635 100644
--- a/doc/exit.n
+++ b/doc/exit.n
@@ -19,23 +19,23 @@ exit \- End the application
.PP
Terminate the process, returning \fIreturnCode\fR to the
system as the exit status.
-If \fIreturnCode\fR isn't specified then it defaults
+If \fIreturnCode\fR is not specified then it defaults
to 0.
.SH EXAMPLE
Since non-zero exit codes are usually interpreted as error cases by
the calling process, the \fBexit\fR command is an important part of
-signalling that something fatal has gone wrong. This code fragment is
+signaling that something fatal has gone wrong. This code fragment is
useful in scripts to act as a general problem trap:
.CS
proc main {} {
# ... put the real main code in here ...
}
-if {[catch {main} msg]} {
+if {[catch {main} msg options]} {
puts stderr "unexpected script error: $msg"
if {[info exist env(DEBUG)]} {
puts stderr "---- BEGIN TRACE ----"
- puts stderr $errorInfo
+ puts stderr [dict get $options -errorinfo]
puts stderr "---- END TRACE ----"
}
@@ -45,7 +45,7 @@ if {[catch {main} msg]} {
.CE
.SH "SEE ALSO"
-exec(n), tclvars(n)
+exec(n)
.SH KEYWORDS
exit, process
diff --git a/doc/expr.n b/doc/expr.n
index e529925..8d6a8ae 100644
--- a/doc/expr.n
+++ b/doc/expr.n
@@ -1,12 +1,13 @@
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-2000 Sun Microsystems, Inc.
+'\" Copyright (c) 2005 by Kevin B. Kenny <kennykb@acm.org>. All rights reserved
'\"
'\" 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.4 Tcl "Tcl Built-In Commands"
+.TH expr n 8.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -14,14 +15,14 @@ expr \- Evaluate an expression
.SH SYNOPSIS
\fBexpr \fIarg \fR?\fIarg arg ...\fR?
.BE
-
.SH DESCRIPTION
.PP
Concatenates \fIarg\fRs (adding separator spaces between them),
evaluates the result as a Tcl expression, and returns the value.
-The operators permitted in Tcl expressions are a subset of
-the operators permitted in C expressions, and they have the
-same meaning and precedence as the corresponding C operators.
+The operators permitted in Tcl expressions include a subset of
+the operators permitted in C expressions. For those operators
+common to both Tcl and C, Tcl applies the same meaning and precedence
+as the corresponding C operators.
Expressions almost always yield numeric results
(integer or floating-point values).
For example, the expression
@@ -31,36 +32,38 @@ For example, the expression
evaluates to 14.2.
Tcl expressions differ from C expressions in the way that
operands are specified. Also, Tcl expressions support
-non-numeric operands and string comparisons.
-.SH OPERANDS
+non-numeric operands and string comparisons, as well as some
+additional operators not found in C.
+.SS OPERANDS
.PP
A Tcl expression consists of a combination of operands, operators,
and parentheses.
White space may be used between the operands and operators and
parentheses; 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 octal (if the
-first character of the operand is \fB0\fR), or in hexadecimal (if the first
-two characters of the operand are \fB0x\fR).
+.VS 8.5
+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
+(if the first two characters of the operand are \fB0o\fR), or in hexadecimal
+(if the first two characters of the operand are \fB0x\fR). For
+compatibility with older Tcl releases, an octal integer value is also
+indicated simply when the first character of the operand is \fB0\fR,
+whether or not the second character is also \fBo\fR.
If an operand does not have one of the integer formats given
above, then it is treated as a floating-point number if that is
-possible. Floating-point numbers may be specified in any of the
-ways accepted by an ANSI-compliant C compiler (except that the
-\fBf\fR, \fBF\fR, \fBl\fR, and \fBL\fR suffixes will not be permitted in
-most installations). For example, all of the
+possible. Floating-point numbers may be specified in any of several
+common formats making use of the decimal digits, the decimal point \fB.\fR,
+the characters \fBe\fR or \fBE\fR indicating scientific notation, and
+the sign characters \fB+\fR or \fB\-\fR. For example, all of the
following are valid floating-point numbers: 2.1, 3., 6e4, 7.91e+16.
+Also recognized as floating point values are the strings \fBInf\fR
+and \fBNaN\fR making use of any case for each character.
+.VE 8.5
If no numeric interpretation is possible (note that all literal
operands that are not numeric or boolean must be quoted with either
braces or with double quotes), then an operand is left as a string
(and only a limited set of operators may be applied to it).
.PP
-.VS 8.4
-On 32-bit systems, integer values MAX_INT (0x7FFFFFFF) and MIN_INT
-(-0x80000000) will be represented as 32-bit values, and integer values
-outside that range will be represented as 64-bit values (if that is
-possible at all.)
-.VE 8.4
-.PP
Operands may be specified in any of the following ways:
.IP [1]
As a numeric value, either integer or floating-point.
@@ -84,8 +87,8 @@ The command will be executed and its result will be used as
the operand.
.IP [7]
As a mathematical function whose arguments have any of the above
-forms for operands, such as \fBsin($x)\fR. See below for a list of defined
-functions.
+forms for operands, such as \fBsin($x)\fR. See \fBMATH FUNCTIONS\fR below for
+a discussion of how mathematical functions are handled.
.LP
Where the above substitutions occur (e.g. inside quoted strings), they
are performed by the expression's instructions.
@@ -102,21 +105,27 @@ Then the command on the left side of each of the lines below
will produce the value on the right side of the line:
.CS
.ta 6c
-\fBexpr 3.1 + $a 6.1
-expr 2 + "$a.$b" 5.6
-expr 4*[llength "6 2"] 8
-expr {{word one} < "word $a"} 0\fR
+\fBexpr\fR 3.1 + $a \fI6.1\fR
+\fBexpr\fR 2 + "$a.$b" \fI5.6\fR
+\fBexpr\fR 4*[llength "6 2"] \fI8\fR
+\fBexpr\fR {{word one} < "word $a"} \fI0\fR
.CE
-.SH OPERATORS
+.SS OPERATORS
.PP
-The valid operators are listed below, grouped in decreasing order
-of precedence:
+The valid operators (most of which are also available as commands in
+the \fBtcl::mathop\fR namespace; see the \fBmathop\fR(n) manual page
+for details) are listed below, grouped in decreasing order of precedence:
.TP 20
\fB\-\0\0+\0\0~\0\0!\fR
Unary minus, unary plus, bit-wise NOT, logical NOT. None of these operators
may be applied to string operands, and bit-wise NOT may be
applied only to integers.
.TP 20
+\fB**\fR
+.VS 8.5
+Exponentiation. Valid for any numeric operands.
+.VE 8.5
+.TP 20
\fB*\0\0/\0\0%\fR
Multiply, divide, remainder. None of these operators may be
applied to string operands, and remainder may be applied only
@@ -140,12 +149,19 @@ in which case string comparison is used.
\fB==\0\0!=\fR
Boolean equal and not equal. Each operator produces a zero/one result.
Valid for all operand types.
-.VS 8.4
.TP 20
\fBeq\0\0ne\fR
Boolean string equal and string not equal. Each operator produces a
zero/one result. The operand types are interpreted only as strings.
-.VE 8.4
+.TP 20
+\fBin\0\0ni\fR
+.VS 8.5
+List containment and negated list containment. Each operator produces
+a zero/one result and treats its first argument as a string and its
+second argument as a Tcl list. The \fBin\fR operator indicates
+whether the first argument is a member of the second argument list;
+the \fBni\fR operator inverts the sense of the result.
+.VE 8.5
.TP 20
\fB&\fR
Bit-wise AND. Valid for integer operands only.
@@ -173,168 +189,84 @@ The \fIx\fR operand must have a boolean or numeric value.
.LP
See the C manual for more details on the results
produced by each operator.
+.VS 8.5
+The exponentiation operator promotes types like the multiply and
+divide operators, and produces a result that is the same as the output
+of the \fBpow\fR function (after any type conversions.)
+.VE 8.5
All of the binary operators group left-to-right within the same
precedence level. For example, the command
.CS
-\fBexpr 4*2 < 7\fR
+\fBexpr\fR {4*2 < 7}
.CE
returns 0.
.PP
-The \fB&&\fR, \fB||\fR, and \fB?:\fR operators have ``lazy
-evaluation'', just as in C,
-which means that operands are not evaluated if they are
+The \fB&&\fR, \fB||\fR, and \fB?:\fR operators have
+.QW "lazy evaluation" ,
+just as in C, which means that operands are not evaluated if they are
not needed to determine the outcome. For example, in the command
.CS
\fBexpr {$v ? [a] : [b]}\fR
.CE
-only one of \fB[a]\fR or \fB[b]\fR will actually be evaluated,
+only one of
+.QW \fB[a]\fR
+or
+.QW \fB[b]\fR
+will actually be evaluated,
depending on the value of \fB$v\fR. Note, however, that this is
only true if the entire expression is enclosed in braces; otherwise
-the Tcl parser will evaluate both \fB[a]\fR and \fB[b]\fR before
-invoking the \fBexpr\fR command.
-.SH "MATH FUNCTIONS"
+the Tcl parser will evaluate both
+.QW \fB[a]\fR
+and
+.QW \fB[b]\fR
+before invoking the \fBexpr\fR command.
+.SS "MATH FUNCTIONS"
.PP
-Tcl supports the following mathematical functions in expressions, all
-of which work solely with floating-point numbers unless otherwise noted:
-.DS
-.ta 3c 6c 9c
-\fBabs\fR \fBcosh\fR \fBlog\fR \fBsqrt\fR
-\fBacos\fR \fBdouble\fR \fBlog10\fR \fBsrand\fR
-\fBasin\fR \fBexp\fR \fBpow\fR \fBtan\fR
-\fBatan\fR \fBfloor\fR \fBrand\fR \fBtanh\fR
-\fBatan2\fR \fBfmod\fR \fBround\fR \fBwide\fR
-\fBceil\fR \fBhypot\fR \fBsin\fR
-\fBcos\fR \fBint\fR \fBsinh\fR
-.DE
+.VS 8.5
+When the expression parser encounters a mathematical function
+such as \fBsin($x)\fR, it replaces it with a call to an ordinary
+Tcl function in the \fBtcl::mathfunc\fR namespace. The processing
+of an expression such as:
+.CS
+\fBexpr {sin($x+$y)}\fR
+.CE
+is the same in every way as the processing of:
+.CS
+\fBexpr {[tcl::mathfunc::sin [expr {$x+$y}]]}\fR
+.CE
+which in turn is the same as the processing of:
+.CS
+\fBtcl::mathfunc::sin [expr {$x+$y}]\fR
+.CE
.PP
-.TP
-\fBabs(\fIarg\fB)\fR
-Returns the absolute value of \fIarg\fR. \fIArg\fR may be either
-integer or floating-point, and the result is returned in the same form.
-.TP
-\fBacos(\fIarg\fB)\fR
-Returns the arc cosine of \fIarg\fR, in the range [\fI0\fR,\fIpi\fR]
-radians. \fIArg\fR should be in the range [\fI-1\fR,\fI1\fR].
-.TP
-\fBasin(\fIarg\fB)\fR
-Returns the arc sine of \fIarg\fR, in the range [\fI-pi/2\fR,\fIpi/2\fR]
-radians. \fIArg\fR should be in the range [\fI-1\fR,\fI1\fR].
-.TP
-\fBatan(\fIarg\fB)\fR
-Returns the arc tangent of \fIarg\fR, in the range [\fI-pi/2\fR,\fIpi/2\fR]
-radians.
-.TP
-\fBatan2(\fIy, x\fB)\fR
-Returns the arc tangent of \fIy\fR/\fIx\fR, in the range [\fI-pi\fR,\fIpi\fR]
-radians. \fIx\fR and \fIy\fR cannot both be 0. If \fIx\fR is greater
-than \fI0\fR, this is equivalent to \fBatan(\fIy/x\fB)\fR.
-.TP
-\fBceil(\fIarg\fB)\fR
-Returns the smallest integral floating-point value (i.e. with a zero
-fractional part) not less than \fIarg\fR.
-.TP
-\fBcos(\fIarg\fB)\fR
-Returns the cosine of \fIarg\fR, measured in radians.
-.TP
-\fBcosh(\fIarg\fB)\fR
-Returns the hyperbolic cosine of \fIarg\fR. If the result would cause
-an overflow, an error is returned.
-.TP
-\fBdouble(\fIarg\fB)\fR
-If \fIarg\fR is a floating-point value, returns \fIarg\fR, otherwise converts
-\fIarg\fR to floating-point and returns the converted value.
-.TP
-\fBexp(\fIarg\fB)\fR
-Returns the exponential of \fIarg\fR, defined as \fIe\fR**\fIarg\fR.
-If the result would cause an overflow, an error is returned.
-.TP
-\fBfloor(\fIarg\fB)\fR
-Returns the largest integral floating-point value (i.e. with a zero
-fractional part) not greater than \fIarg\fR.
-.TP
-\fBfmod(\fIx, y\fB)\fR
-Returns the floating-point remainder of the division of \fIx\fR by
-\fIy\fR. If \fIy\fR is 0, an error is returned.
-.TP
-\fBhypot(\fIx, y\fB)\fR
-Computes the length of the hypotenuse of a right-angled triangle
-\fBsqrt(\fIx\fR*\fIx\fR+\fIy\fR*\fIy\fB)\fR.
-.TP
-\fBint(\fIarg\fB)\fR
-.VS 8.4
-If \fIarg\fR is an integer value of the same width as the machine
-word, returns \fIarg\fR, otherwise
-converts \fIarg\fR to an integer (of the same size as a machine word,
-i.e. 32-bits on 32-bit systems, and 64-bits on 64-bit systems) by
-truncation and returns the converted value.
-.VE 8.4
-.TP
-\fBlog(\fIarg\fB)\fR
-Returns the natural logarithm of \fIarg\fR. \fIArg\fR must be a
-positive value.
-.TP
-\fBlog10(\fIarg\fB)\fR
-Returns the base 10 logarithm of \fIarg\fR. \fIArg\fR must be a
-positive value.
-.TP
-\fBpow(\fIx, y\fB)\fR
-Computes the value of \fIx\fR raised to the power \fIy\fR. If \fIx\fR
-is negative, \fIy\fR must be an integer value.
-.TP
-\fBrand()\fR
-Returns a pseudo-random floating-point value in the range (\fI0\fR,\fI1\fR).
-The generator algorithm is a simple linear congruential generator that
-is not cryptographically secure. Each result from \fBrand\fR completely
-determines all future results from subsequent calls to \fBrand\fR, so
-\fBrand\fR should not be used to generate a sequence of secrets, such as
-one-time passwords. The seed of the generator is initialized from the
-internal clock of the machine or may be set with the \fBsrand\fR function.
-.TP
-\fBround(\fIarg\fB)\fR
-If \fIarg\fR is an integer value, returns \fIarg\fR, otherwise converts
-\fIarg\fR to integer by rounding and returns the converted value.
-.TP
-\fBsin(\fIarg\fB)\fR
-Returns the sine of \fIarg\fR, measured in radians.
-.TP
-\fBsinh(\fIarg\fB)\fR
-Returns the hyperbolic sine of \fIarg\fR. If the result would cause
-an overflow, an error is returned.
-.TP
-\fBsqrt(\fIarg\fB)\fR
-Returns the square root of \fIarg\fR. \fIArg\fR must be non-negative.
-.TP
-\fBsrand(\fIarg\fB)\fR
-The \fIarg\fR, which must be an integer, is used to reset the seed for
-the random number generator of \fBrand\fR. Returns the first random
-number (see \fBrand()\fR) from that seed. Each interpreter has its own seed.
-.TP
-\fBtan(\fIarg\fB)\fR
-Returns the tangent of \fIarg\fR, measured in radians.
-.TP
-\fBtanh(\fIarg\fB)\fR
-Returns the hyperbolic tangent of \fIarg\fR.
-.TP
-\fBwide(\fIarg\fB)\fR
-.VS 8.4
-Converts \fIarg\fR to an integer value at least 64-bits wide (by sign-extension
-if \fIarg\fR is a 32-bit number) if it is not one already.
-.VE 8.4
+The executor will search for \fBtcl::mathfunc::sin\fR using the usual
+rules for resolving functions in namespaces. Either
+\fB::tcl::mathfunc::sin\fR or \fB[namespace
+current]::tcl::mathfunc::sin\fR will satisfy the request, and others
+may as well (depending on the current \fBnamespace path\fR setting).
.PP
-In addition to these predefined functions, applications may
-define additional functions using \fBTcl_CreateMathFunc\fR().
-.SH "TYPES, OVERFLOW, AND PRECISION"
+See the \fBmathfunc\fR(n) manual page for the math functions that are
+available by default.
+.VE 8.5
+.SS "TYPES, OVERFLOW, AND PRECISION"
.PP
-All internal computations involving integers are done with the C type
-\fIlong\fR, and all internal computations involving floating-point are
+.VS 8.5
+All internal computations involving integers are done calling on the
+LibTomMath multiple precision integer library as required so that all
+integer calculations are performed exactly. Note that in Tcl releases
+prior to 8.5, integer calculations were performed with one of the C types
+\fIlong int\fR or \fITcl_WideInt\fR, causing implicit range truncation
+in those calculations where values overflowed the range of those types.
+Any code that relied on these implicit truncations will need to explicitly
+add \fBint()\fR or \fBwide()\fR function calls to expressions at the points
+where such truncation is required to take place.
+.VE 8.5
+.PP
+All internal computations involving floating-point are
done with the C type \fIdouble\fR.
When converting a string to floating-point, exponent overflow is
-detected and results in a Tcl error.
-For conversion to integer from string, detection of overflow depends
-on the behavior of some routines in the local C library, so it should
-be regarded as unreliable.
-In any case, integer overflow and underflow are generally not detected
-reliably for intermediate results. Floating-point overflow and underflow
+detected and results in the \fIdouble\fR value of \fBInf\fR or
+\fB\-Inf\fR as appropriate. Floating-point overflow and underflow
are detected to the degree supported by the hardware, which is generally
pretty reliable.
.PP
@@ -344,34 +276,36 @@ For arithmetic computations, integers are used until some
floating-point number is introduced, after which floating-point is used.
For example,
.CS
-\fBexpr 5 / 4\fR
+\fBexpr\fR {5 / 4}
.CE
returns 1, while
.CS
-\fBexpr 5 / 4.0\fR
-\fBexpr 5 / ( [string length "abcd"] + 0.0 )\fR
+\fBexpr\fR {5 / 4.0}
+\fBexpr\fR {5 / ( [string length "abcd"] + 0.0 )}
.CE
both return 1.25.
-Floating-point values are always returned with a ``\fB.\fR''
-or an \fBe\fR so that they will not look like integer values. For
-example,
+Floating-point values are always returned with a
+.QW \fB.\fR
+or an
+.QW \fBe\fR
+so that they will not look like integer values. For example,
.CS
-\fBexpr 20.0/5.0\fR
+\fBexpr\fR {20.0/5.0}
.CE
returns \fB4.0\fR, not \fB4\fR.
-.SH "STRING OPERATIONS"
+.SS "STRING OPERATIONS"
.PP
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,
-.VS 8.4
except in the case of the \fBeq\fR and \fBne\fR operators.
-.VE 8.4
If one of the operands of a comparison is a string and the other
-has a numeric value, the numeric operand is converted back to
-a string using the C \fIsprintf\fR format specifier
-\fB%d\fR for integers and \fB%g\fR for floating-point values.
-For example, the commands
+has a numeric value, a canonical string representation of the numeric
+operand value is generated to compare with the string operand.
+Canonical string representation for integer values is a decimal string
+format. Canonical string representation for floating-point values
+is that produced by the \fB%g\fR format specifier of Tcl's
+\fBformat\fR command. For example, the commands
.CS
\fBexpr {"0x03" > "2"}\fR
\fBexpr {"0y" < "0x12"}\fR
@@ -380,14 +314,10 @@ 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.
Because of Tcl's tendency to treat values as numbers whenever
-possible, it isn't generally a good idea to use operators like \fB==\fR
+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
-operands could be arbitrary; it's better in these cases to use
-.VS 8.4
-the \fBeq\fR or \fBne\fR operators, or
-.VE 8.4
-the \fBstring\fR command instead.
-
+operands could be arbitrary; it is better in these cases to use
+the \fBeq\fR or \fBne\fR operators, or the \fBstring\fR command instead.
.SH "PERFORMANCE CONSIDERATIONS"
.PP
Enclose expressions in braces for the best speed and the smallest
@@ -410,7 +340,7 @@ then the \fBexpr\fR command will evaluate the expression \fB$a + 2*4\fR.
Most expressions do not require a second round of substitutions.
Either they are enclosed in braces or, if not,
their variable and command substitutions yield numbers or strings
-that don't themselves require substitutions.
+that do not themselves require substitutions.
However, because a few unbraced expressions
need two rounds of substitutions,
the bytecode compiler must emit
@@ -419,12 +349,18 @@ The most expensive code is required for
unbraced expressions that contain command substitutions.
These expressions must be implemented by generating new code
each time the expression is executed.
+.VS 8.5
+When the expression is unbraced to allow the substitution of a function or
+operator, consider using the commands documented in the \fBmathfunc\fR(n) or
+\fBmathop\fR(n) manual pages directly instead.
+.VE 8.5
.SH EXAMPLES
-Define a procedure that computes an "interesting" mathematical
-function:
+Define a procedure that computes an
+.QW interesting
+mathematical function:
.CS
-proc calc {x y} {
- \fBexpr\fR { ($x*$x - $y*$y) / exp($x*$x + $y*$y) }
+proc tcl::mathfunc::calc {x y} {
+ \fBexpr\fR { ($x**2 - $y**2) / exp($x**2 + $y**2) }
}
.CE
.PP
@@ -461,9 +397,14 @@ Generate a random integer in the range 0..99 inclusive:
.CS
set randNum [\fBexpr\fR { int(100 * rand()) }]
.CE
-
.SH "SEE ALSO"
-array(n), for(n), if(n), string(n), Tcl(n), while(n)
-
+array(n), for(n), if(n), mathfunc(n), mathop(n), namespace(n), proc(n),
+string(n), Tcl(n), while(n)
.SH KEYWORDS
arithmetic, boolean, compare, expression, fuzzy comparison
+.SH COPYRIGHT
+.nf
+Copyright (c) 1993 The Regents of the University of California.
+Copyright (c) 1994-2000 Sun Microsystems Incorporated.
+Copyright (c) 2005 by Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+.fi
diff --git a/doc/fblocked.n b/doc/fblocked.n
index 08d8054..d8e8af7 100644
--- a/doc/fblocked.n
+++ b/doc/fblocked.n
@@ -24,12 +24,10 @@ characters available for input and no end-of-line sequence, \fBgets\fR
returns an empty string and a subsequent call to \fBfblocked\fR will
return 1.
.PP
-.VS
\fIChannelId\fR must be an identifier for an open channel such as a
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.
-.VE
.SH EXAMPLE
The \fBfblocked\fR command is particularly useful when writing network
servers, as it allows you to write your code in a line-by-line style
diff --git a/doc/fconfigure.n b/doc/fconfigure.n
index 11a4c4f..0763232 100644
--- a/doc/fconfigure.n
+++ b/doc/fconfigure.n
@@ -47,7 +47,8 @@ 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 affect the operation of the \fBgets\fR,
-\fBread\fR, \fBputs\fR, \fBflush\fR, and \fBclose\fR commands;
+\fBread\fR, \fBputs\fR, \fBflush\fR, and \fBclose\fR commands by
+allowing them to operate asynchronously;
see the documentation for those commands for details.
For nonblocking mode to work correctly, the application must be
using the Tcl event loop (e.g. by calling \fBTcl_DoOneEvent\fR or
@@ -89,11 +90,14 @@ If a file contains pure binary data (for instance, a JPEG image), the
encoding for the channel should be configured to be \fBbinary\fR. Tcl
will then assign no interpretation to the data in the file and simply read or
write raw bytes. The Tcl \fBbinary\fR command can be used to manipulate this
-byte-oriented data.
+byte-oriented data. It is usually better to set the
+\fB\-translation\fR option to \fBbinary\fR when you want to transfer
+binary data, as this turns off the other automatic interpretations of
+the bytes in the stream as well.
.PP
The default encoding for newly opened channels is the same platform- and
locale-dependent system encoding used for interfacing with the operating
-system.
+system, as returned by \fBencoding system\fR.
.RE
.TP
\fB\-eofchar\fR \fIchar\fR
@@ -114,6 +118,9 @@ channel, a two-element list will always be returned. The default value
for \fB\-eofchar\fR is the empty string in all cases except for files
under Windows. In that case the \fB\-eofchar\fR is Control-z (\ex1a) for
reading and the empty string for writing.
+The acceptable range for \fB\-eofchar\fR values is \ex01 - \ex7f;
+attempting to set \fB\-eofchar\fR to a value outside of this range will
+generate an error.
.TP
\fB\-translation\fR \fImode\fR
.TP
@@ -124,11 +131,11 @@ newline character (\en). However, in actual files and devices the end of
a line may be represented differently on different platforms, or even for
different devices on the same platform. For example, under UNIX newlines
are used in files, whereas carriage-return-linefeed sequences are
-normally used in network connections. On input (i.e., with \fBgets\fP
-and \fBread\fP) the Tcl I/O system automatically translates the external
+normally used in network connections. On input (i.e., with \fBgets\fR
+and \fBread\fR) the Tcl I/O system automatically translates the external
end-of-line representation into newline characters. Upon output (i.e.,
-with \fBputs\fP), the I/O system translates newlines to the external
-end-of-line representation. The default translation mode, \fBauto\fP,
+with \fBputs\fR), the I/O system translates newlines to the external
+end-of-line representation. The default translation mode, \fBauto\fR,
handles all the common cases automatically, but the \fB\-translation\fR
option provides explicit control over the end of line translations.
.RS
@@ -146,25 +153,24 @@ currently supported:
\fBauto\fR
.
As the input translation mode, \fBauto\fR treats any of newline
-(\fBlf\fP), carriage return (\fBcr\fP), or carriage return followed by a
-newline (\fBcrlf\fP) as the end of line representation. The end of line
+(\fBlf\fR), carriage return (\fBcr\fR), or carriage return followed by a
+newline (\fBcrlf\fR) as the end of line representation. The end of line
representation can even change from line-to-line, and all cases are
translated to a newline. As the output translation mode, \fBauto\fR
chooses a platform specific representation; for sockets on all platforms
-Tcl chooses \fBcrlf\fR, for all Unix flavors, it chooses \fBlf\fR, for the
-Macintosh platform it chooses \fBcr\fR and for the various flavors of
-Windows it chooses \fBcrlf\fR. The default setting for
-\fB\-translation\fR is \fBauto\fR for both input and output.
+Tcl chooses \fBcrlf\fR, for all Unix flavors, it chooses \fBlf\fR, and
+for the various flavors of Windows it chooses \fBcrlf\fR. The default
+setting for \fB\-translation\fR is \fBauto\fR for both input and output.
.TP
\fBbinary\fR
.
No end-of-line translations are performed. This is nearly identical to
-\fBlf\fP mode, except that in addition \fBbinary\fP mode also sets the
+\fBlf\fR mode, except that in addition \fBbinary\fR mode also sets the
end-of-file character to the empty string (which disables it) and sets the
encoding to \fBbinary\fR (which disables encoding filtering). See the
description of \fB\-eofchar\fR and \fB\-encoding\fR for more information.
-.PP
.RS
+.PP
Internally, i.e. when it comes to the actual behaviour of the
translator this value \fBis\fR identical to \fBlf\fR and is therefore
reported as such when queried. Even if \fBbinary\fR was used to set
@@ -175,17 +181,17 @@ the translation.
.
The end of a line in the underlying file or device is represented by a
single carriage return character. As the input translation mode,
-\fBcr\fP mode converts carriage returns to newline characters. As the
-output translation mode, \fBcr\fP mode translates newline characters to
-carriage returns. This mode is typically used on Macintosh platforms.
+\fBcr\fR mode converts carriage returns to newline characters. As the
+output translation mode, \fBcr\fR mode translates newline characters to
+carriage returns.
.TP
\fBcrlf\fR
.
The end of a line in the underlying file or device is represented by a
carriage return character followed by a linefeed character. As the input
-translation mode, \fBcrlf\fP mode converts carriage-return-linefeed
+translation mode, \fBcrlf\fR mode converts carriage-return-linefeed
sequences to newline characters. As the output translation mode,
-\fBcrlf\fP mode translates newline characters to carriage-return-linefeed
+\fBcrlf\fR mode translates newline characters to carriage-return-linefeed
sequences. This mode is typically used on Windows platforms and for
network connections.
.TP
@@ -251,12 +257,12 @@ set words {}
while {[llength $words] < 3} {
gets $f line
if {[string match "#*" $line]} continue
- lappend words [eval concat [scan $line %d%d%d]]
+ lappend words {*}[join [scan $line %d%d%d]]
}
# Those words supply the size of the image and its
# overall depth per channel. Assign to variables.
-foreach {xSize ySize depth} $words {break}
+lassign $words xSize ySize depth
# Now switch to binary mode to pull in the data,
# one byte per channel (red,green,blue) per pixel.
diff --git a/doc/fcopy.n b/doc/fcopy.n
index 3702f15..d583cf0 100644
--- a/doc/fcopy.n
+++ b/doc/fcopy.n
@@ -10,54 +10,56 @@
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
-fcopy \- Copy data from one channel to another.
+fcopy \- Copy data from one channel to another
.SH SYNOPSIS
\fBfcopy \fIinchan\fR \fIoutchan\fR ?\fB\-size \fIsize\fR? ?\fB\-command \fIcallback\fR?
.BE
.SH DESCRIPTION
.PP
-The \fBfcopy\fP command copies data from one I/O channel, \fIinchan\fR to another I/O channel, \fIoutchan\fR.
-The \fBfcopy\fP command leverages the buffering in the Tcl I/O system to
+The \fBfcopy\fR command copies data from one I/O channel, \fIinchan\fR to another I/O channel, \fIoutchan\fR.
+The \fBfcopy\fR command leverages the buffering in the Tcl I/O system to
avoid extra copies and to avoid buffering too much data in
main memory when copying large files to slow destinations like
network sockets.
.PP
-The \fBfcopy\fP
+The \fBfcopy\fR
command transfers data from \fIinchan\fR until end of file
-or \fIsize\fP bytes have been
-transferred. If no \fB\-size\fP argument is given,
+or \fIsize\fR bytes have been
+transferred. If no \fB\-size\fR argument is given,
then the copy goes until end of file.
All the data read from \fIinchan\fR is copied to \fIoutchan\fR.
-Without the \fB\-command\fP option, \fBfcopy\fP blocks until the copy is complete
+Without the \fB\-command\fR option, \fBfcopy\fR blocks until the copy is complete
and returns the number of bytes written to \fIoutchan\fR.
.PP
-The \fB\-command\fP argument makes \fBfcopy\fP work in the background.
-In this case it returns immediately and the \fIcallback\fP is invoked
+The \fB\-command\fR argument makes \fBfcopy\fR work in the background.
+In this case it returns immediately and the \fIcallback\fR is invoked
later when the copy completes.
-The \fIcallback\fP is called with
+The \fIcallback\fR is called with
one or two additional
arguments that indicates how many bytes were written to \fIoutchan\fR.
If an error occurred during the background copy, the second argument is the
error string associated with the error.
With a background copy,
it is not necessary to put \fIinchan\fR or \fIoutchan\fR into
-non-blocking mode; the \fBfcopy\fP command takes care of that automatically.
+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\fP command or by using Tk.
+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 fcopy.
+\fIinchan\fR or \fIoutchan\fR during a background \fBfcopy\fR.
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\fP made.
+and the command callback is \fInot\fR made.
If \fIinchan\fR is closed,
then all data already queued for \fIoutchan\fR is written out.
.PP
Note that \fIinchan\fR can become readable during a background copy.
-You should turn off any \fBfileevent\fP handlers during a background
+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\fP handler will get a "channel busy" error.
+Any I/O attempted by a \fBfileevent\fR handler will get a
+.QW "channel busy"
+error.
.PP
\fBFcopy\fR translates end-of-line sequences in \fIinchan\fR and \fIoutchan\fR
according to the \fB\-translation\fR option
@@ -67,30 +69,46 @@ See the manual entry for \fBfconfigure\fR for details on the
The translations mean that the number of bytes read from \fIinchan\fR
can be different than the number of bytes written to \fIoutchan\fR.
Only the number of bytes written to \fIoutchan\fR is reported,
-either as the return value of a synchronous \fBfcopy\fP or
-as the argument to the callback for an asynchronous \fBfcopy\fP.
+either as the return value of a synchronous \fBfcopy\fR or
+as the argument to the callback for an asynchronous \fBfcopy\fR.
.PP
-\fBFcopy\fR obeys the encodings configured for the channels. This
+\fBFcopy\fR obeys the encodings and character translations configured
+for the channels. This
means that the incoming characters are converted internally first
UTF-8 and then into the encoding of the channel \fBfcopy\fR writes
to. See the manual entry for \fBfconfigure\fR for details on the
-\fB\-encoding\fR option. No conversion is done if both channels are
-set to encoding "binary". If only the output channel is set to
-encoding "binary" the system will write the internal UTF-8
-representation of the incoming characters. If only the input channel
-is set to encoding "binary" the system will assume that the incoming
+\fB\-encoding\fR and \fB\-translation\fR options. No conversion is
+done if both channels are
+set to encoding
+.QW binary
+and have matching translations. If only the output channel is set to encoding
+.QW binary
+the system will write the internal UTF-8 representation of the incoming
+characters. If only the input channel is set to encoding
+.QW binary
+the system will assume that the incoming
bytes are valid UTF-8 characters and convert them according to the
output encoding. The behaviour of the system for bytes which are not
valid UTF-8 characters is undefined in this case.
-.SH EXAMPLE
+.SH EXAMPLES
.PP
-This first example shows how the callback gets
+The first example transfers the contents of one channel exactly to
+another. Note that when copying one file to another, it is better to
+use \fBfile copy\fR which also copies file metadata (e.g. the file
+access permissions) where possible.
+.CS
+fconfigure $in -translation binary
+fconfigure $out -translation binary
+\fBfcopy\fR $in $out
+.CE
+.PP
+This second example shows how the callback gets
passed the number of bytes transferred.
It also uses vwait to put the application into the event loop.
Of course, this simplified example could be done without the command
callback.
-.DS
+.CS
proc Cleanup {in out bytes {error {}}} {
global total
set total $bytes
@@ -102,14 +120,13 @@ proc Cleanup {in out bytes {error {}}} {
}
set in [open $file1]
set out [socket $server $port]
-fcopy $in $out -command [list Cleanup $in $out]
+\fBfcopy\fR $in $out -command [list Cleanup $in $out]
vwait total
-
-.DE
+.CE
.PP
-The second example copies in chunks and tests for end of file
+The third example copies in chunks and tests for end of file
in the command callback
-.DS
+.CS
proc CopyMore {in out chunk bytes {error {}}} {
global total done
incr total $bytes
@@ -118,21 +135,21 @@ proc CopyMore {in out chunk bytes {error {}}} {
close $in
close $out
} else {
- fcopy $in $out -command [list CopyMore $in $out $chunk] \\
- -size $chunk
+ \fBfcopy\fR $in $out -size $chunk \e
+ -command [list CopyMore $in $out $chunk]
}
}
set in [open $file1]
set out [socket $server $port]
set chunk 1024
set total 0
-fcopy $in $out -command [list CopyMore $in $out $chunk] -size $chunk
+\fBfcopy\fR $in $out -size $chunk \e
+ -command [list CopyMore $in $out $chunk]
vwait done
-
-.DE
+.CE
.SH "SEE ALSO"
-eof(n), fblocked(n), fconfigure(n)
+eof(n), fblocked(n), fconfigure(n), file(n)
.SH KEYWORDS
blocking, channel, end of line, end of file, nonblocking, read, translation
diff --git a/doc/file.n b/doc/file.n
index bc9eccc..b62d252 100644
--- a/doc/file.n
+++ b/doc/file.n
@@ -14,7 +14,6 @@ file \- Manipulate file names and attributes
.SH SYNOPSIS
\fBfile \fIoption\fR \fIname\fR ?\fIarg arg ...\fR?
.BE
-
.SH DESCRIPTION
.PP
This command provides several operations on a file's name or attributes.
@@ -30,7 +29,7 @@ Returns a decimal string giving the time at which file \fIname\fR was last
accessed. If \fItime\fR is specified, it is an access time to set
for the file. The time is measured in the standard POSIX fashion as
seconds from a fixed starting time (often January 1, 1970). If the file
-doesn't exist or its access time cannot be queried or set then an error is
+does not exist or its access time cannot be queried or set then an error is
generated. On Windows, FAT file systems do not support access time.
.TP
\fBfile attributes \fIname\fR
@@ -38,18 +37,19 @@ generated. On Windows, FAT file systems do not support access time.
\fBfile attributes \fIname\fR ?\fBoption\fR?
.TP
\fBfile attributes \fIname\fR ?\fBoption value option value...\fR?
-.RS
+.
This subcommand returns or sets platform specific values associated
with a file. The first form returns a list of the platform specific
flags and their values. The second form returns the value for the
specific option. The third form sets one or more of the values. The
values are as follows:
+.RS
.PP
-On Unix, \fB-group\fR gets or sets the group name for the file. A group id
-can be given to the command, but it returns a group name. \fB-owner\fR gets
+On Unix, \fB\-group\fR gets or sets the group name for the file. A group id
+can be given to the command, but it returns a group name. \fB\-owner\fR gets
or sets the user name of the owner of the file. The command returns the
owner name, but the numerical id can be passed when setting the
-owner. \fB-permissions\fR sets or retrieves the octal code that chmod(1)
+owner. \fB\-permissions\fR sets or retrieves the octal code that chmod(1)
uses. This command does also has limited support for setting using the
symbolic attributes for chmod(1), of the form [ugo]?[[+\-=][rwxst],[...]],
where multiple symbolic attributes can be separated by commas (example:
@@ -57,45 +57,49 @@ where multiple symbolic attributes can be separated by commas (example:
permissions for group and other). A simplified \fBls\fR style string,
of the form rwxrwxrwx (must be 9 characters), is also supported
(example: \fBrwxr\-xr\-t\fR is equivalent to 01755).
+On versions of Unix supporting file flags, \fB\-readonly\fR gives the
+value or sets or clears the readonly attribute of the file,
+i.e. the user immutable flag \fBuchg\fR to chflags(1).
.PP
-On Windows, \fB-archive\fR gives the value or sets or clears the
-archive attribute of the file. \fB-hidden\fR gives the value or sets
-or clears the hidden attribute of the file. \fB-longname\fR will
+On Windows, \fB\-archive\fR gives the value or sets or clears the
+archive attribute of the file. \fB\-hidden\fR gives the value or sets
+or clears the hidden attribute of the file. \fB\-longname\fR will
expand each path element to its long version. This attribute cannot be
-set. \fB-readonly\fR gives the value or sets or clears the readonly
-attribute of the file. \fB-shortname\fR gives a string where every
+set. \fB\-readonly\fR gives the value or sets or clears the readonly
+attribute of the file. \fB\-shortname\fR gives a string where every
path element is replaced with its short (8.3) version of the
-name. This attribute cannot be set. \fB-system\fR gives or sets or
+name. This attribute cannot be set. \fB\-system\fR gives or sets or
clears the value of the system attribute of the file.
.PP
-On Macintosh, \fB-creator\fR gives or sets the Finder creator type of
-the file. \fB-hidden\fR gives or sets or clears the hidden attribute
-of the file. \fB-readonly\fR gives or sets or clears the readonly
-attribute of the file. Note that directories can only be locked if
-File Sharing is turned on. \fB-type\fR gives or sets the Finder file
-type for the file.
+On Mac OS X and Darwin, \fB\-creator\fR gives or sets the
+Finder creator type of the file. \fB\-hidden\fR gives or sets or clears
+the hidden attribute of the file. \fB\-readonly\fR gives or sets or
+clears the readonly attribute of the file. \fB\-rsrclength\fR gives
+the length of the resource fork of the file, this attribute can only be
+set to the value 0, which results in the resource fork being stripped
+off the file.
.RE
-.VS
.TP
\fBfile channels ?\fIpattern\fR?
.
-If \fIpattern\fR isn't specified, returns a list of names of all
+If \fIpattern\fR is not specified, returns a list of names of all
registered open channels in this interpreter. If \fIpattern\fR is
specified, only those names matching \fIpattern\fR are returned. Matching
is determined using the same rules as for \fBstring match\fR.
-.VE
.TP
\fBfile copy \fR?\fB\-force\fR? ?\fB\-\|\-\fR? \fIsource\fR \fItarget\fR
.TP
\fBfile copy \fR?\fB\-force\fR? ?\fB\-\|\-\fR? \fIsource\fR ?\fIsource\fR ...? \fItargetDir\fR
-.RS
+.
The first form makes a copy of the file or directory \fIsource\fR under
the pathname \fItarget\fR. If \fItarget\fR is an existing directory,
then the second form is used. The second form makes a copy inside
\fItargetDir\fR of each \fIsource\fR file listed. If a directory is
specified as a \fIsource\fR, then the contents of the directory will be
recursively copied into \fItargetDir\fR. Existing files will not be
-overwritten unless the \fB\-force\fR option is specified. When copying
+overwritten unless the \fB\-force\fR option is specified (when Tcl will
+also attempt to adjust permissions on the destination file or directory
+if that is necessary to allow the copy to proceed). When copying
within a single filesystem, \fIfile copy\fR will copy soft links (i.e.
the links themselves are copied, not the things they point to). Trying
to overwrite a non-empty directory, overwrite a directory with a file,
@@ -104,7 +108,6 @@ or overwrite a file with a directory will all result in errors even if
specified, halting at the first error, if any. A \fB\-\|\-\fR marks
the end of switches; the argument following the \fB\-\|\-\fR will be
treated as a \fIsource\fR even if it starts with a \fB\-\fR.
-.RE
.TP
\fBfile delete \fR?\fB\-force\fR? ?\fB\-\|\-\fR? \fIpathname\fR ?\fIpathname\fR ... ?
.
@@ -116,9 +119,11 @@ Trying to delete a non-existent file is not considered an error.
Trying to delete a read-only file will cause the file to be deleted,
even if the \fB\-force\fR flags is not specified. If the \fB\-force\fR
option is specified on a directory, Tcl will attempt both to change
-permissions and move the current directory 'pwd' out of the given path
-if that is necessary to allow the deletion to proceed. Arguments are
-processed in the order specified, halting at the first error, if any.
+permissions and move the current directory
+.QW pwd
+out of the given path if that is necessary to allow the deletion to
+proceed. Arguments are processed in the order specified, halting at
+the first error, if any.
A \fB\-\|\-\fR marks the end of switches; the argument following the
\fB\-\|\-\fR will be treated as a \fIpathname\fR even if it starts with
a \fB\-\fR.
@@ -126,9 +131,10 @@ a \fB\-\fR.
\fBfile dirname \fIname\fR
Returns a name comprised of all of the path components in \fIname\fR
excluding the last element. If \fIname\fR is a relative file name and
-only contains one path element, then returns ``\fB.\fR'' (or ``\fB:\fR''
-on the Macintosh). If \fIname\fR refers to a root directory, then the
-root directory is returned. For example,
+only contains one path element, then returns
+.QW \fB.\fR .
+If \fIname\fR refers to a root directory, then the root directory is
+returned. For example,
.RS
.CS
\fBfile dirname c:/\fR
@@ -186,39 +192,53 @@ returns \fB/foo/bar\fR.
.PP
Note that any of the names can contain separators, and that the result
is always canonical for the current platform: \fB/\fR for Unix and
-Windows, and \fB:\fR for Macintosh.
+Windows.
.RE
.TP
-\fBfile link ?\fI-linktype\fR? \fIlinkName\fR ?\fItarget\fR?
+\fBfile link ?\fI\-linktype\fR? \fIlinkName\fR ?\fItarget\fR?
.
If only one argument is given, that argument is assumed to be
\fIlinkName\fR, and this command returns the value of the link given by
\fIlinkName\fR (i.e. the name of the file it points to). If
-\fIlinkName\fR isn't a link or its value cannot be read (as, for example,
+\fIlinkName\fR is not a link or its value cannot be read (as, for example,
seems to be the case with hard links, which look just like ordinary
files), then an error is returned.
-.
+.RS
+.PP
If 2 arguments are given, then these are assumed to be \fIlinkName\fR
and \fItarget\fR. If \fIlinkName\fR already exists, or if \fItarget\fR
-doesn't exist, an error will be returned. Otherwise, Tcl creates a new
-link called \fIlinkName\fR which points to the existing filesystem object
-at \fItarget\fR, where the type of the link is platform-specific (on Unix
-a symbolic link will be the default). This is useful for the case where
-the user wishes to create a link in a cross-platform way, and doesn't
-care what type of link is created.
-.
+does not exist, an error will be returned. Otherwise, Tcl creates a new
+link called \fIlinkName\fR which points to the existing filesystem
+object at \fItarget\fR (which is also the returned value), where the
+type of the link is platform-specific (on Unix a symbolic link will be
+the default). This is useful for the case where the user wishes to
+create a link in a cross-platform way, and does not care what type of
+link is created.
+.PP
If the user wishes to make a link of a specific type only, (and signal an
error if for some reason that is not possible), then the optional
-\fI-linktype\fR argument should be given. Accepted values for
-\fI-linktype\fR are "-symbolic" and "-hard".
-.
-When creating links on filesystems that either do not support any links,
-or do not support the specific type requested, an error message will be
-returned. In particular Windows 95, 98 and ME do not support any links
-at present, but most Unix platforms support both symbolic and hard links
-(the latter for files only), MacOS supports symbolic links and Windows
-NT/2000/XP (on NTFS drives) support symbolic directory links and hard
-file links.
+\fI\-linktype\fR argument should be given. Accepted values for
+\fI\-linktype\fR are
+.QW \-symbolic
+and
+.QW \-hard .
+.PP
+On Unix, symbolic links can be made to relative paths, and those paths
+must be relative to the actual \fIlinkName\fR's location (not to the
+cwd), but on all other platforms where relative links are not supported,
+target paths will always be converted to absolute, normalized form
+before the link is created (and therefore relative paths are interpreted
+as relative to the cwd). Furthermore,
+.QW ~user
+paths are always expanded
+to absolute form. When creating links on filesystems that either do not
+support any links, or do not support the specific type requested, an
+error message will be returned. In particular Windows 95, 98 and ME do
+not support any links at present, but most Unix platforms support both
+symbolic and hard links (the latter for files only) and Windows
+NT/2000/XP (on NTFS drives) support symbolic
+directory links and hard file links.
+.RE
.TP
\fBfile lstat \fIname varName\fR
.
@@ -226,7 +246,7 @@ Same as \fBstat\fR option (see below) except uses the \fIlstat\fR
kernel call instead of \fIstat\fR. This means that if \fIname\fR
refers to a symbolic link the information returned in \fIvarName\fR
is for the link rather than the file it refers to. On systems that
-don't support symbolic links this option behaves exactly the same
+do not support symbolic links this option behaves exactly the same
as the \fBstat\fR option.
.TP
\fBfile mkdir \fIdir\fR ?\fIdir\fR ...?
@@ -244,32 +264,35 @@ Returns a decimal string giving the time at which file \fIname\fR was last
modified. If \fItime\fR is specified, it is a modification time to set for
the file (equivalent to Unix \fBtouch\fR). The time is measured in the
standard POSIX fashion as seconds from a fixed starting time (often January
-1, 1970). If the file doesn't exist or its modified time cannot be queried
+1, 1970). If the file does not exist or its modified time cannot be queried
or set then an error is generated.
.TP
\fBfile nativename \fIname\fR
.
Returns the platform-specific name of the file. This is useful if the
-filename is needed to pass to a platform-specific call, such as exec
-under Windows or AppleScript on the Macintosh.
+filename is needed to pass to a platform-specific call, such as to a
+subprocess via \fBexec\fR under Windows (see \fBEXAMPLES\fR below).
.TP
\fBfile normalize \fIname\fR
.
-.RS
Returns a unique normalized path representation for the file-system
object (file, directory, link, etc), whose string value can be used as a
unique identifier for it. A normalized path is an absolute path which has
-all '../', './' removed. Also it is one which is in the ``standard''
-format for the native platform. On MacOS, Unix, this means the segments
+all
+.QW ../
+and
+.QW ./
+removed. Also it is one which is in the
+.QW standard
+format for the native platform. On Unix, this means the segments
leading up to the path must be free of symbolic links/aliases (but the
very last path component may be a symbolic link), and on Windows it also
means we want the long form with that form's case-dependence (which
gives us a unique, case-dependent path). The one exception concerning the
last link in the path is necessary, because Tcl or the user may wish to
-operate on the actual symbolic link itself (for example 'file delete', 'file
-rename', 'file copy' are defined to operate on symbolic links, not on the
-things that they point to).
-.RE
+operate on the actual symbolic link itself (for example \fBfile delete\fR,
+\fBfile rename\fR, \fBfile copy\fR are defined to operate on symbolic
+links, not on the things that they point to).
.TP
\fBfile owned \fIname\fR
.
@@ -278,13 +301,13 @@ otherwise.
.TP
\fBfile pathtype \fIname\fR
.
-Returns one of \fBabsolute\fR, \fBrelative\fR, \fBvolumerelative\fR. If
-\fIname\fR refers to a specific file on a specific volume, the path type
-will be \fBabsolute\fR. If \fIname\fR refers to a file relative to the
-current working directory, then the path type will be \fBrelative\fR. If
-\fIname\fR refers to a file relative to the current working directory on
-a specified volume, or to a specific file on the current working volume, then
-the path type is \fBvolumerelative\fR.
+Returns one of \fBabsolute\fR, \fBrelative\fR, \fBvolumerelative\fR. If
+\fIname\fR refers to a specific file on a specific volume, the path type will
+be \fBabsolute\fR. If \fIname\fR refers to a file relative to the current
+working directory, then the path type will be \fBrelative\fR. If \fIname\fR
+refers to a file relative to the current working directory on a specified
+volume, or to a specific file on the current working volume, then the path
+type is \fBvolumerelative\fR.
.TP
\fBfile readable \fIname\fR
.
@@ -294,14 +317,14 @@ Returns \fB1\fR if file \fIname\fR is readable by the current user,
\fBfile readlink \fIname\fR
.
Returns the value of the symbolic link given by \fIname\fR (i.e. the name
-of the file it points to). If \fIname\fR isn't a symbolic link or its
-value cannot be read, then an error is returned. On systems that don't
+of the file it points to). If \fIname\fR is not a symbolic link or its
+value cannot be read, then an error is returned. On systems that do not
support symbolic links this option is undefined.
.TP
\fBfile rename \fR?\fB\-force\fR? ?\fB\-\|\-\fR? \fIsource\fR \fItarget\fR
.TP
\fBfile rename \fR?\fB\-force\fR? ?\fB\-\|\-\fR? \fIsource\fR ?\fIsource\fR ...? \fItargetDir\fR
-.RS
+.
The first form takes the file or directory specified by pathname
\fIsource\fR and renames it to \fItarget\fR, moving the file if the
pathname \fItarget\fR specifies a name in a different directory. If
@@ -316,13 +339,14 @@ result in errors. Arguments are processed in the order specified,
halting at the first error, if any. A \fB\-\|\-\fR marks the end of
switches; the argument following the \fB\-\|\-\fR will be treated as a
\fIsource\fR even if it starts with a \fB\-\fR.
-.RE
.TP
\fBfile rootname \fIname\fR
.
Returns all of the characters in \fIname\fR up to but not including the
-last ``.'' character in the last component of name. If the last
-component of \fIname\fR doesn't contain a dot, then returns \fIname\fR.
+last
+.QW .
+character in the last component of name. If the last
+component of \fIname\fR does not contain a dot, then returns \fIname\fR.
.TP
\fBfile separator\fR ?\fIname\fR?
.
@@ -335,7 +359,7 @@ is generated.
\fBfile size \fIname\fR
.
Returns a decimal string giving the size of file \fIname\fR in bytes. If
-the file doesn't exist or its size cannot be queried then an error is
+the file does not exist or its size cannot be queried then an error is
generated.
.TP
\fBfile split \fIname\fR
@@ -343,7 +367,7 @@ generated.
Returns a list whose elements are the path components in \fIname\fR. The
first element of the list will have the same path type as \fIname\fR.
All other elements will be relative. Path separators will be discarded
-unless they are needed ensure that an element is unambiguously relative.
+unless they are needed to ensure that an element is unambiguously relative.
For example, under Unix
.RS
.CS
@@ -370,24 +394,32 @@ empty string.
.TP
\fBfile system \fIname\fR
.
-Returns a list of two elements, the first of which is the name of the
-filesystem to use for the file, and the second an arbitrary string
-representing the filesystem-specific nature or type of the location
-within that filesystem. If a filesystem only supports one type of file,
-the second element may be null. For example the native files have a
-first element 'native', and a second element which is a platform-specific
-type name for the file's system (e.g. 'NTFS', 'FAT', etc), or possibly
-the empty string if no further information is available or if this
-is not implemented. A generic virtual file system might return the
-list 'vfs ftp' to represent a file on a remote ftp site mounted as a
-virtual filesystem through an extension called 'vfs'. If the file does
-not belong to any filesystem, an error is generated.
+Returns a list of one or two elements, the first of which is the name of
+the filesystem to use for the file, and the second, if given, an
+arbitrary string representing the filesystem-specific nature or type of
+the location within that filesystem. If a filesystem only supports one
+type of file, the second element may not be supplied. For example the
+native files have a first element
+.QW native ,
+and a second element which when given is a platform-specific type name
+for the file's system (e.g.
+.QW NTFS ,
+.QW FAT ,
+on Windows). A generic virtual file system might return
+the list
+.QW "vfs ftp"
+to represent a file on a remote ftp site mounted as a
+virtual filesystem through an extension called
+.QW vfs .
+If the file does not belong to any filesystem, an error is generated.
.TP
\fBfile tail \fIname\fR
.
-Returns all of the characters in \fIname\fR after the last directory
-separator. If \fIname\fR contains no separators then returns
-\fIname\fR.
+Returns all of the characters in the last filesystem component of
+\fIname\fR. Any trailing directory separator in \fIname\fR is ignored.
+If \fIname\fR contains no separators then returns \fIname\fR. So,
+\fBfile tail a/b\fR, \fBfile tail a/b/\fR and \fBfile tail b\fR all
+return \fBb\fR.
.TP
\fBfile type \fIname\fR
.
@@ -398,13 +430,15 @@ Returns a string giving the type of file \fIname\fR, which will be one of
\fBfile volumes\fR
.
Returns the absolute paths to the volumes mounted on the system, as a
-proper Tcl list. On the Macintosh, this will be a list of the mounted
-drives, both local and network. N.B. if two drives have the same name,
-they will both appear on the volume list, but there is currently no way,
-from Tcl, to access any but the first of these drives. On UNIX, the
-command will always return "/", since all filesystems are locally mounted.
+proper Tcl list. Without any virtual filesystems mounted as root
+volumes, on UNIX, the command will always return
+.QW / ,
+since all filesystems are locally mounted.
On Windows, it will return a list of the available local drives
-(e.g. {a:/ c:/}).
+(e.g.
+.QW "a:/ c:/" ).
+If any virtual filesystem has mounted additional
+volumes, they will be in the returned list.
.TP
\fBfile writable \fIname\fR
.
@@ -431,7 +465,7 @@ proc findMatchingCFiles {dir} {
set ext .o
}
}
- foreach file [glob -nocomplain -directory $dir *.c] {
+ foreach file [glob \-nocomplain \-directory $dir *.c] {
set objectFile [\fBfile tail\fR [\fBfile rootname\fR $file]]$ext
if {[\fBfile exists\fR $objectFile]} {
lappend files $file
@@ -451,12 +485,19 @@ if {![\fBfile isdirectory\fR [\fBfile dirname\fR $newName]]} {
\fBfile mkdir\fR [\fBfile dirname\fR $newName]
}
\fBfile rename\fR $oldName $newName
-\fBfile link\fR -symbolic $oldName $newName
+\fBfile link\fR \-symbolic $oldName $newName
+.CE
+.PP
+On Windows, a file can be
+.QW started
+easily enough (equivalent to double-clicking on it in the Explorer
+interface) but the name passed to the operating system must be in
+native format:
+.CS
+exec {*}[auto_execok start] {} [\fBfile nativename\fR ~/example.txt]
.CE
-
.SH "SEE ALSO"
filename(n), open(n), close(n), eof(n), gets(n), tell(n), seek(n),
fblocked(n), flush(n)
-
.SH KEYWORDS
attributes, copy files, delete files, directory, file, move files, name, rename files, stat
diff --git a/doc/fileevent.n b/doc/fileevent.n
index 99fe43a..eb555f5 100644
--- a/doc/fileevent.n
+++ b/doc/fileevent.n
@@ -28,17 +28,17 @@ interact with the user while waiting for the data to arrive. If an
application invokes \fBgets\fR or \fBread\fR on a blocking channel when
there is no input data available, the process will block; until the input
data arrives, it will not be able to service other events, so it will
-appear to the user to ``freeze up''. With \fBfileevent\fR, the process can
+appear to the user to
+.QW "freeze up" .
+With \fBfileevent\fR, the process can
tell when data is present and only invoke \fBgets\fR or \fBread\fR when
-they won't block.
+they will not block.
.PP
-.VS
The \fIchannelId\fR argument to \fBfileevent\fR refers to an open
channel such as a 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.
-.VE
.PP
If the \fIscript\fR argument is specified, then \fBfileevent\fR
creates a new event handler: \fIscript\fR will be evaluated
@@ -94,7 +94,7 @@ The script for a file event is executed at global level (outside the
context of any Tcl procedure) in the interpreter in which the
\fBfileevent\fR command was invoked.
If an error occurs while executing the script then the
-\fBbgerror\fR mechanism is used to report the error.
+command registered with \fBinterp bgerror\fR is used to report the error.
In addition, the file event handler is deleted if it ever returns
an error; this is done in order to prevent infinite loops due to
buggy handlers.
@@ -117,7 +117,7 @@ proc GetData {chan} {
by Mark Diekhans.
.SH "SEE ALSO"
-bgerror(n), fconfigure(n), gets(n), puts(n), read(n), Tcl_StandardChannels(3)
+fconfigure(n), gets(n), interp(n), puts(n), read(n), Tcl_StandardChannels(3)
.SH KEYWORDS
asynchronous I/O, blocking, channel, event handler, nonblocking, readable,
diff --git a/doc/filename.n b/doc/filename.n
index b588440..1fe22f0 100644
--- a/doc/filename.n
+++ b/doc/filename.n
@@ -23,7 +23,6 @@ to be portable should not assume a particular form for file names.
Instead, portable scripts must use the \fBfile split\fR and \fBfile
join\fR commands to manipulate file names (see the \fBfile\fR manual
entry for more details).
-
.SH "PATH TYPES"
.PP
File names are grouped into three general types based on the starting point
@@ -36,76 +35,26 @@ qualified, either giving the path relative to the root directory on the
current volume, or relative to the current directory of the specified
volume. The \fBfile pathtype\fR command can be used to determine the
type of a given path.
-
.SH "PATH SYNTAX"
.PP
The rules for native names depend on the value reported in the Tcl
array element \fBtcl_platform(platform)\fR:
.TP 10
-\fBmac\fR
-On Apple Macintosh systems, Tcl supports two forms of path names. The
-normal Mac style names use colons as path separators. Paths may be
-relative or absolute, and file names may contain any character other
-than colon. A leading colon causes the rest of the path to be
-interpreted relative to the current directory. If a path contains a
-colon that is not at the beginning, then the path is interpreted as an
-absolute path. Sequences of two or more colons anywhere in the path
-are used to construct relative paths where \fB::\fR refers to the
-parent of the current directory, \fB:::\fR refers to the parent of the
-parent, and so forth.
+\fBUnix\fR
+On Unix and Apple MacOS X platforms, Tcl uses path names where the
+components are separated by slashes. Path names may be relative or
+absolute, and file names may contain any character other than slash.
+The file names \fB\&.\fR and \fB\&..\fR are special and refer to the
+current directory and the parent of the current directory respectively.
+Multiple adjacent slash characters are interpreted as a single
+separator. Any number of trailing slash characters at the end of a
+path are simply ignored, so the paths \fBfoo\fR, \fBfoo/\fR and
+\fBfoo//\fR are all identical, and in particular \fBfoo/\fR does not
+necessarily mean a directory is being referred.
.RS
.PP
-In addition to Macintosh style names, Tcl also supports a subset of
-Unix-like names. If a path contains no colons, then it is interpreted
-like a Unix path. Slash is used as the path separator. The file name
-\fB\&.\fR refers to the current directory, and \fB\&..\fR refers to the
-parent of the current directory. However, some names like \fB/\fR or
-\fB/..\fR have no mapping, and are interpreted as Macintosh names. In
-general, commands that generate file names will return Macintosh style
-names, but commands that accept file names will take both Macintosh
-and Unix-style names.
-.PP
-The following examples illustrate various forms of path names:
-.TP 15
-\fB:\fR
-Relative path to the current folder.
-.TP 15
-\fBMyFile\fR
-Relative path to a file named \fBMyFile\fR in the current folder.
-.TP 15
-\fBMyDisk:MyFile\fR
-Absolute path to a file named \fBMyFile\fR on the device named \fBMyDisk\fR.
-.TP 15
-\fB:MyDir:MyFile\fR
-Relative path to a file name \fBMyFile\fR in a folder named
-\fBMyDir\fR in the current folder.
-.TP 15
-\fB::MyFile\fR
-Relative path to a file named \fBMyFile\fR in the folder above the
-current folder.
-.TP 15
-\fB:::MyFile\fR
-Relative path to a file named \fBMyFile\fR in the folder two levels above the
-current folder.
-.TP 15
-\fB/MyDisk/MyFile\fR
-Absolute path to a file named \fBMyFile\fR on the device named
-\fBMyDisk\fR.
-.TP 15
-\fB\&../MyFile\fR
-Relative path to a file named \fBMyFile\fR in the folder above the
-current folder.
-.RE
-.TP
-\fBunix\fR
-On Unix platforms, Tcl uses path names where the components are
-separated by slashes. Path names may be relative or absolute, and
-file names may contain any character other than slash. The file names
-\fB\&.\fR and \fB\&..\fR are special and refer to the current directory
-and the parent of the current directory respectively. Multiple
-adjacent slash characters are interpreted as a single separator.
-The following examples illustrate various forms of path names:
-.RS
+The following examples illustrate various forms of path
+names:
.TP 15
\fB/\fR
Absolute path to the root directory.
@@ -129,7 +78,7 @@ Relative path to the file \fBfoo\fR in the directory above the current
directory.
.RE
.TP
-\fBwindows\fR
+\fBWindows\fR
On Microsoft Windows platforms, Tcl supports both drive-relative and UNC
style names. Both \fB/\fR and \fB\e\fR may be used as directory separators
in either type of name. Drive-relative names consist of an optional drive
@@ -169,37 +118,39 @@ Volume-relative path to a file \fBfoo\fR in the root directory of the current
volume. This is not a valid UNC path, so the assumption is that the
extra backslashes are superfluous.
.RE
-
.SH "TILDE SUBSTITUTION"
.PP
In addition to the file name rules described above, Tcl also supports
-\fIcsh\fR-style tilde substitution. If a file name starts with a
-tilde, then the file name will be interpreted as if the first element
-is replaced with the location of the home directory for the given
-user. If the tilde is followed immediately by a separator, then the
-\fB$HOME\fR environment variable is substituted. Otherwise the
-characters between the tilde and the next separator are taken as a
-user name, which is used to retrieve the user's home directory for
-substitution.
+\fIcsh\fR-style tilde substitution. If a file name starts with a tilde,
+then the file name will be interpreted as if the first element is
+replaced with the location of the home directory for the given user. If
+the tilde is followed immediately by a separator, then the \fB$HOME\fR
+environment variable is substituted. Otherwise the characters between
+the tilde and the next separator are taken as a user name, which is used
+to retrieve the user's home directory for substitution. This works on
+Unix, MacOS X and Windows (except very old releases).
.PP
-The Macintosh and Windows platforms do not support tilde substitution
-when a user name follows the tilde. On these platforms, attempts to
-use a tilde followed by a user name will generate an error that the
-user does not exist when Tcl attempts to interpret that part of the
-path or otherwise access the file. The behaviour of these paths
-when not trying to interpret them is the same as on Unix. File
-names that have a tilde without a user name will be correctly
-substituted using the \fB$HOME\fR environment variable, just like
-for Unix.
-
+Old Windows platforms do not support tilde substitution when a user name
+follows the tilde. On these platforms, attempts to use a tilde followed
+by a user name will generate an error that the user does not exist when
+Tcl attempts to interpret that part of the path or otherwise access the
+file. The behaviour of these paths when not trying to interpret them is
+the same as on Unix. File names that have a tilde without a user name
+will be correctly substituted using the \fB$HOME\fR environment
+variable, just like for Unix.
.SH "PORTABILITY ISSUES"
.PP
Not all file systems are case sensitive, so scripts should avoid code
that depends on the case of characters in a file name. In addition,
the character sets allowed on different devices may differ, so scripts
should choose file names that do not contain special characters like:
-\fB<>:"/\e|\fR. The safest approach is to use names consisting of
-alphanumeric characters only. Also Windows 3.1 only supports file
+\fB<>:?"/\e|\fR.
+'\""\" reset emacs highlighting
+The safest approach is to use names consisting of
+alphanumeric characters only. Care should be taken with filenames
+which contain spaces (common on Windows systems) and
+filenames where the backslash is the directory separator (Windows
+native path names). Also Windows 3.1 only supports file
names with a root of no more than 8 characters and an extension of no
more than 3 characters.
.PP
@@ -207,16 +158,21 @@ On Windows platforms there are file and path length restrictions.
Complete paths or filenames longer than about 260 characters will lead
to errors in most file operations.
.PP
-Another Windows peculiarity is that any number of trailing dots '.' in
-filenames are totally ignored, so, for example, attempts to create a
-file or directory with a name "foo." will result in the creation of a
-file/directory with name "foo". This fact is reflected in the
-results of 'file normalize'. Furthermore, a file name consisting only
-of dots '.........' or dots with trailing characters '.....abc' is
-illegal.
+Another Windows peculiarity is that any number of trailing dots
+.QW .
+in filenames are totally ignored, so, for example, attempts to create a
+file or directory with a name
+.QW foo.
+will result in the creation of a file/directory with name
+.QW foo .
+This fact is reflected in the results of \fBfile normalize\fR.
+Furthermore, a file name consisting only of dots
+.QW .........
+or dots with trailing characters
+.QW .....abc
+is illegal.
+.SH "SEE ALSO"
+file(n), glob(n)
.SH KEYWORDS
current directory, absolute file name, relative file name,
volume-relative file name, portability
-
-.SH "SEE ALSO"
-file(n), glob(n)
diff --git a/doc/flush.n b/doc/flush.n
index a288141..1c79ea0 100644
--- a/doc/flush.n
+++ b/doc/flush.n
@@ -19,13 +19,11 @@ flush \- Flush buffered output for a channel
.PP
Flushes any output that has been buffered for \fIchannelId\fR.
.PP
-.VS
\fIChannelId\fR must be an identifier for an open channel such as a
Tcl standard channel (\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. The
channel must have been opened for writing.
-.VE
.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
diff --git a/doc/for.n b/doc/for.n
index 14755cb..033903f 100644
--- a/doc/for.n
+++ b/doc/for.n
@@ -10,7 +10,7 @@
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
-for \- ``For'' loop
+for \- 'For' loop
.SH SYNOPSIS
\fBfor \fIstart test next body\fR
.BE
diff --git a/doc/foreach.n b/doc/foreach.n
index be7a6fb..654c0cf 100644
--- a/doc/foreach.n
+++ b/doc/foreach.n
@@ -35,9 +35,9 @@ In the general case there can be more than one value list
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\fP are assigned
-consecutive values from the corresponding \fIlist\fP.
-Values in each \fIlist\fP are used in order from first to last,
+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.
@@ -49,37 +49,48 @@ The \fBbreak\fR and \fBcontinue\fR statements may be
invoked inside \fIbody\fR, with the same effect as in the \fBfor\fR
command. \fBForeach\fR returns an empty string.
.SH EXAMPLES
+This loop prints every value in a list together with the square and
+cube of the value:
+.CS
+'\" Maintainers: notice the tab hacking below!
+.ta 3i
+set values {1 3 5 7 2 4 6 8} ;# Odd numbers first, for fun!
+puts "Value\etSquare\etCube" ;# Neat-looking header
+\fBforeach\fR x $values { ;# Now loop and print...
+ puts " $x\et [expr {$x**2}]\et [expr {$x**3}]"
+}
+.CE
.PP
The following loop uses i and j as loop variables to iterate over
pairs of elements of a single list.
-.DS
+.CS
set x {}
\fBforeach\fR {i j} {a b c d e f} {
lappend x $j $i
}
# The value of x is "b a d c f e"
# There are 3 iterations of the loop.
-.DE
+.CE
.PP
The next loop uses i and j to iterate over two lists in parallel.
-.DS
+.CS
set x {}
\fBforeach\fR i {a b c} j {d e f g} {
lappend x $i $j
}
# The value of x is "a d b e c f {} g"
# There are 4 iterations of the loop.
-.DE
+.CE
.PP
The two forms are combined in the following example.
-.DS
+.CS
set x {}
\fBforeach\fR i {a b c} {j k} {d e f g} {
lappend x $i $j $k
}
# The value of x is "a d e b f g c {} {}"
# There are 3 iterations of the loop.
-.DE
+.CE
.SH "SEE ALSO"
for(n), while(n), break(n), continue(n)
diff --git a/doc/format.n b/doc/format.n
index 0dea667..f842f16 100644
--- a/doc/format.n
+++ b/doc/format.n
@@ -17,9 +17,8 @@ format \- Format a string in the style of sprintf
.SH INTRODUCTION
.PP
-This command generates a formatted string in the same way as the
-ANSI C \fBsprintf\fR procedure (it uses \fBsprintf\fR in its
-implementation).
+This command generates a formatted string in a fashion similar to the
+ANSI C \fBsprintf\fR procedure.
\fIFormatString\fR indicates how to format the result, using
\fB%\fR conversion specifiers as in \fBsprintf\fR, and the additional
arguments, if any, provide values to be substituted into the result.
@@ -42,15 +41,15 @@ of all of the conversion specifiers in \fIformatString\fR.
.PP
Each conversion specifier may contain up to six different parts:
an XPG3 position specifier,
-a set of flags, a minimum field width, a precision, a length modifier,
+a set of flags, a minimum field width, a precision, a size modifier,
and a conversion character.
Any of these fields may be omitted except for the conversion character.
The fields that are present must appear in the order given above.
The paragraphs below discuss each of these fields in turn.
.PP
If the \fB%\fR is followed by a decimal number and a \fB$\fR, as in
-``\fB%2$d\fR'', then the value to convert is not taken from the
-next sequential argument.
+.QW \fB%2$d\fR ,
+then the value to convert is not taken from the next sequential argument.
Instead, it is taken from the argument indicated by the number,
where 1 corresponds to the first \fIarg\fR.
If the conversion specifier requires multiple arguments because
@@ -74,8 +73,8 @@ Specifies that a number should always be printed with a sign,
even if positive.
.TP 10
\fIspace\fR
-Specifies that a space should be added to the beginning of the
-number if the first character isn't a sign.
+Specifies that a space should be added to the beginning of the
+number if the first character is not a sign.
.TP 10
\fB0\fR
Specifies that the number should be padded on the left with
@@ -92,7 +91,7 @@ has a decimal point.
For \fBg\fR and \fBG\fR conversions it specifies that
trailing zeroes should not be removed.
.PP
-The third portion of a conversion specifier is a number giving a
+The third portion of a conversion specifier is a decimal number giving a
minimum field width for this conversion.
It is typically used to make columns line up in tabular printouts.
If the converted argument contains fewer characters than the
@@ -104,7 +103,7 @@ may be used to specify padding with zeroes on the left or with
spaces on the right, respectively.
If the minimum field width is specified as \fB*\fR rather than
a number, then the next argument to the \fBformat\fR command
-determines the minimum field width; it must be a numeric string.
+determines the minimum field width; it must be an integer value.
.PP
The fourth portion of a conversion specifier is a precision,
which consists of a period followed by a number.
@@ -123,17 +122,19 @@ If the precision is specified with \fB*\fR rather than a number
then the next argument to the \fBformat\fR command determines the precision;
it must be a numeric string.
.PP
-The fifth part of a conversion specifier is a length modifier,
-which must be \fBh\fR or \fBl\fR.
-If it is \fBh\fR it specifies that the numeric value should be
-truncated to a 16-bit value before converting.
-This option is rarely useful.
-.VS 8.4
-If it is \fBl\fR it specifies that the numeric value should be (at
-least) a 64-bit value. If neither \fBh\fR nor \fBl\fR are present,
-numeric values are interpreted as being values of the width of the
-native machine word, as described by \fBtcl_platform(wordSize)\fR.
-.VE
+The fifth part of a conversion specifier is a size modifier,
+which must be \fBll\fR, \fBh\fR, or \fBl\fR.
+If it is \fBll\fR it specifies that an integer value is taken
+without truncation for conversion to a formatted substring.
+If it is \fBh\fR it specifies that an integer value is
+truncated to a 16-bit range before converting. This option is rarely useful.
+If it is \fBl\fR it specifies that the integer value is
+truncated to the same range as that produced by the \fBwide()\fR
+function of the \fBexpr\fR command (at least a 64-bit range).
+If neither \fBh\fR nor \fBl\fR are present, the integer value is
+truncated to the same range as that produced by the \fBint()\fR
+function of the \fBexpr\fR command (at least a 32-bit range, but
+determined by the value of \fBtcl_platform(wordSize)\fR).
.PP
The last thing in a conversion specifier is an alphabetic character
that determines what kind of conversion to perform.
@@ -146,33 +147,32 @@ Convert integer to signed decimal string.
Convert integer to unsigned decimal string.
.TP 10
\fBi\fR
-Convert integer to signed decimal string; the integer may either be
-in decimal, in octal (with a leading \fB0\fR) or in hexadecimal
-(with a leading \fB0x\fR).
+Convert integer to signed decimal string (equivalent to \fBd\fR).
.TP 10
\fBo\fR
Convert integer to unsigned octal string.
.TP 10
\fBx\fR or \fBX\fR
Convert integer to unsigned hexadecimal string, using digits
-``0123456789abcdef'' for \fBx\fR and ``0123456789ABCDEF'' for \fBX\fR).
-.VS
+.QW 0123456789abcdef
+for \fBx\fR and
+.QW 0123456789ABCDEF
+for \fBX\fR).
.TP 10
\fBc\fR
Convert integer to the Unicode character it represents.
-.VE
.TP 10
\fBs\fR
No conversion; just insert string.
.TP 10
\fBf\fR
-Convert floating-point number to signed decimal string of
+Convert number to signed decimal string of
the form \fIxx.yyy\fR, where the number of \fIy\fR's is determined by
the precision (default: 6).
If the precision is 0 then no decimal point is output.
.TP 10
-\fBe\fR or \fBe\fR
-Convert floating-point number to scientific notation in the
+\fBe\fR or \fBE\fR
+Convert number to scientific notation in the
form \fIx.yyy\fBe\(+-\fIzz\fR, where the number of \fIy\fR's is determined
by the precision (default: 6).
If the precision is 0 then no decimal point is output.
@@ -181,40 +181,34 @@ printed instead of \fBe\fR.
.TP 10
\fBg\fR or \fBG\fR
If the exponent is less than \-4 or greater than or equal to the
-precision, then convert floating-point number as for \fB%e\fR or
+precision, then convert number as for \fB%e\fR or
\fB%E\fR.
Otherwise convert as for \fB%f\fR.
Trailing zeroes and a trailing decimal point are omitted.
.TP 10
\fB%\fR
No conversion: just insert \fB%\fR.
-.LP
-For the numerical conversions the argument being converted must
-be an integer or floating-point string; format converts the argument
-to binary and then converts it back to a string according to
-the conversion specifier.
.SH "DIFFERENCES FROM ANSI SPRINTF"
.PP
The behavior of the format command is the same as the
ANSI C \fBsprintf\fR procedure except for the following
differences:
.IP [1]
-\fB%p\fR and \fB%n\fR specifiers are not currently supported.
+\fB%p\fR and \fB%n\fR specifiers are not supported.
.IP [2]
-For \fB%c\fR conversions the argument must be a decimal string,
+For \fB%c\fR conversions the argument must be an integer value,
which will then be converted to the corresponding character value.
.IP [3]
-The \fBl\fR modifier
-.VS 8.4
-is ignored for real values and on 64-bit platforms, which are always
-converted as if the \fBl\fR modifier were present (i.e. the types
-\fBdouble\fR and \fBlong\fR are used for the internal representation
-of real and integer values, respectively).
-.VE 8.4
-If the \fBh\fR modifier is specified then integer values are truncated
-to \fBshort\fR before conversion. Both \fBh\fR and \fBl\fR modifiers
-are ignored on all other conversions.
+The size modifiers are ignored when formatting floating-point values.
+The \fBll\fR modifier has no \fBsprintf\fR counterpart.
.SH EXAMPLES
+Convert the numeric value of a UNICODE character to the character
+itself:
+.CS
+set value 120
+set char [\fBformat\fR %c $value]
+.CE
+.PP
Convert the output of \fBtime\fR into seconds to an accuracy of
hundredths of a second:
.CS
@@ -235,7 +229,7 @@ reordering the data values passed to \fBformat\fR:
set fmt1 "Today, %d shares in %s were bought at $%.2f each"
puts [\fBformat\fR $fmt1 123 "Global BigCorp" 19.37]
-set fmt2 "Bought %2\\$s equity ($%3$.2f x %1\\$d) today"
+set fmt2 "Bought %2\e$s equity ($%3$.2f x %1\e$d) today"
puts [\fBformat\fR $fmt2 123 "Global BigCorp" 19.37]
.CE
.PP
@@ -261,9 +255,7 @@ for {set i 0} {$i<=20} {incr i} {
# Finish off by printing the separator again
puts $sep
.CE
-
.SH "SEE ALSO"
scan(n), sprintf(3), string(n)
-
.SH KEYWORDS
conversion specifier, format, sprintf, string, substitution
diff --git a/doc/gets.n b/doc/gets.n
index d61d072..bed7e32 100644
--- a/doc/gets.n
+++ b/doc/gets.n
@@ -21,13 +21,11 @@ This command reads the next line from \fIchannelId\fR, returns everything
in the line up to (but not including) the end-of-line character(s), and
discards the end-of-line character(s).
.PP
-.VS
\fIChannelId\fR must be an identifier for an open channel such as the
Tcl standard input channel (\fBstdin\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. The channel must have
been opened for input.
-.VE
.PP
If \fIvarName\fR is omitted the line is returned as the result of the
command.
diff --git a/doc/glob.n b/doc/glob.n
index 6f45d90..c257983 100644
--- a/doc/glob.n
+++ b/doc/glob.n
@@ -17,14 +17,17 @@ glob \- Return names of files that match patterns
.SH DESCRIPTION
.PP
-This command performs file name ``globbing'' in a fashion similar to
+This command performs file name
+.QW globbing
+in a fashion similar to
the csh shell. It returns a list of the files whose names match any
-of the \fIpattern\fR arguments.
+of the \fIpattern\fR arguments. No particular order is guaranteed
+in the list, so if a sorted list is required the caller should use
+\fBlsort\fR.
.LP
If the initial arguments to \fBglob\fR start with \fB\-\fR then
they are treated as switches. The following switches are
currently supported:
-.VS 8.3
.TP
\fB\-directory\fR \fIdirectory\fR
Search for files which match the given patterns starting in the given
@@ -35,14 +38,13 @@ characters explicitly. This option may not be used in conjunction with
whose names may contain glob-sensitive characters.
.TP
\fB\-join\fR
-The remaining pattern arguments are treated as a single pattern
-obtained by joining the arguments with directory separators.
-.VE 8.3
+The remaining pattern arguments, after option processing, are treated
+as a single pattern obtained by joining the arguments with directory
+separators.
.TP
\fB\-nocomplain\fR
Allows an empty list to be returned without error; without this
switch an error is returned if the result list would be empty.
-.VS 8.3
.TP
\fB\-path\fR \fIpathPrefix\fR
Search for files with the given \fIpathPrefix\fR where the rest of the name
@@ -100,10 +102,10 @@ The following are equivalent:
\fBglob */\fR
.CE
.RE
-except that the first case doesn't return the trailing ``/'' and
-is more platform independent.
+except that the first case doesn't return the trailing
+.QW /
+and is more platform independent.
.RE
-.VE 8.3
.TP
\fB\-\|\-\fR
Marks the end of switches. The argument following this one will
@@ -129,20 +131,35 @@ Matches the character \fIx\fR.
\fB{\fIa\fB,\fIb\fB,\fI...\fR}
Matches any of the strings \fIa\fR, \fIb\fR, etc.
.LP
-On Unix, as with csh, a ``.'' at the beginning of a file's name or just
-after a ``/'' must be matched explicitly or with a {} construct,
-unless the ``-types hidden'' flag is given (since ``.'' at the beginning
-of a file's name indicates that it is hidden). On other platforms,
-files beginning with a ``.'' are handled no differently to any others,
-except the special directories ``.'' and ``..'' which must be matched
-explicitly (this is to avoid a recursive pattern like ``glob -join * *
-* *'' from recursing up the directory hierarchy as well as down).
-In addition, all ``/'' characters must be matched explicitly.
+On Unix, as with csh, a
+.QW .
+at the beginning of a file's name or just after a
+.QW /
+must be matched explicitly or with a {} construct, unless the
+\fB\-types hidden\fR flag is given (since
+.QW .
+at the beginning of a file's name indicates that it is hidden). On
+other platforms, files beginning with a
+.QW .
+are handled no differently to any others, except the special directories
+.QW .
+and
+.QW ..
+which must be matched explicitly (this is to avoid a recursive pattern like
+.QW "glob -join * * * *"
+from recursing up the directory hierarchy as well as down). In addition, all
+.QW /
+characters must be matched explicitly.
.LP
-If the first character in a \fIpattern\fR is ``~'' then it refers
-to the home directory for the user whose name follows the ``~''.
-If the ``~'' is followed immediately by ``/'' then the value of
-the HOME environment variable is used.
+If the first character in a \fIpattern\fR is
+.QW ~
+then it refers to the home directory for the user whose name follows the
+.QW ~ .
+If the
+.QW ~
+is followed immediately by
+.QW /
+then the value of the HOME environment variable is used.
.LP
The \fBglob\fR command differs from csh globbing in two ways.
First, it does not sort its result list (use the \fBlsort\fR
@@ -152,29 +169,32 @@ exist; in csh no check for existence is made unless a pattern
contains a ?, *, or [] construct.
.LP
When the \fBglob\fR command returns relative paths whose filenames
-start with a tilde ``~'' (for example through \fBglob *\fR or
-\fBglob -tails\fR, the returned list will not quote the tilde with
-``./''. This means care must be taken if those names are later to
+start with a tilde
+.QW ~
+(for example through \fBglob *\fR or \fBglob -tails\fR, the returned
+list will not quote the tilde with
+.QW ./ .
+This means care must be taken if those names are later to
be used with \fBfile join\fR, to avoid them being interpreted as
absolute paths pointing to a given user's home directory.
.SH "PORTABILITY ISSUES"
.PP
-Unlike other Tcl commands that will accept both network and native
-style names (see the \fBfilename\fR manual entry for details on how
-native and network names are specified), the \fBglob\fR command only
-accepts native names.
-.TP
\fBWindows\fR
.
For Windows UNC names, the servername and sharename components of the path
may not contain ?, *, or [] constructs. On Windows NT, if \fIpattern\fR is
-of the form ``\fB~\fIusername\fB@\fIdomain\fR'' it refers to the home
+of the form
+.QW \fB~\fIusername\fB@\fIdomain\fR ,
+it refers to the home
directory of the user whose account information resides on the specified NT
domain server. Otherwise, user account information is obtained from
the local computer. On Windows 95 and 98, \fBglob\fR accepts patterns
-like ``.../'' and ``..../'' for successively higher up parent directories.
-
-.
+like
+.QW .../
+and
+.QW ..../
+for successively higher up parent directories.
+.PP
Since the backslash character has a special meaning to the glob
command, glob patterns containing Windows style path separators need
special care. The pattern \fIC:\e\efoo\e\e*\fR is interpreted as
@@ -184,13 +204,6 @@ interpreted as a wildcard character. One solution to this problem is
to use the Unix style forward slash as a path separator. Windows style
paths can be converted to Unix style paths with the command \fBfile
join $path\fR (or \fBfile normalize $path\fR in Tcl 8.4).
-.TP
-\fBMacintosh\fR
-.
-When using the options, \fB\-directory\fR, \fB\-join\fR or \fB\-path\fR, glob
-assumes the directory separator for the entire pattern is the standard
-``:''. When not using these options, glob examines each pattern argument
-and uses ``/'' unless the pattern contains a ``:''.
.SH EXAMPLES
Find all the Tcl files in the current directory:
.CS
@@ -208,7 +221,12 @@ Find all subdirectories of the current directory:
\fBglob\fR \-type d *
.CE
.PP
-Find all files whose name contains an "a", a "b" or the sequence "cde":
+Find all files whose name contains an
+.QW a ,
+a
+.QW b
+or the sequence
+.QW cde :
.CS
\fBglob\fR \-type f *{a,b,cde}*
.CE
diff --git a/doc/global.n b/doc/global.n
index b0e4389..c9d7a36 100644
--- a/doc/global.n
+++ b/doc/global.n
@@ -26,6 +26,10 @@ in the list returned by \fBinfo locals\fR).
If \fIvarname\fR contains namespace qualifiers, the local variable's name is
the unqualified name of the global variable, as determined by the
\fBnamespace tail\fR command.
+.PP
+\fIvarname\fR is always treated as the name of a variable, not an
+array element. An error is returned if the name looks like an array element,
+such as \fBa(b)\fR.
.SH EXAMPLES
This procedure sets the namespace variable \fI::a::x\fR
.CS
@@ -43,7 +47,7 @@ opened with \fBsocket\fR or as part of a counted HTTP response).
.CS
proc accum {string} {
\fBglobal\fR accumulator
- append accumulator $string \\n
+ append accumulator $string \en
}
.CE
diff --git a/doc/history.n b/doc/history.n
index 0ce7c4c..ba507b4 100644
--- a/doc/history.n
+++ b/doc/history.n
@@ -14,20 +14,20 @@ history \- Manipulate the history list
.SH SYNOPSIS
\fBhistory \fR?\fIoption\fR? ?\fIarg arg ...\fR?
.BE
-
.SH DESCRIPTION
.PP
The \fBhistory\fR command performs one of several operations related to
recently-executed commands recorded in a history list. Each of
-these recorded commands is referred to as an ``event''. When
-specifying an event to the \fBhistory\fR command, the following
+these recorded commands is referred to as an
+.QW event .
+When specifying an event to the \fBhistory\fR command, the following
forms may be used:
.IP [1]
A number: if positive, it refers to the event with
that number (all events are numbered starting at 1). If the number
is negative, it selects an event relative to the current event
(\fB\-1\fR refers to the previous event, \fB\-2\fR to the one before that, and
-so on). Event \fB0\fP refers to the current event.
+so on). Event \fB0\fR refers to the current event.
.IP [2]
A string: selects the most recent event that matches the string.
An event is considered to match the string either if the string is
@@ -43,7 +43,7 @@ as \fBhistory info\fR, described below.
\fBhistory add\fI command \fR?\fBexec\fR?
Adds the \fIcommand\fR argument to the history list as a new event. If
\fBexec\fR is specified (or abbreviated) then the command is also
-executed and its result is returned. If \fBexec\fR isn't specified
+executed and its result is returned. If \fBexec\fR is not specified
then an empty string is returned as result.
.TP
\fBhistory change\fI newValue\fR ?\fIevent\fR?
@@ -87,16 +87,16 @@ revision: see below for details.
.PP
Pre-8.0 Tcl had a complex history revision mechanism.
The current mechanism is more limited, and the old
-history operations \fBsubstitute\fP and \fBwords\fP have been removed.
-(As a consolation, the \fBclear\fP operation was added.)
+history operations \fBsubstitute\fR and \fBwords\fR have been removed.
+(As a consolation, the \fBclear\fR operation was added.)
.PP
-The history option \fBredo\fR results in much simpler ``history revision''.
+The history option \fBredo\fR results in much simpler
+.QW "history revision" .
When this option is invoked then the most recent event
is modified to eliminate the history command and replace it with
the result of the history command.
If you want to redo an event without modifying history, then use
-the \fBevent\fP operation to retrieve some event,
-and the \fBadd\fP operation to add it to history and execute it.
-
+the \fBevent\fR operation to retrieve some event,
+and the \fBadd\fR operation to add it to history and execute it.
.SH KEYWORDS
event, history, record
diff --git a/doc/http.n b/doc/http.n
index a563b5d..24b5f6a 100644
--- a/doc/http.n
+++ b/doc/http.n
@@ -7,21 +7,22 @@
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.so man.macros
-.TH "http" n 2.5 http "Tcl Bundled Packages"
+.TH "http" n 2.7 http "Tcl Bundled Packages"
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
-http \- Client-side implementation of the HTTP/1.0 protocol.
+http \- Client-side implementation of the HTTP/1.1 protocol
.SH SYNOPSIS
-\fBpackage require http ?2.5?\fR
+\fBpackage require http ?2.7?\fR
+.\" See Also -useragent option documentation in body!
.sp
\fB::http::config \fI?options?\fR
.sp
\fB::http::geturl \fIurl ?options?\fR
.sp
-\fB::http::formatQuery\fP \fIkey value\fP ?\fIkey value\fP ...?
+\fB::http::formatQuery\fR \fIkey value\fR ?\fIkey value\fR ...?
.sp
-\fB::http::reset\fP \fItoken\fP ?\fIwhy\fP?
+\fB::http::reset\fR \fItoken\fR ?\fIwhy\fR?
.sp
\fB::http::wait \fItoken\fR
.sp
@@ -45,12 +46,12 @@ http \- Client-side implementation of the HTTP/1.0 protocol.
.sp
\fB::http::unregister \fIproto\fR
.BE
-
.SH DESCRIPTION
.PP
-The \fBhttp\fR package provides the client side of the HTTP/1.0
-protocol. The package implements the GET, POST, and HEAD operations
-of HTTP/1.0. It allows configuration of a proxy host to get through
+The \fBhttp\fR package provides the client side of the HTTP/1.1
+protocol, as defined in RFC 2616.
+The package implements the GET, POST, and HEAD operations
+of HTTP/1.1. It allows configuration of a proxy host to get through
firewalls. The package is compatible with the \fBSafesock\fR security
policy, so it can be used by untrusted applets to do URL fetching from
a restricted set of hosts. This package can be extended to support
@@ -63,9 +64,9 @@ is performed.
The return value of \fB::http::geturl\fR is a token for the transaction.
The value is also the name of an array in the ::http namespace
that contains state information about the transaction. The elements
-of this array are described in the STATE ARRAY section.
+of this array are described in the \fBSTATE ARRAY\fR section.
.PP
-If the \fB-command\fP option is specified, then
+If the \fB\-command\fR option is specified, then
the HTTP operation is done in the background.
\fB::http::geturl\fR returns immediately after generating the
HTTP request and the callback is invoked
@@ -75,7 +76,7 @@ applications, the caller can use \fB::http::wait\fR after calling
\fB::http::geturl\fR to start the event loop.
.SH COMMANDS
.TP
-\fB::http::config\fP ?\fIoptions\fR?
+\fB::http::config\fR ?\fIoptions\fR?
The \fB::http::config\fR command is used to set and query the name of the
proxy server and port, and the User-Agent name used in the HTTP
requests. If no options are specified, then the current configuration
@@ -85,20 +86,21 @@ that setting is returned. Otherwise, the options should be a set of
flags and values that define the configuration:
.RS
.TP
-\fB\-accept\fP \fImimetypes\fP
+\fB\-accept\fR \fImimetypes\fR
The Accept header of the request. The default is */*, which means that
all types of documents are accepted. Otherwise you can supply a
comma-separated list of mime type patterns that you are
-willing to receive. For example, "image/gif, image/jpeg, text/*".
+willing to receive. For example,
+.QW "image/gif, image/jpeg, text/*" .
.TP
-\fB\-proxyhost\fP \fIhostname\fP
+\fB\-proxyhost\fR \fIhostname\fR
The name of the proxy host, if any. If this value is the
empty string, the URL host is contacted directly.
.TP
-\fB\-proxyport\fP \fInumber\fP
+\fB\-proxyport\fR \fInumber\fR
The proxy port number.
.TP
-\fB\-proxyfilter\fP \fIcommand\fP
+\fB\-proxyfilter\fR \fIcommand\fR
The command is a callback that is made during
\fB::http::geturl\fR
to determine if a proxy is required for a given host. One argument, a
@@ -109,7 +111,7 @@ an empty list. The default filter returns the values of the
\fB\-proxyhost\fR and \fB\-proxyport\fR settings if they are
non-empty.
.TP
-\fB\-urlencoding\fP \fIencoding\fP
+\fB\-urlencoding\fR \fIencoding\fR
The \fIencoding\fR used for creating the x-url-encoded URLs with
\fB::http::formatQuery\fR. The default is \fButf-8\fR, as specified by RFC
2718. Prior to http 2.5 this was unspecified, and that behavior can be
@@ -118,45 +120,46 @@ returned by specifying the empty string (\fB{}\fR), although
\fB::http::formatQuery\fR throwing an error processing non-latin-1
characters.
.TP
-\fB\-useragent\fP \fIstring\fP
-The value of the User-Agent header in the HTTP request. The default
-is \fB"Tcl http client package 2.4."\fR
+\fB\-useragent\fR \fIstring\fR
+The value of the User-Agent header in the HTTP request. The default is
+.QW "\fBTcl http client package 2.7\fR" .
.RE
.TP
-\fB::http::geturl\fP \fIurl\fP ?\fIoptions\fP?
+\fB::http::geturl\fR \fIurl\fR ?\fIoptions\fR?
The \fB::http::geturl\fR command is the main procedure in the package.
The \fB\-query\fR option causes a POST operation and
the \fB\-validate\fR option causes a HEAD operation;
otherwise, a GET operation is performed. The \fB::http::geturl\fR command
returns a \fItoken\fR value that can be used to get
-information about the transaction. See the STATE ARRAY and ERRORS section for
+information about the transaction. See the \fBSTATE ARRAY\fR and
+\fBERRORS\fR section for
details. The \fB::http::geturl\fR command blocks until the operation
completes, unless the \fB\-command\fR option specifies a callback
that is invoked when the HTTP transaction completes.
\fB::http::geturl\fR takes several options:
.RS
.TP
-\fB\-binary\fP \fIboolean\fP
+\fB\-binary\fR \fIboolean\fR
Specifies whether to force interpreting the URL data as binary. Normally
this is auto-detected (anything not beginning with a \fBtext\fR content
type or whose content encoding is \fBgzip\fR or \fBcompress\fR is
considered binary data).
.TP
-\fB\-blocksize\fP \fIsize\fP
+\fB\-blocksize\fR \fIsize\fR
The block size used when reading the URL.
At most \fIsize\fR bytes are read at once. After each block, a call to the
\fB\-progress\fR callback is made (if that option is specified).
.TP
-\fB\-channel\fP \fIname\fP
+\fB\-channel\fR \fIname\fR
Copy the URL contents to channel \fIname\fR instead of saving it in
\fBstate(body)\fR.
.TP
-\fB\-command\fP \fIcallback\fP
-Invoke \fIcallback\fP after the HTTP transaction completes.
-This option causes \fB::http::geturl\fP to return immediately.
-The \fIcallback\fP gets an additional argument that is the \fItoken\fR returned
+\fB\-command\fR \fIcallback\fR
+Invoke \fIcallback\fR after the HTTP transaction completes.
+This option causes \fB::http::geturl\fR to return immediately.
+The \fIcallback\fR gets an additional argument that is the \fItoken\fR returned
from \fB::http::geturl\fR. This token is the name of an array that is
-described in the STATE ARRAY section. Here is a template for the
+described in the \fBSTATE ARRAY\fR section. Here is a template for the
callback:
.RS
.CS
@@ -167,27 +170,30 @@ proc httpCallback {token} {
.CE
.RE
.TP
-\fB\-handler\fP \fIcallback\fP
-Invoke \fIcallback\fP whenever HTTP data is available; if present, nothing
+\fB\-handler\fR \fIcallback\fR
+Invoke \fIcallback\fR whenever HTTP data is available; if present, nothing
else will be done with the HTTP data. This procedure gets two additional
arguments: the socket for the HTTP data and the \fItoken\fR returned from
-\fB::http::geturl\fR. The token is the name of a global array that is described
-in the STATE ARRAY section. The procedure is expected to return the number
-of bytes read from the socket. Here is a template for the callback:
+\fB::http::geturl\fR. The token is the name of a global array that is
+described in the \fBSTATE ARRAY\fR section. The procedure is expected
+to return the number of bytes read from the socket. Here is a
+template for the callback:
.RS
.CS
proc httpHandlerCallback {socket token} {
upvar #0 $token state
# Access socket, and state as a Tcl array
+ # For example...
...
- (example: set data [read $socket 1000];set nbytes [string length $data])
+ set data [read $socket 1000]
+ set nbytes [string length $data]
...
- return nbytes
+ return $nbytes
}
.CE
.RE
.TP
-\fB\-headers\fP \fIkeyvaluelist\fP
+\fB\-headers\fR \fIkeyvaluelist\fR
This option is used to add extra headers to the HTTP request. The
\fIkeyvaluelist\fR argument must be a list with an even number of
elements that alternate between keys and values. The keys become
@@ -199,7 +205,20 @@ HTTP request:
Pragma: no-cache
.CE
.TP
-\fB\-progress\fP \fIcallback\fP
+\fB\-keepalive\fR \fIboolean\fR
+If true, attempt to keep the connection open for servicing
+multiple requests. Default is 0.
+.TP
+\fB\-method\fR \fItype\fR
+Force the HTTP request method to \fItype\fR. \fB::http::geturl\fR will
+auto-select GET, POST or HEAD based on other options, but this option
+enables choices like PUT and DELETE for webdav support.
+.TP
+\fB\-myaddr\fR \fIaddress\fR
+Pass an specific local address to the underlying \fBsocket\fR call in case
+multiple interfaces are available.
+.TP
+\fB\-progress\fR \fIcallback\fR
The \fIcallback\fR is made after each transfer of data from the URL.
The callback gets three additional arguments: the \fItoken\fR from
\fB::http::geturl\fR, the expected total size of the contents from the
@@ -215,13 +234,18 @@ proc httpProgress {token total current} {
.CE
.RE
.TP
-\fB\-query\fP \fIquery\fP
+\fB\-protocol\fR \fIversion\fR
+Select the HTTP protocol version to use. This should be 1.0 or 1.1 (the
+default). Should only be necessary for servers that do not understand or
+otherwise complain about HTTP/1.1.
+.TP
+\fB\-query\fR \fIquery\fR
This flag causes \fB::http::geturl\fR to do a POST request that passes the
\fIquery\fR to the server. The \fIquery\fR must be an x-url-encoding
formatted query. The \fB::http::formatQuery\fR procedure can be used to
do the formatting.
.TP
-\fB\-queryblocksize\fP \fIsize\fP
+\fB\-queryblocksize\fR \fIsize\fR
The block size used when posting query data to the URL.
At most
\fIsize\fR
@@ -229,103 +253,106 @@ bytes are written at once. After each block, a call to the
\fB\-queryprogress\fR
callback is made (if that option is specified).
.TP
-\fB\-querychannel\fP \fIchannelID\fP
+\fB\-querychannel\fR \fIchannelID\fR
This flag causes \fB::http::geturl\fR to do a POST request that passes the
data contained in \fIchannelID\fR to the server. The data contained in
\fIchannelID\fR must be an x-url-encoding
-formatted query unless the \fB\-type\fP option below is used.
+formatted query unless the \fB\-type\fR option below is used.
If a Content-Length header is not specified via the \fB\-headers\fR options,
\fB::http::geturl\fR attempts to determine the size of the post data
in order to create that header. If it is
unable to determine the size, it returns an error.
.TP
-\fB\-queryprogress\fP \fIcallback\fP
+\fB\-queryprogress\fR \fIcallback\fR
The \fIcallback\fR is made after each transfer of data to the URL
(i.e. POST) and acts exactly like the \fB\-progress\fR option (the
callback format is the same).
.TP
-\fB\-timeout\fP \fImilliseconds\fP
+\fB\-strict\fR \fIboolean\fR
+Whether to enforce RFC 3986 URL validation on the request. Default is 1.
+.TP
+\fB\-timeout\fR \fImilliseconds\fR
If \fImilliseconds\fR is non-zero, then \fB::http::geturl\fR sets up a timeout
to occur after the specified number of milliseconds.
-A timeout results in a call to \fB::http::reset\fP and to
-the \fB-command\fP callback, if specified.
-The return value of \fB::http::status\fP is \fBtimeout\fP
+A timeout results in a call to \fB::http::reset\fR and to
+the \fB\-command\fR callback, if specified.
+The return value of \fB::http::status\fR is \fBtimeout\fR
after a timeout has occurred.
.TP
-\fB\-type\fP \fImime-type\fP
+\fB\-type\fR \fImime-type\fR
Use \fImime-type\fR as the \fBContent-Type\fR value, instead of the
default value (\fBapplication/x-www-form-urlencoded\fR) during a
POST operation.
.TP
-\fB\-validate\fP \fIboolean\fP
+\fB\-validate\fR \fIboolean\fR
If \fIboolean\fR is non-zero, then \fB::http::geturl\fR does an HTTP HEAD
request. This request returns meta information about the URL, but the
contents are not returned. The meta information is available in the
-\fBstate(meta) \fR variable after the transaction. See the STATE
-ARRAY section for details.
+\fBstate(meta) \fR variable after the transaction. See the
+\fBSTATE ARRAY\fR section for details.
.RE
.TP
-\fB::http::formatQuery\fP \fIkey value\fP ?\fIkey value\fP ...?
+\fB::http::formatQuery\fR \fIkey value\fR ?\fIkey value\fR ...?
This procedure does x-url-encoding of query data. It takes an even
number of arguments that are the keys and values of the query. It
encodes the keys and values, and generates one string that has the
proper & and = separators. The result is suitable for the
\fB\-query\fR value passed to \fB::http::geturl\fR.
.TP
-\fB::http::reset\fP \fItoken\fP ?\fIwhy\fP?
+\fB::http::reset\fR \fItoken\fR ?\fIwhy\fR?
This command resets the HTTP transaction identified by \fItoken\fR, if
-any. This sets the \fBstate(status)\fP value to \fIwhy\fP, which defaults to \fBreset\fR, and then calls the registered \fB\-command\fR callback.
+any. This sets the \fBstate(status)\fR value to \fIwhy\fR, which defaults to \fBreset\fR, and then calls the registered \fB\-command\fR callback.
.TP
-\fB::http::wait\fP \fItoken\fP
+\fB::http::wait\fR \fItoken\fR
This is a convenience procedure that blocks and waits for the
transaction to complete. This only works in trusted code because it
-uses \fBvwait\fR. Also, it's not useful for the case where
-\fB::http::geturl\fP is called \fIwithout\fP the \fB-command\fP option
-because in this case the \fB::http::geturl\fP call doesn't return
-until the HTTP transaction is complete, and thus there's nothing to
+uses \fBvwait\fR. Also, it is not useful for the case where
+\fB::http::geturl\fR is called \fIwithout\fR the \fB\-command\fR option
+because in this case the \fB::http::geturl\fR call does not return
+until the HTTP transaction is complete, and thus there is nothing to
wait for.
.TP
-\fB::http::data\fP \fItoken\fP
-This is a convenience procedure that returns the \fBbody\fP element
+\fB::http::data\fR \fItoken\fR
+This is a convenience procedure that returns the \fBbody\fR element
(i.e., the URL data) of the state array.
.TP
-\fB::http::error\fP \fItoken\fP
-This is a convenience procedure that returns the \fBerror\fP element
+\fB::http::error\fR \fItoken\fR
+This is a convenience procedure that returns the \fBerror\fR element
of the state array.
.TP
-\fB::http::status\fP \fItoken\fP
-This is a convenience procedure that returns the \fBstatus\fP element of
+\fB::http::status\fR \fItoken\fR
+This is a convenience procedure that returns the \fBstatus\fR element of
the state array.
.TP
-\fB::http::code\fP \fItoken\fP
-This is a convenience procedure that returns the \fBhttp\fP element of the
+\fB::http::code\fR \fItoken\fR
+This is a convenience procedure that returns the \fBhttp\fR element of the
state array.
.TP
-\fB::http::ncode\fP \fItoken\fP
+\fB::http::ncode\fR \fItoken\fR
This is a convenience procedure that returns just the numeric return
-code (200, 404, etc.) from the \fBhttp\fP element of the state array.
+code (200, 404, etc.) from the \fBhttp\fR element of the state array.
.TP
-\fB::http::size\fP \fItoken\fP
-This is a convenience procedure that returns the \fBcurrentsize\fP
+\fB::http::size\fR \fItoken\fR
+This is a convenience procedure that returns the \fBcurrentsize\fR
element of the state array, which represents the number of bytes
-received from the URL in the \fB::http::geturl\fP call.
+received from the URL in the \fB::http::geturl\fR call.
.TP
-\fB::http::meta\fP \fItoken\fP
-This is a convenience procedure that returns the \fBmeta\fP
+\fB::http::meta\fR \fItoken\fR
+This is a convenience procedure that returns the \fBmeta\fR
element of the state array which contains the HTTP response
headers. See below for an explanation of this element.
.TP
-\fB::http::cleanup\fP \fItoken\fP
+\fB::http::cleanup\fR \fItoken\fR
This procedure cleans up the state associated with the connection
-identified by \fItoken\fP. After this call, the procedures
-like \fB::http::data\fP cannot be used to get information
-about the operation. It is \fIstrongly\fP recommended that you call
-this function after you're done with a given HTTP request. Not doing
+identified by \fItoken\fR. After this call, the procedures
+like \fB::http::data\fR cannot be used to get information
+about the operation. It is \fIstrongly\fR recommended that you call
+this function after you are done with a given HTTP request. Not doing
so will result in memory not being freed, and if your app calls
-\fB::http::geturl\fP enough times, the memory leak could cause a
+\fB::http::geturl\fR enough times, the memory leak could cause a
performance hit...or worse.
.TP
-\fB::http::register\fP \fIproto port command\fP
+\fB::http::register\fR \fIproto port command\fR
This procedure allows one to provide custom HTTP transport types
such as HTTPS, by registering a prefix, the default port, and the
command to execute to create the Tcl \fBchannel\fR. E.g.:
@@ -340,12 +367,11 @@ set token [::http::geturl https://my.secure.site/]
.CE
.RE
.TP
-\fB::http::unregister\fP \fIproto\fP
+\fB::http::unregister\fR \fIproto\fR
This procedure unregisters a protocol handler that was previously
registered via \fB::http::register\fR.
-
-.SH "ERRORS"
-The \fB::http::geturl\fP procedure will raise errors in the following cases:
+.SH ERRORS
+The \fB::http::geturl\fR procedure will raise errors in the following cases:
invalid command line options,
an invalid URL,
a URL on a non-existent host,
@@ -354,60 +380,59 @@ These errors mean that it
cannot even start the network transaction.
It will also raise an error if it gets an I/O error while
writing out the HTTP request header.
-For synchronous \fB::http::geturl\fP calls (where \fB-command\fP is
+For synchronous \fB::http::geturl\fR calls (where \fB\-command\fR is
not specified), it will raise an error if it gets an I/O error while
-reading the HTTP reply headers or data. Because \fB::http::geturl\fP
-doesn't return a token in these cases, it does all the required
-cleanup and there's no issue of your app having to call
-\fB::http::cleanup\fP.
+reading the HTTP reply headers or data. Because \fB::http::geturl\fR
+does not return a token in these cases, it does all the required
+cleanup and there is no issue of your app having to call
+\fB::http::cleanup\fR.
.PP
-For asynchronous \fB::http::geturl\fP calls, all of the above error
-situations apply, except that if there's any error while
-reading the
+For asynchronous \fB::http::geturl\fR calls, all of the above error
+situations apply, except that if there is any error while reading the
HTTP reply headers or data, no exception is thrown. This is because
-after writing the HTTP headers, \fB::http::geturl\fP returns, and the
+after writing the HTTP headers, \fB::http::geturl\fR returns, and the
rest of the HTTP transaction occurs in the background. The command
callback can check if any error occurred during the read by calling
-\fB::http::status\fP to check the status and if its \fIerror\fP,
-calling \fB::http::error\fP to get the error message.
+\fB::http::status\fR to check the status and if its \fIerror\fR,
+calling \fB::http::error\fR to get the error message.
.PP
Alternatively, if the main program flow reaches a point where it needs
to know the result of the asynchronous HTTP request, it can call
-\fB::http::wait\fP and then check status and error, just as the
+\fB::http::wait\fR and then check status and error, just as the
callback does.
.PP
In any case, you must still call
-\fB::http::cleanup\fP to delete the state array when you're done.
+\fB::http::cleanup\fR to delete the state array when you are done.
.PP
There are other possible results of the HTTP transaction
-determined by examining the status from \fB::http::status\fP.
+determined by examining the status from \fB::http::status\fR.
These are described below.
.TP
ok
-If the HTTP transaction completes entirely, then status will be \fBok\fP.
-However, you should still check the \fB::http::code\fP value to get
-the HTTP status. The \fB::http::ncode\fP procedure provides just
-the numeric error (e.g., 200, 404 or 500) while the \fB::http::code\fP
-procedure returns a value like "HTTP 404 File not found".
+If the HTTP transaction completes entirely, then status will be \fBok\fR.
+However, you should still check the \fB::http::code\fR value to get
+the HTTP status. The \fB::http::ncode\fR procedure provides just
+the numeric error (e.g., 200, 404 or 500) while the \fB::http::code\fR
+procedure returns a value like
+.QW "HTTP 404 File not found" .
.TP
eof
If the server closes the socket without replying, then no error
-is raised, but the status of the transaction will be \fBeof\fP.
+is raised, but the status of the transaction will be \fBeof\fR.
.TP
error
-The error message will also be stored in the \fBerror\fP status
-array element, accessible via \fB::http::error\fP.
+The error message will also be stored in the \fBerror\fR status
+array element, accessible via \fB::http::error\fR.
.PP
-Another error possibility is that \fB::http::geturl\fP is unable to
+Another error possibility is that \fB::http::geturl\fR is unable to
write all the post query data to the server before the server
responds and closes the socket.
-The error message is saved in the \fBposterror\fP status array
-element and then \fB::http::geturl\fP attempts to complete the
+The error message is saved in the \fBposterror\fR status array
+element and then \fB::http::geturl\fR attempts to complete the
transaction.
If it can read the server's response
-it will end up with an \fBok\fP status, otherwise it will have
-an \fBeof\fP status.
-
+it will end up with an \fBok\fR status, otherwise it will have
+an \fBeof\fR status.
.SH "STATE ARRAY"
The \fB::http::geturl\fR procedure returns a \fItoken\fR that can be used to
get to the state of the HTTP transaction in the form of a Tcl array.
@@ -417,14 +442,14 @@ upvar #0 $token state
.CE
Once the data associated with the URL is no longer needed, the state
array should be unset to free up storage.
-The \fB::http::cleanup\fP procedure is provided for that purpose.
+The \fB::http::cleanup\fR procedure is provided for that purpose.
The following elements of
the array are supported:
.RS
.TP
\fBbody\fR
The contents of the URL. This will be empty if the \fB\-channel\fR
-option has been specified. This value is returned by the \fB::http::data\fP command.
+option has been specified. This value is returned by the \fB::http::data\fR command.
.TP
\fBcharset\fR
The value of the charset attribute from the \fBContent-Type\fR meta-data
@@ -437,7 +462,7 @@ A copy of the \fBContent-Encoding\fR meta-data value.
.TP
\fBcurrentsize\fR
The current number of bytes fetched from the URL.
-This value is returned by the \fB::http::size\fP command.
+This value is returned by the \fB::http::size\fR command.
.TP
\fBerror\fR
If defined, this is the error string seen when the HTTP transaction
@@ -445,10 +470,10 @@ was aborted.
.TP
\fBhttp\fR
The HTTP status reply from the server. This value
-is returned by the \fB::http::code\fP command. The format of this value is:
+is returned by the \fB::http::code\fR command. The format of this value is:
.RS
.CS
-\fIHTTP/1.0 code string\fP
+\fIHTTP/1.1 code string\fR
.CE
The \fIcode\fR is a three-digit number defined in the HTTP standard.
A code of 200 is OK. Codes beginning with 4 or 5 indicate errors.
@@ -488,7 +513,7 @@ the post query data to the server.
.TP
\fBstatus\fR
Either \fBok\fR, for successful completion, \fBreset\fR for
-user-reset, \fBtimeout\fP if a timeout occurred before the transaction
+user-reset, \fBtimeout\fR if a timeout occurred before the transaction
could complete, or \fBerror\fR for an error condition. During the
transaction this value is the empty string.
.TP
@@ -506,7 +531,7 @@ The requested URL.
# Copy a URL to a file and print meta-data
proc httpcopy { url file {chunk 4096} } {
set out [open $file w]
- set token [\fB::http::geturl\fR $url -channel $out \\
+ set token [\fB::http::geturl\fR $url -channel $out \e
-progress httpCopyProgress -blocksize $chunk]
close $out
@@ -537,9 +562,7 @@ proc httpCopyProgress {args} {
flush stderr
}
.CE
-
.SH "SEE ALSO"
safe(n), socket(n), safesock(n)
-
.SH KEYWORDS
security policy, socket
diff --git a/doc/if.n b/doc/if.n
index b9e9219..d84cf08 100644
--- a/doc/if.n
+++ b/doc/if.n
@@ -30,7 +30,8 @@ then \fBbody2\fR is executed, and so on.
If none of the expressions evaluates to true then \fIbodyN\fR is
executed.
The \fBthen\fR and \fBelse\fR arguments are optional
-``noise words'' to make the command easier to read.
+.QW "noise words"
+to make the command easier to read.
There may be any number of \fBelseif\fR clauses, including zero.
\fIBodyN\fR may also be omitted as long as \fBelse\fR is omitted too.
The return value from the command is the result of the body script
diff --git a/doc/incr.n b/doc/incr.n
index c98d795..72b3ff8 100644
--- a/doc/incr.n
+++ b/doc/incr.n
@@ -24,6 +24,12 @@ integer) is added to the value of variable \fIvarName\fR; otherwise
1 is added to \fIvarName\fR.
The new value is stored as a decimal string in variable \fIvarName\fR
and also returned as result.
+.PP
+.VS 8.5
+Starting with the Tcl 8.5 release, the variable \fIvarName\fR passed
+to \fBincr\fR may be unset, and in that case, it will be set to
+the value \fIincrement\fR or to the default increment value of \fB1\fR.
+.VE 8.5
.SH EXAMPLES
Add one to the contents of the variable \fIx\fR:
.CS
@@ -42,7 +48,7 @@ variable \fIx\fR:
.CE
.PP
Add nothing at all to the variable \fIx\fR (often useful for checking
-whether an argument to a procedure is actually numeric and generating
+whether an argument to a procedure is actually integral and generating
an error if it is not):
.CS
\fBincr\fR x 0
diff --git a/doc/info.n b/doc/info.n
index 1b11397..fae0d43 100644
--- a/doc/info.n
+++ b/doc/info.n
@@ -21,7 +21,7 @@ info \- Return information about the state of the Tcl interpreter
.PP
This command provides information about various internals of the Tcl
interpreter.
-The legal \fIoption\fR's (which may be abbreviated) are:
+The legal \fIoption\fRs (which may be abbreviated) are:
.TP
\fBinfo args \fIprocname\fR
Returns a list containing the names of the arguments to procedure
@@ -37,8 +37,11 @@ Returns a count of the total number of commands that have been invoked
in this interpreter.
.TP
\fBinfo commands \fR?\fIpattern\fR?
-If \fIpattern\fR isn't specified,
-returns a list of names of all the Tcl commands in the current namespace,
+If \fIpattern\fR is not specified,
+.\" Do not move this .VS above the .TP
+.VS 8.5
+returns a list of names of all the Tcl commands visible
+(i.e. executable without using a qualified name) to the current namespace,
including both the built-in commands written in C and
the command procedures defined using the \fBproc\fR command.
If \fIpattern\fR is specified,
@@ -51,21 +54,25 @@ and may have pattern matching special characters
at the end to specify a set of commands in that namespace.
If \fIpattern\fR is a qualified name,
the resulting list of command names has each one qualified with the name
-of the specified namespace.
+of the specified namespace, and only the commands defined in the named
+namespace are returned.
+.\" Technically, most of this hasn't changed; that's mostly just the
+.\" way it always worked. Hardly anyone knew that though.
+.VE 8.5
.TP
\fBinfo complete \fIcommand\fR
Returns 1 if \fIcommand\fR is a complete Tcl command in the sense of
having no unclosed quotes, braces, brackets or array element names.
-If the command doesn't appear to be complete then 0 is returned.
+If the command does not appear to be complete then 0 is returned.
This command is typically used in line-oriented input environments
to allow users to type in commands that span multiple lines; if the
-command isn't complete, the script can delay evaluating it until additional
+command is not complete, the script can delay evaluating it until additional
lines have been typed to complete the command.
.TP
\fBinfo default \fIprocname arg varname\fR
\fIProcname\fR must be the name of a Tcl command procedure and \fIarg\fR
must be the name of an argument to that procedure. If \fIarg\fR
-doesn't have a default value then the command returns \fB0\fR.
+does not have a default value then the command returns \fB0\fR.
Otherwise it returns \fB1\fR and places the default value of \fIarg\fR
into variable \fIvarname\fR.
.TP
@@ -73,18 +80,125 @@ into variable \fIvarname\fR.
Returns \fB1\fR if the variable named \fIvarName\fR exists in the
current context (either as a global or local variable) and has been
defined by being given a value, returns \fB0\fR otherwise.
-.VS 8.4
+.TP
+\fBinfo frame\fR ?\fInumber\fR?
+This command provides access to all frames on the stack, even those
+hidden from \fBinfo level\fR. If \fInumber\fR is not specified, this
+command returns a number giving the frame level of the command. This
+is 1 if the command is invoked at top-level. If \fInumber\fR is
+specified, then the result is a dictionary containing the location
+information for the command at the \fInumber\fRed level on the stack.
+.RS
+.PP
+If \fInumber\fR is positive (> 0) then it selects a particular stack
+level (1 refers to the top-most active command, i.e., \fBinfo frame\fR
+itself, 2 to the command it was called from, and so on); otherwise it
+gives a level relative to the current command (0 refers to the current
+command, i.e., \fBinfo frame\fR itself, -1 to its caller, and so on).
+.PP
+This is similar to how \fBinfo level\fR works, except that this
+subcommand reports all frames, like \fBsource\fRd scripts,
+\fBeval\fRs, \fBuplevel\fRs, etc.
+.PP
+Note that for nested commands, like
+.QW "foo [bar [x]]" ,
+only
+.QW x
+will be seen by an \fBinfo frame\fR invoked within
+.QW x .
+This is the same as for \fBinfo level\fR and error stack traces.
+.PP
+The result dictionary may contain the keys listed below, with the
+specified meanings for their values:
+.TP
+\fBtype\fR
+This entry is always present and describes the nature of the location
+for the command. The recognized values are \fBsource\fR, \fBproc\fR,
+\fBeval\fR, and \fBprecompiled\fR.
+.RS
+.TP
+\fBsource\fR\0\0\0\0\0\0\0\0
+means that the command is found in a script loaded by the \fBsource\fR
+command.
+.TP
+\fBproc\fR\0\0\0\0\0\0\0\0
+means that the command is found in dynamically created procedure body.
+.TP
+\fBeval\fR\0\0\0\0\0\0\0\0
+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
+the package \fBtbcload\fR), and no further information will be
+available.
+.RE
+.TP
+\fBline\fR
+This entry provides the number of the line the command is at inside of
+the script it is a part of. This information is not present for type
+\fBprecompiled\fR. For type \fBsource\fR this information is counted
+relative to the beginning of the file, whereas for the last two types
+the line is counted relative to the start of the script.
+.TP
+\fBfile\fR
+This entry is present only for type \fBsource\fR. It provides the
+normalized path of the file the command is in.
+.TP
+\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
+the latter is not spoiled.
+.TP
+\fBproc\fR
+This entry is present only if the command is found in the body of a
+regular Tcl procedure. It then provides the name of that procedure.
+.TP
+\fBlambda\fR
+This entry is present only if the command is found in the body of an
+anonymous Tcl procedure, i.e. a lambda. It then provides the entire
+definition of the lambda in question.
+.TP
+\fBlevel\fR
+This entry is present only if the queried frame has a corresponding
+frame returned by \fBinfo level\fR. It provides the index of this
+frame, relative to the current level (0 and negative numbers).
+.PP
+A thing of note is that for procedures statically defined in files the
+locations of commands in their bodies will be reported with type
+\fBsource\fR and absolute line numbers, and not as type
+\fBproc\fR. The same is true for procedures nested in statically
+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
+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.
+.PP
+A different way of describing this behaviour is that file based
+locations are tracked as deeply as possible, and where this is not
+possible the lines are counted based on the smallest possible
+\fBeval\fR or procedure body, as that scope is usually easier to find
+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
+counted relative to the start of each word (smallest scope)
+.RE
.TP
\fBinfo functions \fR?\fIpattern\fR?
-If \fIpattern\fR isn't specified, returns a list of all the math
+If \fIpattern\fR is not specified, returns a list of all the math
functions currently defined.
If \fIpattern\fR is specified, only those functions whose name matches
\fIpattern\fR are returned. Matching is determined using the same
rules as for \fBstring match\fR.
-.VE
.TP
\fBinfo globals \fR?\fIpattern\fR?
-If \fIpattern\fR isn't specified, returns a list of all the names
+If \fIpattern\fR is not specified, returns a list of all the names
of currently-defined global variables.
Global variables are variables in the global namespace.
If \fIpattern\fR is specified, only those names matching \fIpattern\fR
@@ -94,13 +208,11 @@ are returned. Matching is determined using the same rules as for
\fBinfo hostname\fR
Returns the name of the computer on which this invocation is being
executed.
-.VS
Note that this name is not guaranteed to be the fully qualified domain
name of the host. Where machines have several different names (as is
common on systems with both TCP/IP (DNS) and NetBIOS-based networking
installed,) it is the name that is suitable for TCP/IP networking that
is returned.
-.VE
.TP
\fBinfo level\fR ?\fInumber\fR?
If \fInumber\fR is not specified, this command returns a number
@@ -135,7 +247,7 @@ To get a list of just the packages in the current interpreter, specify
an empty string for the \fIinterp\fR argument.
.TP
\fBinfo locals \fR?\fIpattern\fR?
-If \fIpattern\fR isn't specified, returns a list of all the names
+If \fIpattern\fR is not specified, returns a list of all the names
of currently-defined local variables, including arguments to the
current procedure, if any.
Variables defined with the \fBglobal\fR, \fBupvar\fR and
@@ -154,7 +266,7 @@ Returns the value of the global variable \fBtcl_patchLevel\fR; see
the \fBtclvars\fR manual entry for more information.
.TP
\fBinfo procs \fR?\fIpattern\fR?
-If \fIpattern\fR isn't specified, returns a list of all the
+If \fIpattern\fR is not specified, returns a list of all the
names of Tcl command procedures in the current namespace.
If \fIpattern\fR is specified,
only those procedure names in the current namespace
@@ -180,7 +292,7 @@ Otherwise the command returns an empty string.
\fBinfo sharedlibextension\fR
Returns the extension used on this platform for the names of files
containing shared libraries (for example, \fB.so\fR under Solaris).
-If shared libraries aren't supported on this platform then an empty
+If shared libraries are not supported on this platform then an empty
string is returned.
.TP
\fBinfo tclversion\fR
@@ -188,7 +300,7 @@ Returns the value of the global variable \fBtcl_version\fR; see
the \fBtclvars\fR manual entry for more information.
.TP
\fBinfo vars\fR ?\fIpattern\fR?
-If \fIpattern\fR isn't specified,
+If \fIpattern\fR is not specified,
returns a list of all the names of currently-visible variables.
This includes locals and currently-visible globals.
If \fIpattern\fR is specified, only those names matching \fIpattern\fR
@@ -203,11 +315,14 @@ If \fIpattern\fR is a qualified name,
the resulting list of variable names
has each matching namespace variable qualified with the name
of its namespace.
-Note that a currently-visible variable may not yet "exist" if it has not
+Note that a currently-visible variable may not yet
+.QW exist
+if it has not
been set (e.g. a variable declared but not set by \fBvariable\fR).
.SH EXAMPLE
This command prints out a procedure suitable for saving in a Tcl
script:
+.PP
.CS
proc printProc {procName} {
set result [list proc $procName]
@@ -224,13 +339,10 @@ proc printProc {procName} {
puts [lappend result $formals [\fBinfo body\fR $procName]]
}
.CE
-
.SH "SEE ALSO"
global(n), proc(n)
-
.SH KEYWORDS
command, information, interpreter, level, namespace, procedure, variable
-
-'\" Local Variables:
-'\" mode: nroff
-'\" End:
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/doc/interp.n b/doc/interp.n
index bbe7826..c753ee9 100644
--- a/doc/interp.n
+++ b/doc/interp.n
@@ -1,5 +1,6 @@
'\"
'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2004 Donal K. Fellows
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -11,15 +12,14 @@
.SH NAME
interp \- Create and manipulate Tcl interpreters
.SH SYNOPSIS
-\fBinterp \fIoption \fR?\fIarg arg ...\fR?
+\fBinterp \fIsubcommand \fR?\fIarg arg ...\fR?
.BE
-
.SH DESCRIPTION
.PP
-This command makes it possible to create one or more new Tcl
+This command makes it possible to create one or more new Tcl
interpreters that co-exist with the creating interpreter in the
same application. The creating interpreter is called the \fImaster\fR
-and the new interpreter is called a \fIslave\fR.
+and the new interpreter is called a \fIslave\fR.
A master can create any number of slaves, and each slave can
itself create additional slaves for which it is master, resulting
in a hierarchy of interpreters.
@@ -32,7 +32,11 @@ a command in a slave interpreter which, when invoked, causes a
command to be invoked in its master interpreter or in another slave
interpreter. The only other connections between interpreters are
through environment variables (the \fBenv\fR variable), which are
-normally shared among all interpreters in the application. Note that the
+normally shared among all interpreters in the application,
+.VS 8.5
+and by resource limit exceeded callbacks.
+.VE 8.5
+Note that the
name space for files (such as the names returned by the \fBopen\fR command)
is no longer shared between interpreters. Explicit commands are provided to
share files and to transfer references to open files from one interpreter
@@ -45,7 +49,6 @@ scripts without fear of them damaging other interpreters or the
application's environment. For example, all IO channel creation
commands and subprocess creation commands are made inaccessible to safe
interpreters.
-.VS
See \fBSAFE INTERPRETERS\fR below for more information on
what features are present in a safe interpreter.
The dangerous functionality is not removed from the safe interpreter;
@@ -53,10 +56,9 @@ instead, it is \fIhidden\fR, so that only trusted interpreters can obtain
access to it. For a detailed explanation of hidden commands, see
\fBHIDDEN COMMANDS\fR, below.
The alias mechanism can be used for protected communication (analogous to a
-kernel call) between a slave interpreter and its master.
-See \fBALIAS INVOCATION\fR, below, for more details
+kernel call) between a slave interpreter and its master.
+See \fBALIAS INVOCATION\fR, below, for more details
on how the alias mechanism works.
-.VE
.PP
A qualified interpreter name is a proper Tcl lists containing a subset of its
ancestors in the interpreter hierarchy, terminated by the string naming the
@@ -78,7 +80,7 @@ Both restrictions are motivated by safety concerns.
The \fBinterp\fR command is used to create, delete, and manipulate
slave interpreters, and to share or transfer
channels between interpreters. It can have any of several forms, depending
-on the \fIoption\fR argument:
+on the \fIsubcommand\fR argument:
.TP
\fBinterp\fR \fBalias\fR \fIsrcPath\fR \fIsrcToken\fR
Returns a Tcl list whose elements are the \fItargetCmd\fR and
@@ -102,7 +104,9 @@ may be anywhere in the hierarchy of interpreters under the interpreter
invoking the command.
\fISrcPath\fR and \fIsrcCmd\fR identify the source of the alias.
\fISrcPath\fR is a Tcl list whose elements select a particular
-interpreter. For example, ``\fBa b\fR'' identifies an interpreter
+interpreter. For example,
+.QW "\fBa b\fR"
+identifies an interpreter
\fBb\fR, which is a slave of interpreter \fBa\fR, which is a slave
of the invoking interpreter. An empty list specifies the interpreter
invoking the command. \fIsrcCmd\fR gives the name of a new
@@ -116,7 +120,7 @@ already exist; it is not created by this command.
The alias arranges for the given target command to be invoked
in the target interpreter whenever the given source command is
invoked in the source interpreter. See \fBALIAS INVOCATION\fR below for
-more details.
+more details.
The command returns a token that uniquely identifies the command created
\fIsrcCmd\fR, even if the command is renamed afterwards. The token may but
does not have to be equal to \fIsrcCmd\fR.
@@ -124,16 +128,26 @@ does not have to be equal to \fIsrcCmd\fR.
\fBinterp\fR \fBaliases \fR?\fIpath\fR?
This command returns a Tcl list of the tokens of all the source commands for
aliases defined in the interpreter identified by \fIpath\fR. The tokens
-correspond to the values returned when
-the aliases were created (which may not be the same
+correspond to the values returned when
+the aliases were created (which may not be the same
as the current names of the commands).
.TP
+\fBinterp bgerror \fIpath\fR ?\fIcmdPrefix\fR?
+.VS 8.5
+This command either gets or sets the current background error handler
+for the interpreter identified by \fIpath\fR. If \fIcmdPrefix\fR is
+absent, the current background error handler is returned, and if it is
+present, it is a list of words (of minimum length one) that describes
+what to set the interpreter's background error to. See the
+\fBBACKGROUND ERROR HANDLING\fR section for more details.
+.VE 8.5
+.TP
\fBinterp\fR \fBcreate \fR?\fB\-safe\fR? ?\fB\-\|\-\fR? ?\fIpath\fR?
Creates a slave interpreter identified by \fIpath\fR and a new command,
called a \fIslave command\fR. The name of the slave command is the last
component of \fIpath\fR. The new slave interpreter and the slave command
are created in the interpreter identified by the path obtained by removing
-the last component from \fIpath\fR. For example, if \fIpath is \fBa b
+the last component from \fIpath\fR. For example, if \fIpath\fR is \fBa b
c\fR then a new slave interpreter and slave command named \fBc\fR are
created in the interpreter identified by the path \fBa b\fR.
The slave command may be used to manipulate the new interpreter as
@@ -152,6 +166,44 @@ given name already exists in this master.
The initial recursion limit of the slave interpreter is set to the
current recursion limit of its parent interpreter.
.TP
+\fBinterp\fR \fBdebug \fIpath\fR ?\fI\-frame\fR ?\fIbool\fR??
+.
+Controls whether frame-level stack information is captured in the
+slave interpreter identified by \fIpath\fR. If no arguments are
+given, option and current setting are returned. If \fI\-frame\fR
+is given, the debug setting is set to the given boolean if provided
+and the current setting is returned.
+This only effects the output of \fBinfo frame\fR, in that exact
+frame-level information for command invocation at the bytecode level
+is only captured with this setting on.
+.PP
+.RS
+For example, with code like
+.PP
+.CS
+\fBproc\fR mycontrol {... script} {
+ ...
+ \fBuplevel\fR 1 $script
+ ...
+}
+
+\fBproc\fR dosomething {...} {
+ ...
+ mycontrol {
+ somecode
+ }
+}
+.CE
+.PP
+the standard setting will provide a relative line number for the
+command \fBsomecode\fR and the relevant frame will be of type
+\fBeval\fR. With frame-debug active on the other hand the tracking
+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.
+.RE
+.TP
\fBinterp\fR \fBdelete \fR?\fIpath ...?\fR
Deletes zero or more interpreters given by the optional \fIpath\fR
arguments, and for each interpreter, it also deletes its slaves. The
@@ -163,9 +215,9 @@ exists, the command raises an error.
This command concatenates all of the \fIarg\fR arguments in the same
fashion as the \fBconcat\fR command, then evaluates the resulting string as
a Tcl script in the slave interpreter identified by \fIpath\fR. The result
-of this evaluation (including error information such as the \fBerrorInfo\fR
-and \fBerrorCode\fR variables, if an error occurs) is returned to the
-invoking interpreter.
+of this evaluation (including all \fBreturn\fR options,
+such as \fB\-errorinfo\fR and \fB\-errorcode\fR information, if an
+error occurs) is returned to the invoking interpreter.
Note that the script will be executed in the current context stack frame of the
\fIpath\fR interpreter; this is so that the implementations (in a master
interpreter) of aliases in a slave interpreter can execute scripts in
@@ -173,10 +225,9 @@ the slave that find out information about the slave's current state
and stack frame.
.TP
\fBinterp exists \fIpath\fR
-Returns \fB1\fR if a slave interpreter by the specified \fIpath\fR
+Returns \fB1\fR if a slave interpreter by the specified \fIpath\fR
exists in this master, \fB0\fR otherwise. If \fIpath\fR is omitted, the
invoking interpreter is used.
-.VS "" BR
.TP
\fBinterp expose \fIpath\fR \fIhiddenName\fR ?\fIexposedCmdName\fR?
Makes the hidden command \fIhiddenName\fR exposed, eventually bringing
@@ -191,11 +242,11 @@ Hidden commands are explained in more detail in \fBHIDDEN COMMANDS\fR, below.
\fBinterp\fR \fBhide\fR \fIpath\fR \fIexposedCmdName\fR ?\fIhiddenCmdName\fR?
Makes the exposed command \fIexposedCmdName\fR hidden, renaming
it to the hidden command \fIhiddenCmdName\fR, or keeping the same name if
-\fIhiddenCmdName\fR is not given, in the interpreter denoted
+\fIhiddenCmdName\fR is not given, in the interpreter denoted
by \fIpath\fR.
If a hidden command with the targeted name already exists, this command
fails.
-Currently both \fIexposedCmdName\fR and \fIhiddenCmdName\fR can
+Currently both \fIexposedCmdName\fR and \fIhiddenCmdName\fR can
not contain namespace qualifiers, or an error is raised.
Commands to be hidden by \fBinterp hide\fR are looked up in the global
namespace even if the current namespace is not the global one. This
@@ -207,21 +258,41 @@ Hidden commands are explained in more detail in \fBHIDDEN COMMANDS\fR, below.
Returns a list of the names of all hidden commands in the interpreter
identified by \fIpath\fR.
.TP
-\fBinterp\fR \fBinvokehidden\fR \fIpath\fR ?\fB-global\fR? \fIhiddenCmdName\fR ?\fIarg ...\fR?
+\fBinterp\fR \fBinvokehidden\fR \fIpath\fR ?\fI\-option ...\fR? \fIhiddenCmdName\fR ?\fIarg ...\fR?
Invokes the hidden command \fIhiddenCmdName\fR with the arguments supplied
in the interpreter denoted by \fIpath\fR. No substitutions or evaluation
-are applied to the arguments.
-If the \fB-global\fR flag is present, the hidden command is invoked at the
+are applied to the arguments. Three \fI\-option\fRs are supported, all
+of which start with \fB\-\fR: \fB\-namespace\fR (which takes a single
+argument afterwards, \fInsName\fR), \fB\-global\fR, and \fB\-\|\-\fR.
+If the \fB\-namespace\fR flag is present, the hidden command is invoked in
+the namespace called \fInsName\fR in the target interpreter.
+If the \fB\-global\fR flag is present, the hidden command is invoked at the
global level in the target interpreter; otherwise it is invoked at the
current call frame and can access local variables in that and outer call
frames.
+The \fB\-\|\-\fR flag allows the \fIhiddenCmdName\fR argument to start with a
+.QW \-
+character, and is otherwise unnecessary.
+If both the \fB\-namespace\fR and \fB\-global\fR flags are present, the
+\fB\-namespace\fR flag is ignored.
+Note that the hidden command will be executed (by default) in the
+current context stack frame of the \fIpath\fR interpreter.
Hidden commands are explained in more detail in \fBHIDDEN COMMANDS\fR, below.
-.VE
+.TP
+\fBinterp\fR \fBlimit\fR \fIpath\fR \fIlimitType\fR ?\fI\-option\fR? ?\fIvalue\fR \fI...\fR?
+.VS 8.5
+Sets up, manipulates and queries the configuration of the resource
+limit \fIlimitType\fR for the interpreter denoted by \fIpath\fR. If
+no \fI\-option\fR is specified, return the current configuration of the
+limit. If \fI\-option\fR is the sole argument, return the value of that
+option. Otherwise, a list of \fI\-option\fR/\fIvalue\fR argument pairs
+must supplied. See \fBRESOURCE LIMITS\fR below for a more detailed
+explanation of what limits and options are supported.
+.VE 8.5
.TP
\fBinterp issafe\fR ?\fIpath\fR?
Returns \fB1\fR if the interpreter identified by the specified \fIpath\fR
is safe, \fB0\fR otherwise.
-.VS "" BR
.TP
\fBinterp marktrusted\fR \fIpath\fR
Marks the interpreter identified by \fIpath\fR as trusted. Does
@@ -229,7 +300,6 @@ not expose the hidden commands. This command can only be invoked from a
trusted interpreter.
The command has no effect if the interpreter identified by \fIpath\fR is
already trusted.
-.VE
.TP
\fBinterp\fR \fBrecursionlimit\fR \fIpath\fR ?\fInewlimit\fR?
Returns the maximum allowable nesting depth for the interpreter
@@ -239,14 +309,16 @@ of more than \fInewlimit\fR calls to \fBTcl_Eval()\fR
and related procedures in that interpreter will return an error.
The \fInewlimit\fR value is also returned.
The \fInewlimit\fR value must be a positive integer between 1 and the
-maximum value of a non-long integer on the platform.
-.sp
+maximum value of a non-long integer on the platform.
+.RS
+.PP
The command sets the maximum size of the Tcl call stack only. It cannot
by itself prevent stack overflows on the C stack being used by the
application. If your machine has a limit on the size of the C stack, you
may get stack overflows before reaching the limit set by the command. If
this happens, see if there is a mechanism in your system for increasing
-the maximum size of the C stack.
+the maximum size of the C stack.
+.RE
.TP
\fBinterp\fR \fBshare\fR \fIsrcPath channelId destPath\fR
Causes the IO channel identified by \fIchannelId\fR to become shared
@@ -293,7 +365,7 @@ The valid forms of this command are:
\fIslave \fBaliases\fR
Returns a Tcl list whose elements are the tokens of all the
aliases in \fIslave\fR. The tokens correspond to the values returned when
-the aliases were created (which may not be the same
+the aliases were created (which may not be the same
as the current names of the commands).
.TP
\fIslave \fBalias \fIsrcToken\fR
@@ -320,19 +392,28 @@ The command returns a token that uniquely identifies the command created
\fIsrcCmd\fR, even if the command is renamed afterwards. The token may but
does not have to be equal to \fIsrcCmd\fR.
.TP
+\fIslave \fBbgerror\fR ?\fIcmdPrefix\fR?
+.VS 8.5
+This command either gets or sets the current background error handler
+for the \fIslave\fR interpreter. If \fIcmdPrefix\fR is
+absent, the current background error handler is returned, and if it is
+present, it is a list of words (of minimum length one) that describes
+what to set the interpreter's background error to. See the
+\fBBACKGROUND ERROR HANDLING\fR section for more details.
+.VE 8.5
+.TP
\fIslave \fBeval \fIarg \fR?\fIarg ..\fR?
This command concatenates all of the \fIarg\fR arguments in
the same fashion as the \fBconcat\fR command, then evaluates
the resulting string as a Tcl script in \fIslave\fR.
-The result of this evaluation (including error information
-such as the \fBerrorInfo\fR and \fBerrorCode\fR variables, if an
+The result of this evaluation (including all \fBreturn\fR options,
+such as \fB\-errorinfo\fR and \fB\-errorcode\fR information, if an
error occurs) is returned to the invoking interpreter.
Note that the script will be executed in the current context stack frame
of \fIslave\fR; this is so that the implementations (in a master
interpreter) of aliases in a slave interpreter can execute scripts in
the slave that find out information about the slave's current state
and stack frame.
-.VS "" BR
.TP
\fIslave \fBexpose \fIhiddenName \fR?\fIexposedCmdName\fR?
This command exposes the hidden command \fIhiddenName\fR, eventually bringing
@@ -344,12 +425,12 @@ fails.
For more details on hidden commands, see \fBHIDDEN COMMANDS\fR, below.
.TP
\fIslave \fBhide \fIexposedCmdName\fR ?\fIhiddenCmdName\fR?
-This command hides the exposed command \fIexposedCmdName\fR, renaming it to
+This command hides the exposed command \fIexposedCmdName\fR, renaming it to
the hidden command \fIhiddenCmdName\fR, or keeping the same name if the
argument is not given, in the \fIslave\fR interpreter.
If a hidden command with the targeted name already exists, this command
fails.
-Currently both \fIexposedCmdName\fR and \fIhiddenCmdName\fR can
+Currently both \fIexposedCmdName\fR and \fIhiddenCmdName\fR can
not contain namespace qualifiers, or an error is raised.
Commands to be hidden are looked up in the global
namespace even if the current namespace is not the global one. This
@@ -360,27 +441,46 @@ For more details on hidden commands, see \fBHIDDEN COMMANDS\fR, below.
\fIslave \fBhidden\fR
Returns a list of the names of all hidden commands in \fIslave\fR.
.TP
-\fIslave \fBinvokehidden\fR ?\fB-global\fR \fIhiddenName \fR?\fIarg ..\fR?
+\fIslave \fBinvokehidden\fR ?\fI\-option ...\fR? \fIhiddenName \fR?\fIarg ..\fR?
This command invokes the hidden command \fIhiddenName\fR with the
supplied arguments, in \fIslave\fR. No substitutions or evaluations are
-applied to the arguments.
-If the \fB-global\fR flag is given, the command is invoked at the global
+applied to the arguments. Three \fI\-option\fRs are supported, all
+of which start with \fB\-\fR: \fB\-namespace\fR (which takes a single
+argument afterwards, \fInsName\fR), \fB\-global\fR, and \fB\-\|\-\fR.
+If the \fB\-namespace\fR flag is given, the hidden command is invoked in
+the specified namespace in the slave.
+If the \fB\-global\fR flag is given, the command is invoked at the global
level in the slave; otherwise it is invoked at the current call frame and
can access local variables in that or outer call frames.
+The \fB\-\|\-\fR flag allows the \fIhiddenCmdName\fR argument to start with a
+.QW \-
+character, and is otherwise unnecessary.
+If both the \fB\-namespace\fR and \fB\-global\fR flags are given, the
+\fB\-namespace\fR flag is ignored.
+Note that the hidden command will be executed (by default) in the
+current context stack frame of \fIslave\fR.
For more details on hidden commands,
see \fBHIDDEN COMMANDS\fR, below.
-.VE
.TP
\fIslave \fBissafe\fR
Returns \fB1\fR if the slave interpreter is safe, \fB0\fR otherwise.
-.VS "" BR
+.TP
+\fIslave \fBlimit\fR \fIlimitType\fR ?\fI\-option\fR? ?\fIvalue\fR \fI...\fR?
+.VS 8.5
+Sets up, manipulates and queries the configuration of the resource
+limit \fIlimitType\fR for the slave interpreter. If no \fI\-option\fR
+is specified, return the current configuration of the limit. If
+\fI\-option\fR is the sole argument, return the value of that option.
+Otherwise, a list of \fI\-option\fR/\fIvalue\fR argument pairs must
+supplied. See \fBRESOURCE LIMITS\fR below for a more detailed explanation of
+what limits and options are supported.
+.VE 8.5
.TP
\fIslave \fBmarktrusted\fR
Marks the slave interpreter as trusted. Can only be invoked by a
trusted interpreter. This command does not expose any hidden
commands in the slave interpreter. The command has no effect if the slave
is already trusted.
-.VE
.TP
\fIslave\fR \fBrecursionlimit\fR ?\fInewlimit\fR?
Returns the maximum allowable nesting depth for the \fIslave\fR interpreter.
@@ -389,14 +489,16 @@ set so that nesting of more than \fInewlimit\fR calls to \fBTcl_Eval()\fR
and related procedures in \fIslave\fR will return an error.
The \fInewlimit\fR value is also returned.
The \fInewlimit\fR value must be a positive integer between 1 and the
-maximum value of a non-long integer on the platform.
-.sp
+maximum value of a non-long integer on the platform.
+.RS
+.PP
The command sets the maximum size of the Tcl call stack only. It cannot
by itself prevent stack overflows on the C stack being used by the
application. If your machine has a limit on the size of the C stack, you
may get stack overflows before reaching the limit set by the command. If
this happens, see if there is a mechanism in your system for increasing
-the maximum size of the C stack.
+the maximum size of the C stack.
+.RE
.SH "SAFE INTERPRETERS"
.PP
A safe interpreter is one with restricted functionality, so that
@@ -422,32 +524,33 @@ A safe interpreter is created with exactly the following set of
built-in commands:
.DS
.ta 1.2i 2.4i 3.6i
-\fBafter append array binary
-break case catch clock
-close concat continue eof
-error eval expr fblocked
-fcopy fileevent flush for
-foreach format gets global
-if incr info interp
-join lappend lindex linsert
-list llength lrange lreplace
-lsearch lsort namespace package
-pid proc puts read
-regexp regsub rename return
-scan seek set split
-string subst switch tell
-time trace unset update
-uplevel upvar variable vwait
-while\fR
+\fBafter\fR \fBappend\fR \fBapply\fR \fBarray\fR
+\fBbinary\fR \fBbreak\fR \fBcatch\fR \fBchan\fR
+\fBclock\fR \fBclose\fR \fBconcat\fR \fBcontinue\fR
+\fBdict\fR \fBeof\fR \fBerror\fR \fBeval\fR
+\fBexpr\fR \fBfblocked\fR \fBfcopy\fR \fBfileevent\fR
+\fBflush\fR \fBfor\fR \fBforeach\fR \fBformat\fR
+\fBgets\fR \fBglobal\fR \fBif\fR \fBincr\fR
+\fBinfo\fR \fBinterp\fR \fBjoin\fR \fBlappend\fR
+\fBlassign\fR \fBlindex\fR \fBlinsert\fR \fBlist\fR
+\fBllength\fR \fBlrange\fR \fBlrepeat\fR \fBlreplace\fR
+\fBlsearch\fR \fBlset\fR \fBlsort\fR \fBnamespace\fR
+\fBpackage\fR \fBpid\fR \fBproc\fR \fBputs\fR
+\fBread\fR \fBregexp\fR \fBregsub\fR \fBrename\fR
+\fBreturn\fR \fBscan\fR \fBseek\fR \fBset\fR
+\fBsplit\fR \fBstring\fR \fBsubst\fR \fBswitch\fR
+\fBtell\fR \fBtime\fR \fBtrace\fR \fBunset\fR
+\fBupdate\fR \fBuplevel\fR \fBupvar\fR \fBvariable\fR
+\fBvwait\fR \fBwhile\fR
.DE
-.VS "" BR
The following commands are hidden by \fBinterp create\fR when it
creates a safe interpreter:
.DS
.ta 1.2i 2.4i 3.6i
-\fBcd encoding exec exit
-fconfigure file glob load
-open pwd socket source\fR
+\fBcd\fR \fBencoding\fR \fBexec\fR \fBexit\fR
+\fBfconfigure\fR \fBfile\fR \fBglob\fR \fBload\fR
+\fBopen\fR \fBpwd\fR \fBsocket\fR \fBsource\fR
+\fBunload\fR
.DE
These commands can be recreated later as Tcl procedures or aliases, or
re-exposed by \fBinterp expose\fR.
@@ -456,25 +559,24 @@ The following commands from Tcl's library of support procedures are
not present in a safe interpreter:
.DS
.ta 1.6i 3.2i
-\fBauto_exec_ok auto_import auto_load
-auto_load_index auto_qualify unknown\fR
+\fBauto_exec_ok\fR \fBauto_import\fR \fBauto_load\fR
+\fBauto_load_index\fR \fBauto_qualify\fR \fBunknown\fR
.DE
Note in particular that safe interpreters have no default \fBunknown\fR
-command, so Tcl's default autoloading facilities are not available.
+command, so Tcl's default autoloading facilities are not available.
Autoload access to Tcl's commands that are normally autoloaded:
.DS
.ta 2.1i
-\fB
-auto_mkindex auto_mkindex_old
-auto_reset history
-parray pkg_mkIndex
-::pkg::create ::safe::interpAddToAccessPath
-::safe::interpCreate ::safe::interpConfigure
-::safe::interpDelete ::safe::interpFindInAccessPath
-::safe::interpInit ::safe::setLogCmd
-tcl_endOfWord tcl_findLibrary
-tcl_startOfNextWord tcl_startOfPreviousWord
-tcl_wordBreakAfter tcl_wordBreakBefore\fR
+\fBauto_mkindex\fR \fBauto_mkindex_old\fR
+\fBauto_reset\fR \fBhistory\fR
+\fBparray\fR \fBpkg_mkIndex\fR
+\fB::pkg::create\fR \fB::safe::interpAddToAccessPath\fR
+\fB::safe::interpCreate\fR \fB::safe::interpConfigure\fR
+\fB::safe::interpDelete\fR \fB::safe::interpFindInAccessPath\fR
+\fB::safe::interpInit\fR \fB::safe::setLogCmd\fR
+\fBtcl_endOfWord\fR \fBtcl_findLibrary\fR
+\fBtcl_startOfNextWord\fR \fBtcl_startOfPreviousWord\fR
+\fBtcl_wordBreakAfter\fR \fBtcl_wordBreakBefore\fR
.DE
can only be provided by explicit definition of an \fBunknown\fR command
in the safe interpreter. This will involve exposing the \fBsource\fR
@@ -482,7 +584,6 @@ command. This is most easily accomplished by creating the safe interpreter
with Tcl's \fBSafe\-Tcl\fR mechanism. \fBSafe\-Tcl\fR provides safe
versions of \fBsource\fR, \fBload\fR, and other Tcl commands needed
to support autoloading of commands and the loading of packages.
-.VE
.PP
In addition, the \fBenv\fR variable is not present in a safe interpreter,
so it cannot share environment variables with other interpreters. The
@@ -518,9 +619,10 @@ as they would be for any other command invoked in that interpreter.
The command procedure for the source command takes its arguments
and merges them with the \fItargetCmd\fR and \fIarg\fRs for the
alias to create a new array of arguments. If the words
-of \fIsrcCmd\fR were ``\fIsrcCmd arg1 arg2 ... argN\fR'',
+of \fIsrcCmd\fR were
+.QW "\fIsrcCmd arg1 arg2 ... argN\fR" ,
the new set of words will be
-``\fItargetCmd arg arg ... arg arg1 arg2 ... argN\fR'',
+.QW "\fItargetCmd arg arg ... arg arg1 arg2 ... argN\fR" ,
where \fItargetCmd\fR and \fIarg\fRs are the values supplied when the
alias was created. \fITargetCmd\fR is then used to locate a command
procedure in the target interpreter, and that command procedure
@@ -540,7 +642,6 @@ evaluated or substituted, since this would provide an escape
mechanism whereby the slave interpreter could execute arbitrary
code in the master. This in turn would compromise the security
of the system.
-.VS
.SH "HIDDEN COMMANDS"
.PP
Safe interpreters greatly restrict the functionality available to Tcl
@@ -608,10 +709,108 @@ Commands to be hidden by \fBinterp hide\fR are looked up in the global
namespace even if the current namespace is not the global one. This
prevents slaves from fooling a master interpreter into hiding the wrong
command, by making the current namespace be different from the global one.
-.VE
-.SH CREDITS
+.SH "RESOURCE LIMITS"
+.VS 8.5
.PP
-This mechanism is based on the Safe-Tcl prototype implemented
+Every interpreter has two kinds of resource limits that may be imposed by any
+master interpreter upon its slaves. Command limits (of type \fBcommand\fR)
+restrict the total number of Tcl commands that may be executed by an
+interpreter (as can be inspected via the \fBinfo cmdcount\fR command), and
+time limits (of type \fBtime\fR) place a limit by which execution within the
+interpreter must complete. Note that time limits are expressed as
+\fIabsolute\fR times (as in \fBclock seconds\fR) and not relative times (as in
+\fBafter\fR) because they may be modified after creation.
+.PP
+When a limit is exceeded for an interpreter, first any handler callbacks
+defined by master interpreters are called. If those callbacks increase or
+remove the limit, execution within the (previously) limited interpreter
+continues. If the limit is still in force, an error is generated at that point
+and normal processing of errors within the interpreter (by the \fBcatch\fR
+command) is disabled, so the error propagates outwards (building a stack-trace
+as it goes) to the point where the limited interpreter was invoked (e.g. by
+\fBinterp eval\fR) where it becomes the responsibility of the calling code to
+catch and handle.
+.SS "LIMIT OPTIONS"
+.PP
+Every limit has a number of options associated with it, some of which are
+common across all kinds of limits, and others of which are particular to the
+kind of limit.
+.VE 8.5
+.TP
+\fB\-command\fR
+.VS 8.5
+This option (common for all limit types) specifies (if non-empty) a Tcl script
+to be executed in the global namespace of the interpreter reading and writing
+the option when the particular limit in the limited interpreter is exceeded.
+The callback may modify the limit on the interpreter if it wishes the limited
+interpreter to continue executing. If the callback generates an error, it is
+reported through the background error mechanism (see \fBBACKGROUND ERROR
+HANDLING\fR). Note that the callbacks defined by one interpreter are
+completely isolated from the callbacks defined by another, and that the order
+in which those callbacks are called is undefined.
+.VE 8.5
+.TP
+\fB\-granularity\fR
+.VS 8.5
+This option (common for all limit types) specifies how frequently (out of the
+points when the Tcl interpreter is in a consistent state where limit checking
+is possible) that the limit is actually checked. This allows the tuning of how
+frequently a limit is checked, and hence how often the limit-checking overhead
+(which may be substantial in the case of time limits) is incurred.
+.VE 8.5
+.TP
+\fB\-milliseconds\fR
+.VS 8.5
+This option specifies the number of milliseconds after the moment defined in
+the \fB\-seconds\fR option that the time limit will fire. It should only ever
+be specified in conjunction with the \fB\-seconds\fR option (whether it was
+set previously or is being set this invocation.)
+.VE 8.5
+.TP
+\fB\-seconds\fR
+.VS 8.5
+This option specifies the number of seconds after the epoch (see \fBclock
+seconds\fR) that the time limit for the interpreter will be triggered. The
+limit will be triggered at the start of the second unless specified at a
+sub-second level using the \fB\-milliseconds\fR option. This option may be the
+empty string, which indicates that a time limit is not set for the
+interpreter.
+.VE 8.5
+.TP
+\fB\-value\fR
+.VS 8.5
+This option specifies the number of commands that the interpreter may execute
+before triggering the command limit. This option may be the empty string,
+which indicates that a command limit is not set for the interpreter.
+.PP
+Where an interpreter with a resource limit set on it creates a slave
+interpreter, that slave interpreter will have resource limits imposed on it
+that are at least as restrictive as the limits on the creating master
+interpreter. If the master interpreter of the limited master wishes to relax
+these conditions, it should hide the \fBinterp\fR command in the child and
+then use aliases and the \fBinterp invokehidden\fR subcommand to provide such
+access as it chooses to the \fBinterp\fR command to the limited master as
+necessary.
+.SH "BACKGROUND ERROR HANDLING"
+.PP
+When an error happens in a situation where it cannot be reported directly up
+the stack (e.g. when processing events in an \fBupdate\fR or \fBvwait\fR call)
+the error is instead reported through the background error handling mechanism.
+Every interpreter has a background error handler registered; the default error
+handler arranges for the \fBbgerror\fR command in the interpreter's global
+namespace to be called, but other error handlers may be installed and process
+background errors in substantially different ways.
+.PP
+A background error handler consists of a non-empty list of words to which will
+be appended two further words at invocation time. The first word will be the
+error message string, and the second will a dictionary of return options (this
+is also the sort of information that can be obtained by trapping a normal
+error using \fBcatch\fR of course.) The resulting list will then be executed
+in the interpreter's global namespace without further substitutions being
+performed.
+.VE 8.5
+.SH CREDITS
+The safe interpreter mechanism is based on the Safe-Tcl prototype implemented
by Nathaniel Borenstein and Marshall Rose.
.SH EXAMPLES
Creating and using an alias for a command in the current interpreter:
@@ -621,22 +820,33 @@ set idx [getIndex delta]
.CE
.PP
Executing an arbitrary command in a safe interpreter where every
-invokation of \fBlappend\fR is logged:
+invocation of \fBlappend\fR is logged:
.CS
set i [\fBinterp create\fR -safe]
\fBinterp hide\fR $i lappend
\fBinterp alias\fR $i lappend {} loggedLappend $i
proc loggedLappend {i args} {
- puts "logged invokation of lappend $args"
- # Be extremely careful about command construction
- eval [linsert $args 0 \\
- \fBinterp invokehidden\fR $i lappend]
+ puts "logged invocation of lappend $args"
+ \fBinterp invokehidden\fR $i lappend {*}$args
}
\fBinterp eval\fR $i $someUntrustedScript
.CE
-
+.PP
+.VS 8.5
+Setting a resource limit on an interpreter so that an infinite loop
+terminates.
+.CS
+set i [\fBinterp create\fR]
+\fBinterp limit\fR $i command -value 1000
+\fBinterp eval\fR $i {
+ set x 0
+ while {1} {
+ puts "Counting up... [incr x]"
+ }
+}
+.CE
+.VE 8.5
.SH "SEE ALSO"
-load(n), safe(n), Tcl_CreateSlave(3)
-
+bgerror(n), load(n), safe(n), Tcl_CreateSlave(3)
.SH KEYWORDS
alias, master interpreter, safe interpreter, slave interpreter
diff --git a/doc/join.n b/doc/join.n
index f28c07c..582b730 100644
--- a/doc/join.n
+++ b/doc/join.n
@@ -27,14 +27,14 @@ Making a comma-separated list:
.CS
set data {1 2 3 4 5}
\fBjoin\fR $data ", "
- \fB=> 1, 2, 3, 4, 5\fR
+ \fB\(-> 1, 2, 3, 4, 5\fR
.CE
.PP
Using \fBjoin\fR to flatten a list by a single level:
.CS
set data {1 {2 3} 4 {5 {6 7} 8}}
\fBjoin\fR $data
- \fB=> 1 2 3 4 5 {6 7} 8\fR
+ \fB\(-> 1 2 3 4 5 {6 7} 8\fR
.CE
.SH "SEE ALSO"
diff --git a/doc/lappend.n b/doc/lappend.n
index cb5d7fa..dbed3bb 100644
--- a/doc/lappend.n
+++ b/doc/lappend.n
@@ -1,7 +1,7 @@
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
-'\" Copyright (c) 2001 Kevin B. Kenny. All rights reserved.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -21,14 +21,16 @@ lappend \- Append list elements onto a variable
This command treats the variable given by \fIvarName\fR as a list
and appends each of the \fIvalue\fR arguments to that list as a separate
element, with spaces between elements.
-If \fIvarName\fR doesn't exist, it is created as a list with elements
+If \fIvarName\fR does not exist, it is created as a list with elements
given by the \fIvalue\fR arguments.
\fBLappend\fR is similar to \fBappend\fR except that the \fIvalue\fRs
are appended as list elements rather than raw text.
This command provides a relatively efficient way to build up
-large lists. For example, ``\fBlappend a $b\fR'' is much
-more efficient than ``\fBset a [concat $a [list $b]]\fR'' when
-\fB$a\fR is long.
+large lists. For example,
+.QW "\fBlappend a $b\fR"
+is much more efficient than
+.QW "\fBset a [concat $a [list $b]]\fR"
+when \fB$a\fR is long.
.SH EXAMPLE
Using \fBlappend\fR to build up a list of numbers.
.CS
@@ -41,10 +43,7 @@ Using \fBlappend\fR to build up a list of numbers.
.CE
.SH "SEE ALSO"
-list(n), lindex(n), linsert(n), llength(n),
-.VS 8.4
-lset(n)
-.VE
+list(n), lindex(n), linsert(n), llength(n), lset(n),
lsort(n), lrange(n)
.SH KEYWORDS
diff --git a/doc/lassign.n b/doc/lassign.n
new file mode 100644
index 0000000..b791feb
--- /dev/null
+++ b/doc/lassign.n
@@ -0,0 +1,55 @@
+'\"
+'\" Copyright (c) 1992-1999 Karl Lehenbauer & Mark Diekhans
+'\" Copyright (c) 2004 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 lassign n 8.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+lassign \- Assign list elements to variables
+.SH SYNOPSIS
+\fBlassign \fIlist varName \fR?\fIvarName ...\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+This command treats the value \fIlist\fR as a list and assigns
+successive elements from that list to the variables given by the
+\fIvarName\fR arguments in order. If there are more variable names
+than list elements, the remaining variables are set to the empty
+string. If there are more list elements than variables, a list of
+unassigned elements is returned.
+.SH EXAMPLES
+An illustration of how multiple assignment works, and what happens
+when there are either too few or too many elements.
+.CS
+lassign {a b c} x y z ;# Empty return
+puts $x ;# Prints "a"
+puts $y ;# Prints "b"
+puts $z ;# Prints "c"
+
+lassign {d e} x y z ;# Empty return
+puts $x ;# Prints "d"
+puts $y ;# Prints "e"
+puts $z ;# Prints ""
+
+lassign {f g h i} x y ;# Returns "h i"
+puts $x ;# Prints "f"
+puts $y ;# Prints "g"
+.CE
+The \fBlassign\fR command has other uses. It can be used to create
+the analogue of the
+.QW shift
+command in many shell languages like this:
+.CS
+set ::argv [lassign $::argv argumentToReadOff]
+.CE
+.SH "SEE ALSO"
+lindex(n), list(n), lset(n), set(n)
+
+.SH KEYWORDS
+assign, element, list, multiple, set, variable
diff --git a/doc/library.n b/doc/library.n
index 67b1037..f29af8b 100644
--- a/doc/library.n
+++ b/doc/library.n
@@ -21,15 +21,12 @@ auto_execok, auto_import, auto_load, auto_mkindex, auto_mkindex_old, auto_qualif
\fBauto_reset\fR
\fBtcl_findLibrary \fIbasename version patch initScript enVarName varName\fR
\fBparray \fIarrayName\fR
-.VS
\fBtcl_endOfWord \fIstr start\fR
\fBtcl_startOfNextWord \fIstr start\fR
\fBtcl_startOfPreviousWord \fIstr start\fR
\fBtcl_wordBreakAfter \fIstr start\fR
\fBtcl_wordBreakBefore \fIstr start\fR
-.VE
.BE
-
.SH INTRODUCTION
.PP
Tcl includes a library of Tcl procedures for commonly-needed functions.
@@ -55,7 +52,6 @@ If the library procedure \fBTcl_Init\fR is invoked from an application's
The code in \fBinit.tcl\fR will define the \fBunknown\fR procedure
and arrange for the other procedures to be loaded on-demand using
the auto-load mechanism defined below.
-
.SH "COMMAND PROCEDURES"
.PP
The following procedures are provided in the Tcl library:
@@ -68,7 +64,7 @@ named by \fIcmd\fR. If not, it returns an empty string. This command
examines the directories in the current search path (given by the PATH
environment variable) in its search for an executable file named
\fIcmd\fR. On Windows platforms, the search is expanded with the same
-directories and file extensions as used by \fBexec\fR. \fBAuto_exec\fR
+directories and file extensions as used by \fBexec\fR. \fBAuto_execok\fR
remembers information about previous searches in an array named
\fBauto_execs\fR; this avoids the path search in future calls for the
same \fIcmd\fR. The command \fBauto_reset\fR may be used to force
@@ -98,7 +94,7 @@ with the \fBauto_mkindex\fR command. If \fIcmd\fR is found in an
index file, then the appropriate script is evaluated to create the
command. The \fBauto_load\fR command returns 1 if \fIcmd\fR was
successfully created. The command returns 0 if there was no index
-entry for \fIcmd\fR or if the script didn't actually define \fIcmd\fR
+entry for \fIcmd\fR or if the script did not actually define \fIcmd\fR
(e.g. because index information is out of date). If an error occurs
while processing the script, then that error is returned.
\fBAuto_load\fR only reads the index information once and saves it in
@@ -136,9 +132,11 @@ unsophisticated way: if any line contains the word \fBproc\fR
as its first characters then it is assumed to be a procedure
definition and the next word of the line is taken as the
procedure's name.
-Procedure definitions that don't appear in this way (e.g. they
+Procedure definitions that do not appear in this way (e.g. they
have spaces before the \fBproc\fR) will not be indexed. If your
-script contains "dangerous" code, such as global initialization
+script contains
+.QW dangerous
+code, such as global initialization
code or procedure names with special characters like \fB$\fR,
\fB*\fR, \fB[\fR or \fB]\fR, you are safer using auto_mkindex_old.
.RE
@@ -148,7 +146,7 @@ Destroys all the information cached by \fBauto_execok\fR and
\fBauto_load\fR. This information will be re-read from disk the next
time it is needed. \fBAuto_reset\fR also deletes any procedures
listed in the auto-load index, so that fresh copies of them will be
-loaded the next time that they're used.
+loaded the next time that they are used.
.TP
\fBauto_qualify \fIcommand namespace\fR
Computes a list of fully qualified names for \fIcommand\fR. This list
@@ -174,18 +172,20 @@ This is a standard search procedure for use by extensions during
their initialization. They call this procedure to look for their
script library in several standard directories.
The last component of the name of the library directory is
-normally \fIbasenameversion\fP
-(e.g., tk8.0), but it might be "library" when in the build hierarchies.
+normally \fIbasenameversion\fR
+(e.g., tk8.0), but it might be
+.QW library
+when in the build hierarchies.
The \fIinitScript\fR file will be sourced into the interpreter
once it is found. The directory in which this file is found is
-stored into the global variable \fIvarName\fP.
+stored into the global variable \fIvarName\fR.
If this variable is already defined (e.g., by C code during
application initialization) then no searching is done.
Otherwise the search looks in these directories:
-the directory named by the environment variable \fIenVarName\fP;
+the directory named by the environment variable \fIenVarName\fR;
relative to the Tcl library directory;
relative to the executable file in the standard installation
-bin or bin/\fIarch\fP directory;
+bin or bin/\fIarch\fR directory;
relative to the executable file in the current build tree;
relative to the executable file in a parallel build tree.
.TP
@@ -196,7 +196,6 @@ in the array \fIarrayName\fR.
It may be either local or global.
.TP
\fBtcl_endOfWord \fIstr start\fR
-.VS
Returns the index of the first end-of-word location that occurs after
a starting index \fIstart\fR in the string \fIstr\fR. An end-of-word
location is defined to be the first non-word character following the
@@ -232,8 +231,6 @@ Returns the index of the first word boundary before the starting index
boundaries before the starting point in the given string. The index
returned refers to the second character of the pair that comprises a
boundary.
-.VE
-
.SH "VARIABLES"
.PP
The following global variables are defined or used by the procedures in
@@ -268,17 +265,18 @@ the directories listed in the $tcl_pkgPath variable.
If set, then it specifies the location of the directory containing
library scripts (the value of this variable will be
assigned to the \fBtcl_library\fR variable and therefore returned by
-the command \fBinfo library\fR). If this variable isn't set then
+the command \fBinfo library\fR). If this variable is not set then
a default value is used.
.TP
\fBenv(TCLLIBPATH)\fR
If set, then it must contain a valid Tcl list giving directories to
search during auto-load operations. Directories must be specified in
-Tcl format, using "/" as the path separator, regardless of platform.
+Tcl format, using
+.QW /
+as the path separator, regardless of platform.
This variable is only used when initializing the \fBauto_path\fR variable.
.TP
\fBtcl_nonwordchars\fR
-.VS
This variable contains a regular expression that is used by routines
like \fBtcl_endOfWord\fR to identify whether a character is part of a
word or not. If the pattern matches a character, the character is
@@ -294,17 +292,7 @@ word or not. If the pattern matches a character, the character is
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.
-.VE
-.TP
-\fBunknown_pending\fR
-Used by \fBunknown\fR to record the command(s) for which it is
-searching.
-It is used to detect errors where \fBunknown\fR recurses on itself
-infinitely.
-The variable is unset before \fBunknown\fR returns.
-
.SH "SEE ALSO"
info(n), re_syntax(n)
-
.SH KEYWORDS
auto-exec, auto-load, library, unknown, word, whitespace
diff --git a/doc/lindex.n b/doc/lindex.n
index a12fdcf..f0417ac 100644
--- a/doc/lindex.n
+++ b/doc/lindex.n
@@ -1,7 +1,7 @@
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
-'\" Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
+'\" Copyright (c) 2001 by Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -17,9 +17,8 @@ lindex \- Retrieve an element from a list
.BE
.SH DESCRIPTION
.PP
-.VS 8.4
-The \fBlindex\fP command accepts a parameter, \fIlist\fP, which
-it treats as a Tcl list. It also accepts zero or more \fIindices\fP into
+The \fBlindex\fR command accepts a parameter, \fIlist\fR, which
+it treats as a Tcl list. It also accepts zero or more \fIindices\fR into
the list. The indices may be presented either consecutively on the
command line, or grouped in a
Tcl list and presented as a single argument.
@@ -37,7 +36,6 @@ In this case, the return value of \fBlindex\fR is simply the value of the
.PP
When presented with a single index, the \fBlindex\fR command
treats \fIlist\fR as a Tcl list and returns the
-.VE
\fIindex\fR'th element from it (0 refers to the first element of the list).
In extracting the element, \fBlindex\fR observes the same rules
concerning braces and quotes and backslashes as the Tcl command
@@ -46,11 +44,12 @@ substitution and command substitution do not occur.
If \fIindex\fR is negative or greater than or equal to the number
of elements in \fIvalue\fR, then an empty
string is returned.
-If \fIindex\fR has the value \fBend\fR, it refers to the last element
-in the list, and \fBend\-\fIinteger\fR refers to the last element in
-the list minus the specified integer offset.
+.VS 8.5
+The interpretation of each simple \fIindex\fR value is the same as
+for the command \fBstring index\fR, supporting simple index
+arithmetic and indices relative to the end of the list.
+.VE 8.5
.PP
-.VS 8.4
If additional \fIindex\fR arguments are supplied, then each argument is
used in turn to select an element from the previous indexing operation,
allowing the script to select elements from sublists. The command,
@@ -67,25 +66,33 @@ lindex [lindex [lindex $a 1] 2] 3
.CE
.SH EXAMPLES
.CS
-\fBlindex\fR {a b c} \fI=> a b c\fR
-\fBlindex\fR {a b c} {} \fI=> a b c\fR
-\fBlindex\fR {a b c} 0 \fI=> a\fR
-\fBlindex\fR {a b c} 2 \fI=> c\fR
-\fBlindex\fR {a b c} end \fI=> c\fR
-\fBlindex\fR {a b c} end-1 \fI=> b\fR
-\fBlindex\fR {{a b c} {d e f} {g h i}} 2 1 \fI=> h\fR
-\fBlindex\fR {{a b c} {d e f} {g h i}} {2 1} \fI=> h\fR
-\fBlindex\fR {{{a b} {c d}} {{e f} {g h}}} 1 1 0 \fI=> g\fR
-\fBlindex\fR {{{a b} {c d}} {{e f} {g h}}} {1 1 0} \fI=> g\fR
+\fBlindex\fR {a b c}
+ \fI\(-> a b c\fR
+\fBlindex\fR {a b c} {}
+ \fI\(-> a b c\fR
+\fBlindex\fR {a b c} 0
+ \fI\(-> a\fR
+\fBlindex\fR {a b c} 2
+ \fI\(-> c\fR
+\fBlindex\fR {a b c} end
+ \fI\(-> c\fR
+\fBlindex\fR {a b c} end-1
+ \fI\(-> b\fR
+\fBlindex\fR {{a b c} {d e f} {g h i}} 2 1
+ \fI\(-> h\fR
+\fBlindex\fR {{a b c} {d e f} {g h i}} {2 1}
+ \fI\(-> h\fR
+\fBlindex\fR {{{a b} {c d}} {{e f} {g h}}} 1 1 0
+ \fI\(-> g\fR
+\fBlindex\fR {{{a b} {c d}} {{e f} {g h}}} {1 1 0}
+ \fI\(-> g\fR
.CE
-.VE
.SH "SEE ALSO"
list(n), lappend(n), linsert(n), llength(n), lsearch(n),
-.VS 8.4
-lset(n),
+lset(n), lsort(n), lrange(n), lreplace(n),
+.VS 8.5
+string(n)
.VE
-lsort(n),
-lrange(n), lreplace(n)
.SH KEYWORDS
element, index, list
diff --git a/doc/linsert.n b/doc/linsert.n
index 7b85adb..9f37fcd 100644
--- a/doc/linsert.n
+++ b/doc/linsert.n
@@ -1,7 +1,7 @@
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
-'\" Copyright (c) 2001 Kevin B. Kenny. All rights reserved.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -22,11 +22,12 @@ This command produces a new list from \fIlist\fR by inserting all of the
\fIelement\fR arguments just before the \fIindex\fR'th element of
\fIlist\fR. Each \fIelement\fR argument will become a separate element of
the new list. If \fIindex\fR is less than or equal to zero, then the new
-elements are inserted at the beginning of the list. If \fIindex\fR has the
-value \fBend\fR, or if it is greater than or equal to the number of
-elements in the list, then the new elements are appended to the list.
-\fBend\-\fIinteger\fR refers to the last element in the list minus the
-specified integer offset.
+elements are inserted at the beginning of the list.
+.VS 8.5
+The interpretation of the \fIindex\fR value is the same as
+for the command \fBstring index\fR, supporting simple index
+arithmetic and indices relative to the end of the list.
+.VE
.SH EXAMPLE
Putting some values into a list, first indexing from the start and
then indexing from the end, and then chaining them together:
@@ -39,9 +40,10 @@ set newerList [\fBlinsert\fR [\fBlinsert\fR $oldList end-1 quick] 1 lazy]
.CE
.SH "SEE ALSO"
-.VS 8.4
list(n), lappend(n), lindex(n), llength(n), lsearch(n),
-lset(n), lsort(n), lrange(n), lreplace(n)
+lset(n), lsort(n), lrange(n), lreplace(n),
+.VS 8.5
+string(n)
.VE
.SH KEYWORDS
diff --git a/doc/list.n b/doc/list.n
index 21f9edb..2bcdafb 100644
--- a/doc/list.n
+++ b/doc/list.n
@@ -1,7 +1,7 @@
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
-'\" Copyright (c) 2001 Kevin B. Kenny. All rights reserved.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -43,11 +43,10 @@ while \fBconcat\fR with the same arguments will return
.SH "SEE ALSO"
lappend(n), lindex(n), linsert(n), llength(n), lrange(n),
-lreplace(n), lsearch(n),
-.VS 8.4
-lset(n),
-.VE 8.4
-lsort(n)
+.VS 8.5
+lrepeat(n),
+.VE 8.5
+lreplace(n), lsearch(n), lset(n), lsort(n)
.SH KEYWORDS
element, list
diff --git a/doc/llength.n b/doc/llength.n
index 977d9ef..627800f 100644
--- a/doc/llength.n
+++ b/doc/llength.n
@@ -1,7 +1,7 @@
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
-'\" Copyright (c) 2001 Kevin B. Kenny. All rights reserved.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -48,10 +48,8 @@ An empty list is not necessarily an empty string:
.CE
.SH "SEE ALSO"
-.VS 8.4
list(n), lappend(n), lindex(n), linsert(n), lsearch(n),
lset(n), lsort(n), lrange(n), lreplace(n)
-.VE
.SH KEYWORDS
element, list, length
diff --git a/doc/load.n b/doc/load.n
index 02fec35..e5501f6 100644
--- a/doc/load.n
+++ b/doc/load.n
@@ -9,7 +9,7 @@
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
-load \- Load machine code and initialize new commands.
+load \- Load machine code and initialize new commands
.SH SYNOPSIS
\fBload \fIfileName\fR
.br
@@ -71,7 +71,12 @@ in an application. If a given \fIfileName\fR is loaded into multiple
interpreters, then the first \fBload\fR will load the code and
call the initialization procedure; subsequent \fBload\fRs will
call the initialization procedure without loading the code again.
-It is not possible to unload or reload a package.
+.VS 8.5
+For Tcl versions lower than 8.5, it is not possible to unload or reload a
+package. From version 8.5 however, the \fBunload\fR command allows the unloading
+of libraries loaded with \fBload\fR, for libraries that are aware of the
+Tcl's unloading mechanism.
+.VE 8.5
.PP
The \fBload\fR command also supports packages that are statically
linked with the application, if those packages have been registered
@@ -85,13 +90,10 @@ This may be done differently on different platforms.
The default guess, which is used on most UNIX platforms, is to
take the last element of \fIfileName\fR, strip off the first
three characters if they are \fBlib\fR, and use any following
-.VS
alphabetic and underline characters as the module name.
-.VE
For example, the command \fBload libxyz4.2.so\fR uses the module
name \fBxyz\fR and the command \fBload bin/last.so {}\fR uses the
module name \fBlast\fR.
-.VS "" br
.PP
If \fIfileName\fR is an empty string, then \fIpackageName\fR must
be specified.
@@ -102,17 +104,20 @@ 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.
-.VE
.SH "PORTABILITY ISSUES"
.TP
\fBWindows\fR\0\0\0\0\0
.
-When a load fails with "library not found" error, it is also possible
+When a load fails with
+.QW "library not found"
+error, it is also possible
that a dependent library was not found. To see the dependent libraries,
-type ``dumpbin -imports <dllname>'' in a DOS console to see what the
-library must import.
-When loading a DLL in the current directory, Windows will ignore ``./'' as
-a path specifier and use a search heuristic to find the DLL instead.
+type
+.QW "dumpbin -imports <dllname>"
+in a DOS console to see what the library must import.
+When loading a DLL in the current directory, Windows will ignore
+.QW ./
+as a path specifier and use a search heuristic to find the DLL instead.
To avoid this, load the DLL with:
.CS
\fBload\fR [file join [pwd] mylib.DLL]
@@ -131,7 +136,7 @@ The following is a minimal extension:
#include <stdio.h>
static int fooCmd(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) {
- printf("called with %d arguments\\n", objc);
+ printf("called with %d arguments\en", objc);
return TCL_OK;
}
int Foo_Init(Tcl_Interp *interp) {
diff --git a/doc/lrange.n b/doc/lrange.n
index 5b0d187..34f0150 100644
--- a/doc/lrange.n
+++ b/doc/lrange.n
@@ -1,7 +1,7 @@
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
-'\" Copyright (c) 2001 Kevin B. Kenny. All rights reserved.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -21,18 +21,24 @@ lrange \- Return one or more adjacent elements from a list
\fIList\fR must be a valid Tcl list. This command will
return a new list consisting of elements
\fIfirst\fR through \fIlast\fR, inclusive.
-\fIFirst\fR or \fIlast\fR
-may be \fBend\fR (or any abbreviation of it) to refer to the last
-element of the list.
+.VS 8.5
+The index values \fIfirst\fR and \fIlast\fR are interpreted
+the same as index values for the command \fBstring index\fR,
+supporting simple index arithmetic and indices relative to the
+end of the list.
+.VE
If \fIfirst\fR is less than zero, it is treated as if it were zero.
If \fIlast\fR is greater than or equal to the number of elements
in the list, then it is treated as if it were \fBend\fR.
If \fIfirst\fR is greater than \fIlast\fR then an empty string
is returned.
-Note: ``\fBlrange \fIlist first first\fR'' does not always produce the
-same result as ``\fBlindex \fIlist first\fR'' (although it often does
-for simple fields that aren't enclosed in braces); it does, however,
-produce exactly the same results as ``\fBlist [lindex \fIlist first\fB]\fR''
+Note:
+.QW "\fBlrange \fIlist first first\fR"
+does not always produce the same result as
+.QW "\fBlindex \fIlist first\fR"
+(although it often does for simple fields that are not enclosed in
+braces); it does, however, produce exactly the same results as
+.QW "\fBlist [lindex \fIlist first\fB]\fR"
.SH EXAMPLES
Selecting the first two elements:
.CS
@@ -64,9 +70,10 @@ elements to
.CE
.SH "SEE ALSO"
-.VS 8.4
list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n),
-lset(n), lreplace(n), lsort(n)
+lset(n), lreplace(n), lsort(n),
+.VS 8.5
+string(n)
.VE
.SH KEYWORDS
diff --git a/doc/lrepeat.n b/doc/lrepeat.n
new file mode 100644
index 0000000..ac78690
--- /dev/null
+++ b/doc/lrepeat.n
@@ -0,0 +1,39 @@
+'\"
+'\" Copyright (c) 2003 by Simon Geard. All rights reserved.
+'\"
+'\" 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"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+lrepeat \- Build a list by repeating elements
+.SH SYNOPSIS
+\fBlrepeat \fInumber element1 \fR?\fIelement2 element3 ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The \fBlrepeat\fR command creates a list of size \fInumber * number of
+elements\fR by repeating \fInumber\fR times the sequence of elements
+\fIelement1 element2 ...\fR. \fInumber\fR must be a positive integer,
+\fIelementn\fR can be any Tcl value. Note that \fBlrepeat 1 arg ...\fR
+is identical to \fBlist arg ...\fR, though the \fIarg\fR is required
+with \fBlrepeat\fR.
+.SH EXAMPLES
+.CS
+\fBlrepeat\fR 3 a
+ \fI\(-> a a a\fR
+\fBlrepeat\fR 3 [\fBlrepeat\fR 3 0]
+ \fI\(-> {0 0 0} {0 0 0} {0 0 0}\fR
+\fBlrepeat\fR 3 a b c
+ \fI\(-> a b c a b c a b c\fR
+\fBlrepeat\fR 3 [\fBlrepeat\fR 2 a] b c
+ \fI\(-> {a a} b c {a a} b c {a a} b c\fR
+.CE
+.SH "SEE ALSO"
+list(n), lappend(n), linsert(n), llength(n), lset(n)
+
+.SH KEYWORDS
+element, index, list
diff --git a/doc/lreplace.n b/doc/lreplace.n
index 600a986..2cd79d8 100644
--- a/doc/lreplace.n
+++ b/doc/lreplace.n
@@ -1,7 +1,7 @@
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
-'\" Copyright (c) 2001 Kevin B. Kenny. All rights reserved.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -15,26 +15,31 @@ lreplace \- Replace elements in a list with new elements
.SH SYNOPSIS
\fBlreplace \fIlist first last \fR?\fIelement element ...\fR?
.BE
-
.SH DESCRIPTION
.PP
\fBlreplace\fR returns a new list formed by replacing one or more elements of
\fIlist\fR with the \fIelement\fR arguments.
-\fIfirst\fR and \fIlast\fR specify the first and last index of the
-range of elements to replace. 0 refers to the first element of the
-list, and \fBend\fR (or any abbreviation of it) may be used to refer
-to the last element of the list. If \fIlist\fR is empty, then
-\fIfirst\fR and \fIlast\fR are ignored.
-
-If \fIfirst\fR is less than zero, it is considered to refer to the
+.VS 8.5
+\fIfirst\fR and \fIlast\fR are index values specifying the first and
+last elements of the range to replace.
+The index values \fIfirst\fR and \fIlast\fR are interpreted
+the same as index values for the command \fBstring index\fR,
+supporting simple index arithmetic and indices relative to the
+end of the list.
+0 refers to the first element of the
+list, and \fBend\fR refers to the last element of the list.
+If \fIlist\fR is empty, then \fIfirst\fR and \fIlast\fR are ignored.
+.VE
+.PP
+If \fIfirst\fR is less than zero, it is considered to refer to before the
first element of the list. For non-empty lists, the element indicated
-by \fIfirst\fR must exist.
-
-If \fIlast\fR is less than zero but greater than \fIfirst\fR, then any
-specified elements will be prepended to the list. If \fIlast\fR is
-less than \fIfirst\fR then no elements are deleted; the new elements
-are simply inserted before \fIfirst\fR.
-
+by \fIfirst\fR must exist or \fIfirst\fR must indicate before the
+start of the list.
+.PP
+If \fIlast\fR is less than \fIfirst\fR, then any specified elements
+will be inserted into the list at the point specified by \fIfirst\fR
+with no elements being deleted.
+.PP
The \fIelement\fR arguments specify zero or more new arguments to
be added to the list in place of those that were deleted.
Each \fIelement\fR argument will become a separate element of
@@ -61,12 +66,20 @@ a b c d e
% set var [\fBlreplace\fR $var end end]
a b c d
.CE
-
+.PP
+A procedure to delete a given element from a list:
+.CS
+proc lremove {listVariable value} {
+ upvar 1 $listVariable var
+ set idx [lsearch -exact $var $value]
+ set var [\fBlreplace\fR $var $idx $idx]
+}
+.CE
.SH "SEE ALSO"
-.VS 8.4
-list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n),
-lset(n), lrange(n), lsort(n)
+list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n),
+lset(n), lrange(n), lsort(n),
+.VS 8.5
+string(n)
.VE
-
.SH KEYWORDS
element, list, replace
diff --git a/doc/lreverse.n b/doc/lreverse.n
new file mode 100644
index 0000000..da5e489
--- /dev/null
+++ b/doc/lreverse.n
@@ -0,0 +1,31 @@
+'\" -*- nroff -*-
+'\" Copyright (c) 2006 by Donal K. Fellows. All rights reserved.
+'\"
+'\" 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"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+lreverse \- Reverse the order of a list
+.SH SYNOPSIS
+\fBlreverse \fIlist\fR
+.BE
+.SH DESCRIPTION
+.PP
+The \fBlreverse\fR command returns a list that has the same elements as its
+input list, \fIlist\fR, except with the elements in the reverse order.
+.SH EXAMPLES
+.CS
+\fBlreverse\fR {a a b c}
+ \fI\(-> c b a a\fR
+\fBlreverse\fR {a b {c d} e f}
+ \fI\(-> f e {c d} b a\fR
+.CE
+.SH "SEE ALSO"
+list(n), lsearch(n), lsort(n)
+
+.SH KEYWORDS
+element, list, reverse
diff --git a/doc/lsearch.n b/doc/lsearch.n
index 37362fa..b046ba2 100644
--- a/doc/lsearch.n
+++ b/doc/lsearch.n
@@ -1,13 +1,14 @@
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
-'\" Copyright (c) 2001 Kevin B. Kenny. All rights reserved.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+'\" Copyright (c) 2003-2004 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 lsearch n 8.4 Tcl "Tcl Built-In Commands"
+.TH lsearch n 8.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -21,121 +22,169 @@ lsearch \- See if a list contains a particular element
This command searches the elements of \fIlist\fR to see if one
of them matches \fIpattern\fR. If so, the command returns the index
of the first matching element
-.VS 8.4
(unless the options \fB\-all\fR or \fB\-inline\fR are specified.)
-.VE 8.4
If not, the command returns \fB\-1\fR. The \fIoption\fR arguments
indicates how the elements of the list are to be matched against
-\fIpattern\fR and it must have one of the following values:
-.TP
-\fB\-all\fR
-.VS 8.4
-Changes the result to be the list of all matching indices (or all
-matching values if \fB\-inline\fR is specified as well.)
-.VE 8.4
-.TP
-\fB\-ascii\fR
-The list elements are to be examined as Unicode strings (the name is
-for backward-compatability reasons.) This option is only meaningful
-when used with \fB\-exact\fR or \fB\-sorted\fR.
-.TP
-\fB\-decreasing\fR
-The list elements are sorted in decreasing order. This option is only
-meaningful when used with \fB\-sorted\fR.
-.TP
-\fB\-dictionary\fR
-The list elements are to be compared using dictionary-style
-comparisons (see \fBlsort\fR for a fuller description). This option
-is only meaningful when used with \fB\-exact\fR or \fB\-sorted\fR, and
-it is only distinguishable from the \fB\-ascii\fR option when
-the \fB\-sorted\fR option is given, because values are only
-dictionary-equal when exactly equal.
+\fIpattern\fR and must have one of the values below:
+.SS "MATCHING STYLE OPTIONS"
+If all matching style options are omitted, the default matching style
+is \fB\-glob\fR. If more than one matching style is specified, the
+last matching style given takes precedence.
.TP
\fB\-exact\fR
-The list element must contain exactly the same string as \fIpattern\fR.
+\fIPattern\fR is a literal string that is compared for exact equality
+against each list element.
.TP
\fB\-glob\fR
\fIPattern\fR is a glob-style pattern which is matched against each list
element using the same rules as the \fBstring match\fR command.
.TP
-\fB\-increasing\fR
-The list elements are sorted in increasing order. This option is only
-meaningful when used with \fB\-sorted\fR.
+\fB\-regexp\fR
+\fIPattern\fR is treated as a regular expression and matched against
+each list element using the rules described in the \fBre_syntax\fR
+reference page.
+.TP
+\fB\-sorted\fR
+The list elements are in sorted order. If this option is specified,
+\fBlsearch\fR will use a more efficient searching algorithm to search
+\fIlist\fR. If no other options are specified, \fIlist\fR is assumed
+to be sorted in increasing order, and to contain ASCII strings. This
+option is mutually exclusive with \fB\-glob\fR and \fB\-regexp\fR, and
+is treated exactly like \fB\-exact\fR when either \fB\-all\fR or
+\fB\-not\fR are specified.
+.SS "GENERAL MODIFIER OPTIONS"
+These options may be given with all matching styles.
+.TP
+\fB\-all\fR
+.
+Changes the result to be the list of all matching indices (or all matching
+values if \fB\-inline\fR is specified as well.) If indices are returned, the
+indices will be in numeric order. If values are returned, the order of the
+values will be the order of those values within the input \fIlist\fR.
.TP
\fB\-inline\fR
-.VS 8.4
The matching value is returned instead of its index (or an empty
string if no value matches.) If \fB\-all\fR is also specified, then
the result of the command is the list of all values that matched.
-.VE 8.4
-.TP
-\fB\-integer\fR
-The list elements are to be compared as integers. This option is only
-meaningful when used with \fB\-exact\fR or \fB\-sorted\fR.
.TP
\fB\-not\fR
-.VS 8.4
This negates the sense of the match, returning the index of the first
non-matching value in the list.
-.VE 8.4
+.TP
+\fB\-start\fR\0\fIindex\fR
+The list is searched starting at position \fIindex\fR.
+.VS 8.5
+The interpretation of the \fIindex\fR value is the same as
+for the command \fBstring index\fR, supporting simple index
+arithmetic and indices relative to the end of the list.
+.VE 8.5
+.SS "CONTENTS DESCRIPTION OPTIONS"
+These options describe how to interpret the items in the list being
+searched. They are only meaningful when used with the \fB\-exact\fR
+and \fB\-sorted\fR options. If more than one is specified, the last
+one takes precedence. The default is \fB\-ascii\fR.
+.TP
+\fB\-ascii\fR
+The list elements are to be examined as Unicode strings (the name is
+for backward-compatibility reasons.)
+.TP
+\fB\-dictionary\fR
+The list elements are to be compared using dictionary-style
+comparisons (see \fBlsort\fR for a fuller description). Note that this
+only makes a meaningful difference from the \fB\-ascii\fR option when
+the \fB\-sorted\fR option is given, because values are only
+dictionary-equal when exactly equal.
+.TP
+\fB\-integer\fR
+The list elements are to be compared as integers.
+.VS 8.5
+.TP
+\fB\-nocase\fR
+Causes comparisons to be handled in a case-insensitive manner. Has no
+effect if combined with the \fB\-dictionary\fR, \fB\-integer\fR, or
+\fB\-real\fR options.
+.VE 8.5
.TP
\fB\-real\fR
-The list elements are to be compared as floating-point values. This
-option is only meaningful when used with \fB\-exact\fR or \fB\-sorted\fR.
+The list elements are to be compared as floating-point values.
+.SS "SORTED LIST OPTIONS"
+These options (only meaningful with the \fB\-sorted\fR option) specify
+how the list is sorted. If more than one is given, the last one takes
+precedence. The default option is \fB\-increasing\fR.
.TP
-\fB\-regexp\fR
-\fIPattern\fR is treated as a regular expression and matched against
-each list element using the rules described in the \fBre_syntax\fR
-reference page.
+\fB\-decreasing\fR
+The list elements are sorted in decreasing order. This option is only
+meaningful when used with \fB\-sorted\fR.
.TP
-\fB\-sorted\fR
-The list elements are in sorted order. If this option is specified,
-\fBlsearch\fR will use a more efficient searching algorithm to search
-\fIlist\fR. If no other options are specified, \fIlist\fR is assumed
-to be sorted in increasing order, and to contain ASCII strings. This
-option is mutually exclusive with \fB\-glob\fR and \fB\-regexp\fR, and
-is treated exactly like \fB-exact\fR when either \fB\-all\fR, or
-\fB\-not\fR is specified.
-.TP
-\fB\-start\fR \fIindex\fR
-.VS 8.4
-The list is searched starting at position \fIindex\fR. If \fIindex\fR
-has the value \fBend\fR, it refers to the last element in the list,
-and \fBend\-\fIinteger\fR refers to the last element in the list minus
-the specified integer offset.
-.VE 8.4
-.PP
-If \fIoption\fR is omitted then it defaults to \fB\-glob\fR. If more
-than one of \fB\-exact\fR, \fB\-glob\fR, \fB\-regexp\fR, and
-\fB\-sorted\fR is specified, whichever option is specified last takes
-precedence. If more than one of \fB\-ascii\fR, \fB\-dictionary\fR,
-\fB\-integer\fR and \fB\-real\fR is specified, the option specified
-last takes precedence. If more than one of \fB\-increasing\fR and
-\fB\-decreasing\fR is specified, the option specified last takes
-precedence.
-
-.VS 8.4
+\fB\-increasing\fR
+The list elements are sorted in increasing order. This option is only
+meaningful when used with \fB\-sorted\fR.
+.SS "NESTED LIST OPTIONS"
+.VS 8.5
+These options are used to search lists of lists. They may be used
+with any other options.
+.TP
+\fB\-index\fR\0\fIindexList\fR
+This option is designed for use when searching within nested lists.
+The \fIindexList\fR argument gives a path of indices (much as might be
+used with the \fBlindex\fR or \fBlset\fR commands) within each element
+to allow the location of the term being matched against.
+.TP
+\fB\-subindices\fR
+If this option is given, the index result from this command (or every
+index result when \fB\-all\fR is also specified) will be a complete
+path (suitable for use with \fBlindex\fR or \fBlset\fR) within the
+overall list to the term found. This option has no effect unless the
+\fI\-index\fR is also specified, and is just a convenience short-cut.
+.VE 8.5
.SH EXAMPLES
+Basic searching:
.CS
-\fBlsearch\fR {a b c d e} c \fI=> 2\fR
-\fBlsearch\fR -all {a b c a b c} c \fI=> 2 5\fR
-\fBlsearch\fR -inline {a20 b35 c47} b* \fI=> b35\fR
-\fBlsearch\fR -inline -not {a20 b35 c47} b* \fI=> a20\fR
-\fBlsearch\fR -all -inline -not {a20 b35 c47} b* \fI=> a20 c47\fR
-\fBlsearch\fR -all -not {a20 b35 c47} b* \fI=> 0 2\fR
-\fBlsearch\fR -start 3 {a b c a b c} c \fI=> 5\fR
+\fBlsearch\fR {a b c d e} c
+ \fI\(-> 2\fR
+\fBlsearch\fR -all {a b c a b c} c
+ \fI\(-> 2 5\fR
+.CE
+.PP
+Using \fBlsearch\fR to filter lists:
+.CS
+\fBlsearch\fR -inline {a20 b35 c47} b*
+ \fI\(-> b35\fR
+\fBlsearch\fR -inline -not {a20 b35 c47} b*
+ \fI\(-> a20\fR
+\fBlsearch\fR -all -inline -not {a20 b35 c47} b*
+ \fI\(-> a20 c47\fR
+\fBlsearch\fR -all -not {a20 b35 c47} b*
+ \fI\(-> 0 2\fR
+.CE
+.PP
+This can even do a
+.QW set-like
+removal operation:
+.CS
+\fBlsearch\fR -all -inline -not -exact {a b c a d e a f g a} a
+ \fI\(-> b c d e f g\fR
+.CE
+.PP
+Searching may start part-way through the list:
+.CS
+\fBlsearch\fR -start 3 {a b c a b c} c
+ \fI\(-> 5\fR
+.CE
+.PP
+It is also possible to search inside elements:
+.CS
+\fBlsearch\fR -index 1 -all -inline {{a abc} {b bcd} {c cde}} *bc*
+ \fI\(-> {a abc} {b bcd}\fR
.CE
-.VE 8.4
-
.SH "SEE ALSO"
-.VS 8.4
foreach(n), list(n), lappend(n), lindex(n), linsert(n), llength(n),
-lset(n), lsort(n), lrange(n), lreplace(n)
+lset(n), lsort(n), lrange(n), lreplace(n),
+.VS 8.5
+string(n)
.VE
-
.SH KEYWORDS
list, match, pattern, regular expression, search, string
-
'\" Local Variables:
'\" mode: nroff
'\" End:
diff --git a/doc/lset.n b/doc/lset.n
index 81ee225..5efcbae 100755..100644
--- a/doc/lset.n
+++ b/doc/lset.n
@@ -1,5 +1,5 @@
'\"
-'\" Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
+'\" Copyright (c) 2001 by Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -50,9 +50,11 @@ command.
If \fIindex\fR is negative or greater than or equal to the number
of elements in \fI$varName\fR, then an error occurs.
.PP
-If \fIindex\fR has the value \fBend\fR, it refers to the last element
-in the list, and \fBend\-\fIinteger\fR refers to the last element in
-the list minus the specified integer offset.
+.VS 8.5
+The interpretation of each simple \fIindex\fR value is the same as
+for the command \fBstring index\fR, supporting simple index
+arithmetic and indices relative to the end of the list.
+.VE 8.5
.PP
If additional \fIindex\fR arguments are supplied, then each argument is
used in turn to address an element within a sublist designated
@@ -76,36 +78,51 @@ of a list. If an index is outside the permitted range, an error is reported.
In each of these examples, the initial value of \fIx\fR is:
.CS
set x [list [list a b c] [list d e f] [list g h i]]
- => {a b c} {d e f} {g h i}
+ \fI\(-> {a b c} {d e f} {g h i}\fR
.CE
The indicated return value also becomes the new value of \fIx\fR
(except in the last case, which is an error which leaves the value of
\fIx\fR unchanged.)
.CS
-lset x {j k l} => j k l
-lset x {} {j k l} => j k l
-lset x 0 j => j {d e f} {g h i}
-lset x 2 j => {a b c} {d e f} j
-lset x end j => {a b c} {d e f} j
-lset x end-1 j => {a b c} j {g h i}
-lset x 2 1 j => {a b c} {d e f} {g j i}
-lset x {2 1} j => {a b c} {d e f} {g j i}
-lset x {2 3} j => \fIlist index out of range\fR
+\fBlset\fR x {j k l}
+ \fI\(-> j k l\fR
+\fBlset\fR x {} {j k l}
+ \fI\(-> j k l\fR
+\fBlset\fR x 0 j
+ \fI\(-> j {d e f} {g h i}\fR
+\fBlset\fR x 2 j
+ \fI\(-> {a b c} {d e f} j\fR
+\fBlset\fR x end j
+ \fI\(-> {a b c} {d e f} j\fR
+\fBlset\fR x end-1 j
+ \fI\(-> {a b c} j {g h i}\fR
+\fBlset\fR x 2 1 j
+ \fI\(-> {a b c} {d e f} {g j i}\fR
+\fBlset\fR x {2 1} j
+ \fI\(-> {a b c} {d e f} {g j i}\fR
+\fBlset\fR x {2 3} j
+ \fI\(-> list index out of range\fR
.CE
In the following examples, the initial value of \fIx\fR is:
.CS
set x [list [list [list a b] [list c d]] \e
[list [list e f] [list g h]]]
- => {{a b} {c d}} {{e f} {g h}}
+ \fI\(-> {{a b} {c d}} {{e f} {g h}}\fR
.CE
The indicated return value also becomes the new value of \fIx\fR.
.CS
-lset x 1 1 0 j => {{a b} {c d}} {{e f} {j h}}
-lset x {1 1 0} j => {{a b} {c d}} {{e f} {j h}}
+\fBlset\fR x 1 1 0 j
+ \fI\(-> {{a b} {c d}} {{e f} {j h}}\fR
+\fBlset\fR x {1 1 0} j
+ \fI\(-> {{a b} {c d}} {{e f} {j h}}\fR
.CE
.SH "SEE ALSO"
list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n),
-lsort(n), lrange(n), lreplace(n)
+lsort(n), lrange(n), lreplace(n),
+.VS 8.5
+string(n)
+.VE
+
.SH KEYWORDS
element, index, list, replace, set
diff --git a/doc/lsort.n b/doc/lsort.n
index fa8cdd7..1726e92 100644
--- a/doc/lsort.n
+++ b/doc/lsort.n
@@ -2,13 +2,13 @@
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\" Copyright (c) 1999 Scriptics Corporation
-'\" Copyright (c) 2001 Kevin B. Kenny. All rights reserved.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
'\"
'\" 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.3 Tcl "Tcl Built-In Commands"
+.TH lsort n 8.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -57,47 +57,72 @@ be considered less than, equal to, or greater than the second,
respectively.
.TP 20
\fB\-increasing\fR
-Sort the list in increasing order (``smallest'' items first).
+Sort the list in increasing order
+.PQ smallest "items first" .
This is the default.
.TP 20
\fB\-decreasing\fR
-Sort the list in decreasing order (``largest'' items first).
+Sort the list in decreasing order
+.PQ largest "items first" .
.TP 20
-\fB\-index\0\fIindex\fR
+\fB\-indices\fR
+.VS "8.5 (TIP#217)"
+Return a list of indices into \fIlist\fR in sorted order instead of
+the values themselves.
+.VE "8.5 (TIP#217)"
+.TP 20
+\fB\-index\0\fIindexList\fR
If this option is specified, each of the elements of \fIlist\fR must
itself be a proper Tcl sublist. Instead of sorting based on whole
-sublists, \fBlsort\fR will extract the \fIindex\fR'th element from
-each sublist and sort based on the given element. The keyword
-\fBend\fP is allowed for the \fIindex\fP to sort on the last sublist
-element,
-.VS 8.4
-and \fBend-\fIindex\fR sorts on a sublist element offset from
-the end.
-.VE
+sublists, \fBlsort\fR will extract the \fIindexList\fR'th element from
+each sublist
+.VS 8.5
+(as if the overall element and the \fIindexList\fR were passed to
+\fBlindex\fR) and sort based on the given element.
+.VE 8.5
For example,
.RS
.CS
-lsort -integer -index 1 {{First 24} {Second 18} {Third 30}}
+lsort -integer -index 1 \e
+ {{First 24} {Second 18} {Third 30}}
.CE
returns \fB{Second 18} {First 24} {Third 30}\fR, and
-.VS 8.4
'\"
'\" This example is from the test suite!
'\"
.CS
-lsort -index end-1 {{a 1 e i} {b 2 3 f g} {c 4 5 6 d h}}
+lsort -index end-1 \e
+ {{a 1 e i} {b 2 3 f g} {c 4 5 6 d h}}
.CE
-returns \fB{c 4 5 6 d h} {a 1 e i} {b 2 3 f g}\fR.
-.VE
+returns \fB{c 4 5 6 d h} {a 1 e i} {b 2 3 f g}\fR,
+.VS 8.5
+and
+.CS
+lsort -index {0 1} {
+ {{b i g} 12345}
+ {{d e m o} 34512}
+ {{c o d e} 54321}
+}
+.CE
+returns \fB{{d e m o} 34512} {{b i g} 12345} {{c o d e} 54321}\fR
+(because \fBe\fR sorts before \fBi\fR which sorts before \fBo\fR.)
+.VE 8.5
This option is much more efficient than using \fB\-command\fR
to achieve the same effect.
.RE
+.VS 8.5
+.TP 20
+\fB\-nocase\fR
+Causes comparisons to be handled in a case-insensitive manner. Has no
+effect if combined with the \fB\-dictionary\fR, \fB\-integer\fR, or
+\fB\-real\fR options.
+.VE 8.5
.TP 20
\fB\-unique\fR
If this option is specified, then only the last set of duplicate
elements found in the list will be retained. Note that duplicates are
determined relative to the comparison used in the sort. Thus if
-\fI-index 0\fR is used, \fB{1 a}\fR and \fB{1 b}\fR would be
+\fI\-index 0\fR is used, \fB{1 a}\fR and \fB{1 b}\fR would be
considered duplicates and only the second element, \fB{1 b}\fR, would
be retained.
.SH "NOTES"
@@ -169,16 +194,14 @@ More complex sorting using a comparison function:
}
return [string compare [lindex $a 1] [lindex $b 1]]
}
-% \fBlsort\fR -command compare \\
+% \fBlsort\fR -command compare \e
{{3 apple} {0x2 carrot} {1 dingo} {2 banana}}
{1 dingo} {2 banana} {0x2 carrot} {3 apple}
.CE
.SH "SEE ALSO"
-.VS 8.4
list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n),
lset(n), lrange(n), lreplace(n)
-.VE
.SH KEYWORDS
element, list, order, sort
diff --git a/doc/man.macros b/doc/man.macros
index 5d0c6fa..ddd073d 100644
--- a/doc/man.macros
+++ b/doc/man.macros
@@ -1,69 +1,77 @@
-'\" The definitions below are for supplemental macros used in Tcl/Tk
-'\" manual entries.
-'\"
-'\" .AP type name in/out ?indent?
-'\" Start paragraph describing an argument to a library procedure.
-'\" type is type of argument (int, etc.), in/out is either "in", "out",
-'\" or "in/out" to describe whether procedure reads or modifies arg,
-'\" and indent is equivalent to second arg of .IP (shouldn't ever be
-'\" needed; use .AS below instead)
-'\"
-'\" .AS ?type? ?name?
-'\" Give maximum sizes of arguments for setting tab stops. Type and
-'\" name are examples of largest possible arguments that will be passed
-'\" to .AP later. If args are omitted, default tab stops are used.
-'\"
-'\" .BS
-'\" Start box enclosure. From here until next .BE, everything will be
-'\" enclosed in one large box.
-'\"
-'\" .BE
-'\" End of box enclosure.
-'\"
-'\" .CS
-'\" Begin code excerpt.
-'\"
-'\" .CE
-'\" End code excerpt.
-'\"
-'\" .VS ?version? ?br?
-'\" Begin vertical sidebar, for use in marking newly-changed parts
-'\" of man pages. The first argument is ignored and used for recording
-'\" the version when the .VS was added, so that the sidebars can be
-'\" found and removed when they reach a certain age. If another argument
-'\" is present, then a line break is forced before starting the sidebar.
-'\"
-'\" .VE
-'\" End of vertical sidebar.
-'\"
-'\" .DS
-'\" Begin an indented unfilled display.
-'\"
-'\" .DE
-'\" End of indented unfilled display.
-'\"
-'\" .SO
-'\" Start of list of standard options for a Tk widget. The
-'\" options follow on successive lines, in four columns separated
-'\" by tabs.
-'\"
-'\" .SE
-'\" End of list of standard options for a Tk widget.
-'\"
-'\" .OP cmdName dbName dbClass
-'\" Start of description of a specific option. cmdName gives the
-'\" option's name as specified in the class command, dbName gives
-'\" the option's name in the option database, and dbClass gives
-'\" the option's class in the option database.
-'\"
-'\" .UL arg1 arg2
-'\" Print arg1 underlined, then print arg2 normally.
-'\"
-'\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
+.\" The -*- nroff -*- definitions below are for supplemental macros used
+.\" in Tcl/Tk manual entries.
+.\"
+.\" .AP type name in/out ?indent?
+.\" Start paragraph describing an argument to a library procedure.
+.\" type is type of argument (int, etc.), in/out is either "in", "out",
+.\" or "in/out" to describe whether procedure reads or modifies arg,
+.\" and indent is equivalent to second arg of .IP (shouldn't ever be
+.\" needed; use .AS below instead)
+.\"
+.\" .AS ?type? ?name?
+.\" Give maximum sizes of arguments for setting tab stops. Type and
+.\" name are examples of largest possible arguments that will be passed
+.\" to .AP later. If args are omitted, default tab stops are used.
+.\"
+.\" .BS
+.\" Start box enclosure. From here until next .BE, everything will be
+.\" enclosed in one large box.
+.\"
+.\" .BE
+.\" End of box enclosure.
+.\"
+.\" .CS
+.\" Begin code excerpt.
+.\"
+.\" .CE
+.\" End code excerpt.
+.\"
+.\" .VS ?version? ?br?
+.\" Begin vertical sidebar, for use in marking newly-changed parts
+.\" of man pages. The first argument is ignored and used for recording
+.\" the version when the .VS was added, so that the sidebars can be
+.\" found and removed when they reach a certain age. If another argument
+.\" is present, then a line break is forced before starting the sidebar.
+.\"
+.\" .VE
+.\" End of vertical sidebar.
+.\"
+.\" .DS
+.\" Begin an indented unfilled display.
+.\"
+.\" .DE
+.\" End of indented unfilled display.
+.\"
+.\" .SO ?manpage?
+.\" Start of list of standard options for a Tk widget. The manpage
+.\" argument defines where to look up the standard options; if
+.\" omitted, defaults to "options". The options follow on successive
+.\" lines, in three columns separated by tabs.
+.\"
+.\" .SE
+.\" End of list of standard options for a Tk widget.
+.\"
+.\" .OP cmdName dbName dbClass
+.\" Start of description of a specific option. cmdName gives the
+.\" option's name as specified in the class command, dbName gives
+.\" the option's name in the option database, and dbClass gives
+.\" the option's class in the option database.
+.\"
+.\" .UL arg1 arg2
+.\" Print arg1 underlined, then print arg2 normally.
+.\"
+.\" .QW arg1 ?arg2?
+.\" Print arg1 in quotes, then arg2 normally (for trailing punctuation).
+.\"
+.\" .PQ arg1 ?arg2?
+.\" Print an open parenthesis, arg1 in quotes, then arg2 normally
+.\" (for trailing punctuation) and then a closing parenthesis.
+.\"
+.\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
.if t .wh -1.3i ^B
.nr ^l \n(.l
.ad b
-'\" # Start an argument description
+.\" # Start an argument description
.de AP
.ie !"\\$4"" .TP \\$4
.el \{\
@@ -72,7 +80,7 @@
.\}
.ta \\n()Au \\n()Bu
.ie !"\\$3"" \{\
-\&\\$1 \\fI\\$2\\fP (\\$3)
+\&\\$1 \\fI\\$2\\fP (\\$3)
.\".b
.\}
.el \{\
@@ -85,7 +93,7 @@
.\}
.\}
..
-'\" # define tabbing values for .AP
+.\" # define tabbing values for .AP
.de AS
.nr )A 10n
.if !"\\$1"" .nr )A \\w'\\$1'u+3n
@@ -95,9 +103,9 @@
.nr )C \\n()Bu+\\w'(in/out)'u+2n
..
.AS Tcl_Interp Tcl_CreateInterp in/out
-'\" # BS - start boxed text
-'\" # ^y = starting y location
-'\" # ^b = 1
+.\" # BS - start boxed text
+.\" # ^y = starting y location
+.\" # ^b = 1
.de BS
.br
.mk ^y
@@ -107,7 +115,7 @@
.if n \l'\\n(.lu\(ul'
.if n .fi
..
-'\" # BE - end boxed text (draw box now)
+.\" # BE - end boxed text (draw box now)
.de BE
.nf
.ti 0
@@ -127,16 +135,16 @@
.br
.nr ^b 0
..
-'\" # VS - start vertical sidebar
-'\" # ^Y = starting y location
-'\" # ^v = 1 (for troff; for nroff this doesn't matter)
+.\" # VS - start vertical sidebar
+.\" # ^Y = starting y location
+.\" # ^v = 1 (for troff; for nroff this doesn't matter)
.de VS
.if !"\\$2"" .br
.mk ^Y
.ie n 'mc \s12\(br\s0
.el .nr ^v 1u
..
-'\" # VE - end of vertical sidebar
+.\" # VE - end of vertical sidebar
.de VE
.ie n 'mc
.el \{\
@@ -151,9 +159,9 @@
.\}
.nr ^v 0
..
-'\" # Special macro to handle page bottom: finish off current
-'\" # box/sidebar if in box/sidebar mode, then invoked standard
-'\" # page bottom macro.
+.\" # Special macro to handle page bottom: finish off current
+.\" # box/sidebar if in box/sidebar mode, then invoked standard
+.\" # page bottom macro.
.de ^B
.ev 2
'ti 0
@@ -180,34 +188,36 @@
.mk ^Y
.\}
..
-'\" # DS - begin display
+.\" # DS - begin display
.de DS
.RS
.nf
.sp
..
-'\" # DE - end display
+.\" # DE - end display
.de DE
.fi
.RE
.sp
..
-'\" # SO - start of list of standard options
+.\" # SO - start of list of standard options
.de SO
+'ie '\\$1'' .ds So \\fBoptions\\fR
+'el .ds So \\fB\\$1\\fR
.SH "STANDARD OPTIONS"
.LP
.nf
.ta 5.5c 11c
.ft B
..
-'\" # SE - end of list of standard options
+.\" # SE - end of list of standard options
.de SE
.fi
.ft R
.LP
-See the \\fBoptions\\fR manual entry for details on the standard options.
+See the \\*(So manual entry for details on the standard options.
..
-'\" # OP - start of full description for a single option
+.\" # OP - start of full description for a single option
.de OP
.LP
.nf
@@ -218,17 +228,40 @@ Database Class: \\fB\\$3\\fR
.fi
.IP
..
-'\" # CS - begin code excerpt
+.\" # CS - begin code excerpt
.de CS
.RS
.nf
.ta .25i .5i .75i 1i
..
-'\" # CE - end code excerpt
+.\" # CE - end code excerpt
.de CE
.fi
.RE
..
+.\" # UL - underline word
.de UL
\\$1\l'|0\(ul'\\$2
..
+.\" # QW - apply quotation marks to word
+.de QW
+.ie '\\*(lq'"' ``\\$1''\\$2
+.\"" fix emacs highlighting
+.el \\*(lq\\$1\\*(rq\\$2
+..
+.\" # PQ - apply parens and quotation marks to word
+.de PQ
+.ie '\\*(lq'"' (``\\$1''\\$2)\\$3
+.\"" fix emacs highlighting
+.el (\\*(lq\\$1\\*(rq\\$2)\\$3
+..
+.\" # QR - quoted range
+.de QR
+.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3
+.\"" fix emacs highlighting
+.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3
+..
+.\" # MT - "empty" string
+.de MT
+.QW ""
+..
diff --git a/doc/mathfunc.n b/doc/mathfunc.n
new file mode 100644
index 0000000..4ba25e4
--- /dev/null
+++ b/doc/mathfunc.n
@@ -0,0 +1,271 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-2000 Sun Microsystems, Inc.
+'\" Copyright (c) 2005 by Kevin B. Kenny <kennykb@acm.org>. All rights reserved
+'\"
+'\" 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"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+mathfunc \- Mathematical functions for Tcl expressions
+.SH SYNOPSIS
+package require \fBTcl 8.5\fR
+.sp
+\fB::tcl::mathfunc::abs\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::acos\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::asin\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::atan\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::atan2\fR \fIy\fR \fIx\fR
+.br
+\fB::tcl::mathfunc::bool\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::ceil\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::cos\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::cosh\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::double\fR \fIarg\fR
+.br
+.VS 8.5
+\fB::tcl::mathfunc::entier\fR \fIarg\fR
+.br
+.VE 8.5
+\fB::tcl::mathfunc::exp\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::floor\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::fmod\fR \fIx\fR \fIy\fR
+.br
+\fB::tcl::mathfunc::hypot\fR \fIx\fR \fIy\fR
+.br
+\fB::tcl::mathfunc::int\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::isqrt\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::log\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::log10\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::max\fR \fIarg\fR ?\fIarg\fR ...?
+.br
+\fB::tcl::mathfunc::min\fR \fIarg\fR ?\fIarg\fR ...?
+.br
+\fB::tcl::mathfunc::pow\fR \fIx\fR \fIy\fR
+.br
+\fB::tcl::mathfunc::rand\fR
+.br
+\fB::tcl::mathfunc::round\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::sin\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::sinh\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::sqrt\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::srand\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::tan\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::tanh\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::wide\fR \fIarg\fR
+.sp
+.BE
+.SH "DESCRIPTION"
+.PP
+The \fBexpr\fR command handles mathematical functions of the form
+\fBsin($x)\fR or \fBatan2($y,$x)\fR by converting them to calls of the
+form \fB[tcl::mathfunc::sin [expr {$x}]]\fR or
+\fB[tcl::mathfunc::atan2 [expr {$y}] [expr {$x}]]\fR.
+A number of math functions are available by default within the
+namespace \fB::tcl::mathfunc\fR; these functions are also available
+for code apart from \fBexpr\fR, by invoking the given commands
+directly.
+.PP
+Tcl supports the following mathematical functions in expressions, all
+of which work solely with floating-point numbers unless otherwise noted:
+.DS
+.ta 3c 6c 9c
+\fBabs\fR \fBacos\fR \fBasin\fR \fBatan\fR
+\fBatan2\fR \fBbool\fR \fBceil\fR \fBcos\fR
+\fBcosh\fR \fBdouble\fR \fBentier\fR \fBexp\fR
+\fBfloor\fR \fBfmod\fR \fBhypot\fR \fBint\fR
+\fBisqrt\fR \fBlog\fR \fBlog10\fR \fBmax\fR
+\fBmin\fR \fBpow\fR \fBrand\fR \fBround\fR
+\fBsin\fR \fBsinh\fR \fBsqrt\fR \fBsrand\fR
+\fBtan\fR \fBtanh\fR \fBwide\fR
+.DE
+.PP
+In addition to these predefined functions, applications may
+define additional functions by using \fBproc\fR (or any other method,
+such as \fBinterp alias\fR or \fBTcl_CreateObjCommand\fR) to define
+new commands in the \fBtcl::mathfunc\fR namespace. In addition, an
+obsolete interface named \fBTcl_CreateMathFunc\fR() is available to
+extensions that are written in C. The latter interface is not recommended
+for new implementations.
+.SS "DETAILED DEFINITIONS"
+.TP
+\fBabs \fIarg\fR
+Returns the absolute value of \fIarg\fR. \fIArg\fR may be either
+integer or floating-point, and the result is returned in the same form.
+.TP
+\fBacos \fIarg\fR
+Returns the arc cosine of \fIarg\fR, in the range [\fI0\fR,\fIpi\fR]
+radians. \fIArg\fR should be in the range [\fI\-1\fR,\fI1\fR].
+.TP
+\fBasin \fIarg\fR
+Returns the arc sine of \fIarg\fR, in the range [\fI\-pi/2\fR,\fIpi/2\fR]
+radians. \fIArg\fR should be in the range [\fI\-1\fR,\fI1\fR].
+.TP
+\fBatan \fIarg\fR
+Returns the arc tangent of \fIarg\fR, in the range [\fI\-pi/2\fR,\fIpi/2\fR]
+radians.
+.TP
+\fBatan2 \fIy x\fR
+Returns the arc tangent of \fIy\fR/\fIx\fR, in the range [\fI\-pi\fR,\fIpi\fR]
+radians. \fIx\fR and \fIy\fR cannot both be 0. If \fIx\fR is greater
+than \fI0\fR, this is equivalent to
+.QW "\fBatan \fR[\fBexpr\fR {\fIy\fB/\fIx\fR}]" .
+.TP
+\fBbool \fIarg\fR
+Accepts any numeric value, or any string acceptable to
+\fBstring is boolean\fR, and returns the corresponding
+boolean value \fB0\fR or \fB1\fR. Non-zero numbers are true.
+Other numbers are false. Non-numeric strings produce boolean value in
+agreement with \fBstring is true\fR and \fBstring is false\fR.
+.TP
+\fBceil \fIarg\fR
+Returns the smallest integral floating-point value (i.e. with a zero
+fractional part) not less than \fIarg\fR. The argument may be any
+numeric value.
+.TP
+\fBcos \fIarg\fR
+Returns the cosine of \fIarg\fR, measured in radians.
+.TP
+\fBcosh \fIarg\fR
+Returns the hyperbolic cosine of \fIarg\fR. If the result would cause
+an overflow, an error is returned.
+.TP
+\fBdouble \fIarg\fR
+The argument may be any numeric value,
+If \fIarg\fR is a floating-point value, returns \fIarg\fR, otherwise converts
+\fIarg\fR to floating-point and returns the converted value. May return
+\fBInf\fR or \fB\-Inf\fR when the argument is a numeric value that exceeds
+the floating-point range.
+.TP
+\fBentier \fIarg\fR
+.VS 8.5
+The argument may be any numeric value. The integer part of \fIarg\fR
+is determined and returned. The integer range returned by this function
+is unlimited, unlike \fBint\fR and \fBwide\fR which
+truncate their range to fit in particular storage widths.
+.VE 8.5
+.TP
+\fBexp \fIarg\fR
+Returns the exponential of \fIarg\fR, defined as \fIe\fR**\fIarg\fR.
+If the result would cause an overflow, an error is returned.
+.TP
+\fBfloor \fIarg\fR
+Returns the largest integral floating-point value (i.e. with a zero
+fractional part) not greater than \fIarg\fR. The argument may be
+any numeric value.
+.TP
+\fBfmod \fIx y\fR
+Returns the floating-point remainder of the division of \fIx\fR by
+\fIy\fR. If \fIy\fR is 0, an error is returned.
+.TP
+\fBhypot \fIx y\fR
+Computes the length of the hypotenuse of a right-angled triangle
+.QW "\fBsqrt\fR [\fBexpr\fR {\fIx\fB*\fIx\fB+\fIy\fB*\fIy\fR}]".
+.TP
+\fBint \fIarg\fR
+The argument may be any numeric value. The integer part of \fIarg\fR
+is determined, and then the low order bits of that integer value up
+to the machine word size are returned as an integer value. For reference,
+the number of bytes in the machine word are stored in
+\fBtcl_platform(wordSize)\fR.
+.TP
+\fBisqrt \fIarg\fR
+Computes the integer part of the square root of \fIarg\fR. \fIArg\fR must be
+a positive value, either an integer or a floating point number.
+Unlike \fBsqrt\fR, which is limited to the precision of a floating point
+number, \fIisqrt\fR will return a result of arbitrary precision.
+.TP
+\fBlog \fIarg\fR
+Returns the natural logarithm of \fIarg\fR. \fIArg\fR must be a
+positive value.
+.TP
+\fBlog10 \fIarg\fR
+Returns the base 10 logarithm of \fIarg\fR. \fIArg\fR must be a
+positive value.
+.TP
+\fBmax \fIarg\fB \fI...\fR
+Accepts one or more numeric arguments. Returns the one argument
+with the greatest value.
+.TP
+\fBmin \fIarg\fB \fI...\fR
+Accepts one or more numeric arguments. Returns the one argument
+with the least value.
+.TP
+\fBpow \fIx y\fR
+Computes the value of \fIx\fR raised to the power \fIy\fR. If \fIx\fR
+is negative, \fIy\fR must be an integer value.
+.TP
+\fBrand\fR
+Returns a pseudo-random floating-point value in the range (\fI0\fR,\fI1\fR).
+The generator algorithm is a simple linear congruential generator that
+is not cryptographically secure. Each result from \fBrand\fR completely
+determines all future results from subsequent calls to \fBrand\fR, so
+\fBrand\fR should not be used to generate a sequence of secrets, such as
+one-time passwords. The seed of the generator is initialized from the
+internal clock of the machine or may be set with the \fBsrand\fR function.
+.TP
+\fBround \fIarg\fR
+If \fIarg\fR is an integer value, returns \fIarg\fR, otherwise converts
+\fIarg\fR to integer by rounding and returns the converted value.
+.TP
+\fBsin \fIarg\fR
+Returns the sine of \fIarg\fR, measured in radians.
+.TP
+\fBsinh \fIarg\fR
+Returns the hyperbolic sine of \fIarg\fR. If the result would cause
+an overflow, an error is returned.
+.TP
+\fBsqrt \fIarg\fR
+The argument may be any non-negative numeric value. Returns a floating-point
+value that is the square root of \fIarg\fR. May return \fBInf\fR when the
+argument is a numeric value that exceeds the square of the maximum value of
+the floating-point range.
+.TP
+\fBsrand \fIarg\fR
+The \fIarg\fR, which must be an integer, is used to reset the seed for
+the random number generator of \fBrand\fR. Returns the first random
+number (see \fBrand\fR) from that seed. Each interpreter has its own seed.
+.TP
+\fBtan \fIarg\fR
+Returns the tangent of \fIarg\fR, measured in radians.
+.TP
+\fBtanh \fIarg\fR
+Returns the hyperbolic tangent of \fIarg\fR.
+.TP
+\fBwide \fIarg\fR
+The argument may be any numeric value. The integer part of \fIarg\fR
+is determined, and then the low order 64 bits of that integer value
+are returned as an integer value.
+.SH "SEE ALSO"
+expr(n), mathop(n), namespace(n)
+.SH "COPYRIGHT"
+.nf
+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
diff --git a/doc/mathop.n b/doc/mathop.n
new file mode 100644
index 0000000..5a6ba4e
--- /dev/null
+++ b/doc/mathop.n
@@ -0,0 +1,299 @@
+.\" -*- nroff -*-
+.\" Copyright (c) 2006-2007 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 mathop n 8.5 Tcl "Tcl Mathematical Operator Commands"
+.BS
+.\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+mathop \- Mathematical operators as Tcl commands
+.SH SYNOPSIS
+package require \fBTcl 8.5\fR
+.sp
+\fB::tcl::mathop::!\fR \fInumber\fR
+.br
+\fB::tcl::mathop::~\fR \fInumber\fR
+.br
+\fB::tcl::mathop::+\fR ?\fInumber\fR ...?
+.br
+\fB::tcl::mathop::\-\fR \fInumber\fR ?\fInumber\fR ...?
+.br
+\fB::tcl::mathop::*\fR ?\fInumber\fR ...?
+.br
+\fB::tcl::mathop::/\fR \fInumber\fR ?\fInumber\fR ...?
+.br
+\fB::tcl::mathop::%\fR \fInumber number\fR
+.br
+\fB::tcl::mathop::**\fR ?\fInumber\fR ...?
+.br
+\fB::tcl::mathop::&\fR ?\fInumber\fR ...?
+.br
+\fB::tcl::mathop::|\fR ?\fInumber\fR ...?
+.br
+\fB::tcl::mathop::^\fR ?\fInumber\fR ...?
+.br
+\fB::tcl::mathop::<<\fR \fInumber number\fR
+.br
+\fB::tcl::mathop::>>\fR \fInumber number\fR
+.br
+\fB::tcl::mathop::==\fR ?\fIarg\fR ...?
+.br
+\fB::tcl::mathop::!=\fR \fIarg arg\fR
+.br
+\fB::tcl::mathop::<\fR ?\fIarg\fR ...?
+.br
+\fB::tcl::mathop::<=\fR ?\fIarg\fR ...?
+.br
+\fB::tcl::mathop::>=\fR ?\fIarg\fR ...?
+.br
+\fB::tcl::mathop::>\fR ?\fIarg\fR ...?
+.br
+\fB::tcl::mathop::eq\fR ?\fIarg\fR ...?
+.br
+\fB::tcl::mathop::ne\fR \fIarg arg\fR
+.br
+\fB::tcl::mathop::in\fR \fIarg list\fR
+.br
+\fB::tcl::mathop::ni\fR \fIarg list\fR
+.sp
+.BE
+.SH DESCRIPTION
+.PP
+The commands in the \fB::tcl::mathop\fR namespace implement the same set of
+operations as supported by the \fBexpr\fR command. All are exported from the
+namespace, but are not imported into any other namespace by default. Note that
+renaming, reimplementing or deleting any of the commands in the namespace does
+\fInot\fR alter the way that the \fBexpr\fR command behaves, and nor does
+defining any new commands in the \fB::tcl::mathop\fR namespace.
+.PP
+The following operator commands are supported:
+.DS
+.ta 2c 4c 6c 8c
+\fB~\fR \fB!\fR \fB+\fR \fB\-\fR \fB*\fR
+\fB/\fR \fB%\fR \fB**\fR \fB&\fR \fB|\fR
+\fB^\fR \fB>>\fR \fB<<\fR \fB==\fR \fBeq\fR
+\fB!=\fR \fBne\fR \fB<\fR \fB<=\fR \fB>\fR
+\fB>=\fR \fBin\fR \fBni\fR
+.DE
+.SS "MATHEMATICAL OPERATORS"
+.PP
+The behaviors of the mathematical operator commands are as follows:
+.TP
+\fB!\fR \fIboolean\fR
+.
+Returns the boolean negation of \fIboolean\fR, where \fIboolean\fR may be any
+numeric value or any other form of boolean value (i.e. it returns truth if the
+argument is falsity or zero, and falsity if the argument is truth or
+non-zero).
+.TP
+\fB+\fR ?\fInumber\fR ...?
+.
+Returns the sum of arbitrarily many arguments. Each \fInumber\fR argument may
+be any numeric value. If no arguments are given, the result will be zero (the
+summation identity).
+.TP
+\fB\-\fR \fInumber\fR ?\fInumber\fR ...?
+.
+If only a single \fInumber\fR argument is given, returns the negation of that
+numeric value. Otherwise returns the number that results when all subsequent
+numeric values are subtracted from the first one. All \fInumber\fR arguments
+must be numeric values. At least one argument must be given.
+.TP
+\fB*\fR ?\fInumber\fR ...?
+.
+Returns the product of arbitrarily many arguments. Each \fInumber\fR may be
+any numeric value. If no arguments are given, the result will be one (the
+multiplicative identity).
+.TP
+\fB/\fR \fInumber\fR ?\fInumber\fR ...?
+.
+If only a single \fInumber\fR argument is given, returns the reciprocal of that
+numeric value (i.e. the value obtained by dividing 1.0 by that value).
+Otherwise returns the number that results when the first numeric argument is
+divided by all subsequent numeric arguments. All \fInumber\fR arguments must
+be numeric values. At least one argument must be given.
+.RS
+.PP
+Note that when the leading values in the list of arguments are integers,
+integer division will be used for those initial steps (i.e. the intermediate
+results will be as if the functions \fIfloor\fR and \fIint\fR are applied to
+them, in that order). If all values in the operation are integers, the result
+will be an integer.
+.RE
+.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:
+.RS
+.CS
+(\fIx \fB/ \fIy\fR) \fB* \fIy \fB== \fIx \fB-\fR (\fIx \fB% \fIy\fR)
+.CE
+.RE
+.TP
+\fB**\fR ?\fInumber\fR ...?
+.
+Returns the result of raising each value to the power of the result of
+recursively operating on the result of processing the following arguments, so
+.QW "\fB** 2 3 4\fR"
+is the same as
+.QW "\fB** 2 [** 3 4]\fR" .
+Each \fInumber\fR may be
+any numeric value, though the second number must not be fractional if the
+first is negative. If no arguments are given, the result will be one, and if
+only one argument is given, the result will be that argument. The
+result will have an integral value only when all arguments are
+integral values.
+.SS "COMPARISON OPERATORS"
+.PP
+The behaviors of the comparison operator commands (most of which operate
+preferentially on numeric arguments) are as follows:
+.TP
+\fB==\fR ?\fIarg\fR ...?
+.
+Returns whether each argument is equal to the arguments on each side of it in
+the sense of the \fBexpr\fR == operator (\fIi.e.\fR, numeric comparison if
+possible, exact string comparison otherwise). If fewer than two arguments
+are given, this operation always returns a true value.
+.TP
+\fBeq\fR ?\fIarg\fR ...?
+.
+Returns whether each argument is equal to the arguments on each side of it
+using exact string comparison. If fewer than two arguments are given, this
+operation always returns a true value.
+.TP
+\fB!=\fR \fIarg arg\fR
+.
+Returns whether the two arguments are not equal to each other, in the sense of
+the \fBexpr\fR != operator (\fIi.e.\fR, numeric comparison if possible, exact
+string comparison otherwise).
+.TP
+\fBne\fR \fIarg arg\fR
+.
+Returns whether the two arguments are not equal to each other using exact
+string comparison.
+.TP
+\fB<\fR ?\fIarg\fR ...?
+.
+Returns whether the arbitrarily-many arguments are ordered, with each argument
+after the first having to be strictly more than the one preceding it.
+Comparisons are performed preferentially on the numeric values, and are
+otherwise performed using UNICODE string comparison. If fewer than two
+arguments are present, this operation always returns a true value. When the
+arguments are numeric but should be compared as strings, the \fBstring
+compare\fR command should be used instead.
+.TP
+\fB<=\fR ?\fIarg\fR ...?
+.
+Returns whether the arbitrarily-many arguments are ordered, with each argument
+after the first having to be equal to or more than the one preceding it.
+Comparisons are performed preferentially on the numeric values, and are
+otherwise performed using UNICODE string comparison. If fewer than two
+arguments are present, this operation always returns a true value. When the
+arguments are numeric but should be compared as strings, the \fBstring
+compare\fR command should be used instead.
+.TP
+\fB>\fR ?\fIarg\fR ...?
+.
+Returns whether the arbitrarily-many arguments are ordered, with each argument
+after the first having to be strictly less than the one preceding it.
+Comparisons are performed preferentially on the numeric values, and are
+otherwise performed using UNICODE string comparison. If fewer than two
+arguments are present, this operation always returns a true value. When the
+arguments are numeric but should be compared as strings, the \fBstring
+compare\fR command should be used instead.
+.TP
+\fB>=\fR ?\fIarg\fR ...?
+.
+Returns whether the arbitrarily-many arguments are ordered, with each argument
+after the first having to be equal to or less than the one preceding it.
+Comparisons are performed preferentially on the numeric values, and are
+otherwise performed using UNICODE string comparison. If fewer than two
+arguments are present, this operation always returns a true value. When the
+arguments are numeric but should be compared as strings, the \fBstring
+compare\fR command should be used instead.
+.SS "BIT-WISE OPERATORS"
+.PP
+The behaviors of the bit-wise operator commands (all of which only operate on
+integral arguments) are as follows:
+.TP
+\fB~\fR \fInumber\fR
+.
+Returns the bit-wise negation of \fInumber\fR. \fINumber\fR may be an integer
+of any size. Note that the result of this operation will always have the
+opposite sign to the input \fInumber\fR.
+.TP
+\fB&\fR ?\fInumber\fR ...?
+.
+Returns the bit-wise AND of each of the arbitrarily many arguments. Each
+\fInumber\fR must have an integral value. If no arguments are given, the
+result will be minus one.
+.TP
+\fB|\fR ?\fInumber\fR ...?
+.
+Returns the bit-wise OR of each of the arbitrarily many arguments. Each
+\fInumber\fR must have an integral value. If no arguments are given, the
+result will be zero.
+.TP
+\fB^\fR ?\fInumber\fR ...?
+.
+Returns the bit-wise XOR of each of the arbitrarily many arguments. Each
+\fInumber\fR must have an integral value. If no arguments are given, the
+result will be zero.
+.TP
+\fB<<\fR \fInumber number\fR
+.
+Returns the result of bit-wise shifting the first argument left by the
+number of bits specified in the second argument. Each \fInumber\fR
+must have an integral value.
+.TP
+\fB>>\fR \fInumber number\fR
+.
+Returns the result of bit-wise shifting the first argument right by
+the number of bits specified in the second argument. Each \fInumber\fR
+must have an integral value.
+.SS "LIST OPERATORS"
+.PP
+The behaviors of the list-oriented operator commands are as follows:
+.TP
+\fBin\fR \fIarg list\fR
+.
+Returns whether the value \fIarg\fR is present in the list \fIlist\fR
+(according to exact string comparison of elements).
+.TP
+\fBni\fR \fIarg list\fR
+.
+Returns whether the value \fIarg\fR is not present in the list \fIlist\fR
+(according to exact string comparison of elements).
+.SH EXAMPLES
+The simplest way to use the operators is often by using \fBnamespace path\fR
+to make the commands available. This has the advantage of not affecting the
+set of commands defined by the current namespace.
+.CS
+namespace path {\fB::tcl::mathop\fR ::tcl::mathfunc}
+
+\fI# Compute the sum of some numbers\fR
+set sum [\fB+\fR 1 2 3]
+
+\fI# Compute the average of a list\fR
+set list {1 2 3 4 5 6}
+set mean [\fB/\fR [\fB+\fR {*}$list] [double [llength $list]]]
+
+\fI# Test for list membership\fR
+set gotIt [\fBin\fR 3 $list]
+
+\fI# Test to see if a value is within some defined range\fR
+set inRange [\fB<=\fR 1 $x 5]
+
+\fI# Test to see if a list is sorted\fR
+set sorted [\fB<=\fR {*}$list]
+.CE
+.SH "SEE ALSO"
+expr(n), mathfunc(n), namespace(n)
+.SH KEYWORDS
+command, expression, operator
diff --git a/doc/memory.n b/doc/memory.n
index 9485192..4ff681d 100644
--- a/doc/memory.n
+++ b/doc/memory.n
@@ -7,11 +7,10 @@
.TH memory n 8.1 Tcl "Tcl Built-In Commands"
.BS
.SH NAME
-memory \- Control Tcl memory debugging capabilities.
+memory \- Control Tcl memory debugging capabilities
.SH SYNOPSIS
\fBmemory \fIoption \fR?\fIarg arg ...\fR?
.BE
-
.SH DESCRIPTION
.PP
The \fBmemory\fR command gives the Tcl developer control of Tcl's memory
@@ -21,9 +20,11 @@ memory debugging enabled (when \fBTCL_MEM_DEBUG\fR is defined at
compile time), and after \fBTcl_InitMemory\fR has been called.
.TP
\fBmemory active\fR \fIfile\fR
+.
Write a list of all currently allocated memory to the specified \fIfile\fR.
.TP
\fBmemory break_on_malloc\fR \fIcount\fR
+.
After the \fIcount\fR allocations have been performed, \fBckalloc\fR
outputs a message to this effect and that it is now attempting to enter
the C debugger. Tcl will then issue a \fISIGINT\fR signal against itself.
@@ -31,22 +32,33 @@ If you are running Tcl under a C debugger, it should then enter the debugger
command mode.
.TP
\fBmemory info\fR
+.
Returns a report containing the total allocations and frees since
Tcl began, the current packets allocated (the current
number of calls to \fBckalloc\fR not met by a corresponding call
to \fBckfree\fR), the current bytes allocated, and the maximum number
of packets and bytes allocated.
.TP
-\fB memory init [on|off]\fR
+\fBmemory init \fR[\fBon\fR|\fBoff\fR]
+.
Turn on or off the pre-initialization of all allocated memory
-with bogus bytes. Useful for detecting the use of uninitialized values.
+with bogus bytes. Useful for detecting the use of uninitialized
+values.
+.TP
+\fBmemory objs \fIfile\fR
+.
+Causes a list of all allocated Tcl_Obj values to be written to the specified
+\fIfile\fR immediately, together with where they were allocated. Useful for
+checking for leaks of values.
.TP
\fBmemory onexit\fR \fIfile\fR
+.
Causes a list of all allocated memory to be written to the specified \fIfile\fR
during the finalization of Tcl's memory subsystem. Useful for checking
that memory is properly cleaned up during process exit.
.TP
\fBmemory tag\fR \fIstring\fR
+.
Each packet of memory allocated by \fBckalloc\fR can have associated
with it a string-valued tag. In the lists of allocated memory generated
by \fBmemory active\fR and \fBmemory onexit\fR, the tag for each packet
@@ -54,22 +66,25 @@ is printed along with other information about the packet. The
\fBmemory tag\fR command sets the tag value for subsequent calls
to \fBckalloc\fR to be \fIstring\fR.
.TP
-\fBmemory trace [on|off]\fR
-.br
+\fBmemory trace \fR[\fBon\fR|\fBoff\fR]
+.
Turns memory tracing on or off. When memory tracing is on, every call
to \fBckalloc\fR causes a line of trace information to be written to
\fIstderr\fR, consisting of the word \fIckalloc\fR, followed by the
address returned, the amount of memory allocated, and the C filename
and line number of the code performing the allocation. For example:
.RS
+.PP
.CS
ckalloc 40e478 98 tclProc.c 1406
.CE
+.PP
Calls to \fBckfree\fR are traced in the same manner.
.RE
.TP
\fBmemory trace_on_at_malloc\fR \fIcount\fR
-Enable memory tracing after \fIcount\fR \fBckalloc\fR's have been performed.
+.
+Enable memory tracing after \fIcount\fR \fBckalloc\fRs have been performed.
For example, if you enter \fBmemory trace_on_at_malloc 100\fR,
after the 100th call to \fBckalloc\fR, memory trace information will begin
being displayed for all allocations and frees. Since there can be a lot
@@ -79,7 +94,8 @@ produced), if you can identify a number of allocations that occur before
the problem sets in. The current number of memory allocations that have
occurred since Tcl started is printed on a guard zone failure.
.TP
-\fBmemory validate [on|off]\fR
+\fBmemory validate \fR[\fBon\fR|\fBoff\fR]
+.
Turns memory validation on or off. When memory validation is enabled,
on every call to \fBckalloc\fR or \fBckfree\fR, the guard zones are
checked for every piece of memory currently in existence that was
@@ -90,9 +106,7 @@ overwrite can be detected on the first call to \fBckalloc\fR or
\fBckfree\fR after the overwrite occurred, rather than when the
specific memory with the overwritten guard zone(s) is freed, which may
occur long after the overwrite occurred.
-
.SH "SEE ALSO"
ckalloc, ckfree, Tcl_ValidateAllMemory, Tcl_DumpActiveMemory, TCL_MEM_DEBUG
-
.SH KEYWORDS
memory, debug
diff --git a/doc/msgcat.n b/doc/msgcat.n
index e6e08b5..00141ad 100644
--- a/doc/msgcat.n
+++ b/doc/msgcat.n
@@ -5,15 +5,15 @@
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.so man.macros
-.TH "msgcat" n 1.3 msgcat "Tcl Bundled Packages"
+.TH "msgcat" n 1.4 msgcat "Tcl Bundled Packages"
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
msgcat \- Tcl message catalog
.SH SYNOPSIS
-\fBpackage require Tcl 8.2\fR
+\fBpackage require Tcl 8.5\fR
.sp
-\fBpackage require msgcat 1.3.4\fR
+\fBpackage require msgcat 1.4.2\fR
.sp
\fB::msgcat::mc \fIsrc-string\fR ?\fIarg arg ...\fR?
.sp
@@ -31,13 +31,13 @@ msgcat \- Tcl message catalog
.sp
\fB::msgcat::mcunknown \fIlocale src-string\fR
.BE
-
.SH DESCRIPTION
.PP
The \fBmsgcat\fR package provides a set of functions
that can be used to manage multi-lingual user interfaces.
-Text strings are defined in a ``message catalog'' which
-is independent from the application, and
+Text strings are defined in a
+.QW "message catalog"
+which is independent from the application, and
which can be edited or localized without modifying
the application source code. New languages
or locales are provided by adding a new file to
@@ -53,6 +53,7 @@ Returns a translation of \fIsrc-string\fR according to the
user's current locale. If additional arguments past \fIsrc-string\fR
are given, the \fBformat\fR command is used to substitute the
additional arguments in the translation of \fIsrc-string\fR.
+.RS
.PP
\fB::msgcat::mc\fR will search the messages defined
in the current namespace for a translation of \fIsrc-string\fR; if
@@ -67,6 +68,7 @@ application can pass the English string through \fB::msgcat::mc\fR and
use the result. If an application is written for a single language in
this fashion, then it is easy to add support for additional languages
later simply by defining new message catalog entries.
+.RE
.TP
\fB::msgcat::mcmax ?\fIsrc-string src-string ...\fR?
Given several source strings, \fB::msgcat::mcmax\fR returns the length
@@ -91,13 +93,16 @@ preference. The list is derived from the current
locale set in msgcat by \fB::msgcat::mclocale\fR, and
cannot be set independently. For example, if the
current locale is en_US_funky, then \fB::msgcat::mcpreferences\fR
-returns \fB{en_US_funky en_US en}\fR.
+.VS 1.4
+returns \fB{en_US_funky en_US en {}}\fR.
+.VE 1.4
.TP
\fB::msgcat::mcload \fIdirname\fR
Searches the specified directory for files that match
the language specifications returned by \fB::msgcat::mcpreferences\fR
-(note that these are all lowercase), extended by the file
-extension ``.msg''. Each matching file is
+(note that these are all lowercase), extended by the file extension
+.QW .msg .
+Each matching file is
read in order, assuming a UTF-8 encoding. The file contents are
then evaluated as a Tcl script. This means that Unicode characters
may be present in the message file either directly in their UTF-8
@@ -137,10 +142,15 @@ The locale is specified to \fBmsgcat\fR by a locale string
passed to \fB::msgcat::mclocale\fR.
The locale string consists of
a language code, an optional country code, and an optional
-system-specific code, each separated by ``_''. The country and language
+system-specific code, each separated by
+.QW _ .
+The country and language
codes are specified in standards ISO-639 and ISO-3166.
-For example, the locale ``en'' specifies English and ``en_US'' specifies
-U.S. English.
+For example, the locale
+.QW en
+specifies English and
+.QW en_US
+specifies U.S. English.
.PP
When the msgcat package is first loaded, the locale is initialized
according to the user's environment. The variables \fBenv(LC_ALL)\fR,
@@ -159,14 +169,25 @@ 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 ``C''.
+locale of
+.QW C .
.PP
-When a locale is specified by the user, a ``best match'' search is
-performed during string translation. For example, if a user specifies
-en_GB_Funky, the locales ``en_GB_Funky'', ``en_GB'', and ``en'' are
-searched in order until a matching translation string is found. If no
-translation string is available, then \fB::msgcat::mcunknown\fR is
-called.
+When a locale is specified by the user, a
+.QW "best match"
+search is performed during string translation. For example, if a user
+specifies
+.VS 1.4
+en_GB_Funky, the locales
+.QW en_GB_Funky ,
+.QW en_GB ,
+.QW en
+and
+.MT
+(the empty string)
+.VE 1.4
+are searched in order until a matching translation
+string is found. If no translation string is available, then
+\fB::msgcat::mcunknown\fR is called.
.SH "NAMESPACES AND MESSAGE CATALOGS"
.PP
Strings stored in the message catalog are stored relative
@@ -194,10 +215,13 @@ hello from ::foo
When searching for a translation of a message, the
message catalog will search first the current namespace,
then the parent of the current namespace, and so on until
-the global namespace is reached. This allows child namespaces
-to "inherit" messages from their parent namespace.
+the global namespace is reached. This allows child namespaces to
+.QW inherit
+messages from their parent namespace.
.PP
-For example, executing (in the ``en'' locale) the code
+For example, executing (in the
+.QW en
+locale) the code
.CS
\fB::msgcat::mcset\fR en m1 ":: message1"
\fB::msgcat::mcset\fR en m2 ":: message2"
@@ -227,12 +251,23 @@ to the following conditions:
.IP [1]
All message files for a package are in the same directory.
.IP [2]
-The message file name is a msgcat locale specifier (all lowercase)
-followed by ``.msg''. For example:
+The message file name is a msgcat locale specifier (all lowercase) followed by
+.QW .msg .
+For example:
.CS
-es.msg -- spanish
-en_gb.msg -- United Kingdom English
+es.msg \(em spanish
+en_gb.msg \(em United Kingdom English
.CE
+.VS 1.4
+\fIException:\fR The message file for the root locale
+.MT
+is called
+.QW \fBROOT.msg\fR .
+This exception is made so as not to
+cause peculiar behavior, such as marking the message file as
+.QW hidden
+on Unix file systems.
+.VE 1.4
.IP [3]
The file contains a series of calls to \fBmcset\fR and
\fBmcmset\fR, setting the necessary translation strings
@@ -276,8 +311,8 @@ format "In location %s we produced %d units" $city $num
This can be handled by using the positional
parameters:
.CS
-format "We produced %1\\$d units in location %2\\$s" $num $city
-format "In location %2\\$s we produced %1\\$d units" $num $city
+format "We produced %1\e$d units in location %2\e$s" $num $city
+format "In location %2\e$s we produced %1\e$d units" $num $city
.CE
.PP
Similarly, positional parameters can be used with \fBscan\fR to
@@ -285,9 +320,7 @@ extract values from internationalized strings.
.SH CREDITS
.PP
The message catalog code was developed by Mark Harrison.
-
.SH "SEE ALSO"
format(n), scan(n), namespace(n), package(n)
-
.SH KEYWORDS
internationalization, i18n, localization, l10n, message, text, translation
diff --git a/doc/namespace.n b/doc/namespace.n
index 5468416..ddf7b51 100644
--- a/doc/namespace.n
+++ b/doc/namespace.n
@@ -2,28 +2,28 @@
'\" Copyright (c) 1993-1997 Bell Labs Innovations for Lucent Technologies
'\" Copyright (c) 1997 Sun Microsystems, Inc.
'\" Copyright (c) 2000 Scriptics Corporation.
+'\" Copyright (c) 2004-2005 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 namespace n 8.0 Tcl "Tcl Built-In Commands"
+.TH namespace n 8.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
namespace \- create and manipulate contexts for commands and variables
.SH SYNOPSIS
-\fBnamespace \fR?\fIoption\fR? ?\fIarg ...\fR?
+\fBnamespace \fR?\fIsubcommand\fR? ?\fIarg ...\fR?
.BE
-
.SH DESCRIPTION
.PP
The \fBnamespace\fR command lets you create, access, and destroy
separate contexts for commands and variables.
See the section \fBWHAT IS A NAMESPACE?\fR below
for a brief overview of namespaces.
-The legal values of \fIoption\fR are listed below.
-Note that you can abbreviate the \fIoption\fRs.
+The legal values of \fIsubcommand\fR are listed below.
+Note that you can abbreviate the \fIsubcommand\fRs.
.TP
\fBnamespace children \fR?\fInamespace\fR? ?\fIpattern\fR?
Returns a list of all child namespaces that belong to the
@@ -54,7 +54,7 @@ and they will be passed to \fIscript\fR as additional arguments.
For example, suppose the command
\fBset script [namespace code {foo bar}]\fR
is invoked in namespace \fB::a::b\fR.
-Then \fBeval "$script x y"\fR
+Then \fBeval $script [list x y]\fR
can be executed in any namespace (assuming the value of
\fBscript\fR has been passed in properly)
and will have the same effect as the command
@@ -69,7 +69,8 @@ of how this is used to create callback scripts.
.TP
\fBnamespace current\fR
Returns the fully-qualified name for the current namespace.
-The actual name of the global namespace is ``''
+The actual name of the global namespace is
+.MT
(i.e., an empty string),
but this command returns \fB::\fR for the global namespace
as a convenience to programmers.
@@ -82,9 +83,16 @@ If a procedure is currently executing inside the namespace,
the namespace will be kept alive until the procedure returns;
however, the namespace is marked to prevent other code from
looking it up by name.
-If a namespace doesn't exist, this command returns an error.
+If a namespace does not exist, this command returns an error.
If no namespace names are given, this command does nothing.
.TP
+\fBnamespace ensemble\fR \fIsubcommand\fR ?\fIarg ...\fR?
+.VS 8.5
+Creates and manipulates a command that is formed out of an ensemble of
+subcommands. See the section \fBENSEMBLES\fR below for further
+details.
+.VE 8.5
+.TP
\fBnamespace eval\fR \fInamespace arg\fR ?\fIarg ...\fR?
Activates a namespace called \fInamespace\fR and evaluates some code
in that context.
@@ -93,11 +101,12 @@ If more than one \fIarg\fR argument is specified,
the arguments are concatenated together with a space between each one
in the same fashion as the \fBeval\fR command,
and the result is evaluated.
-.br
-.sp
+.RS
+.PP
If \fInamespace\fR has leading namespace qualifiers
and any leading namespaces do not exist,
they are automatically created.
+.RE
.TP
\fBnamespace exists\fR \fInamespace\fR
Returns \fB1\fR if \fInamespace\fR is a valid namespace in the current
@@ -117,10 +126,10 @@ but it may not include any namespace qualifiers.
That is, the pattern can only specify commands
in the current (exporting) namespace.
Each \fIpattern\fR is appended onto the namespace's list of export patterns.
-If the \-\fBclear\fR flag is given,
+If the \fB\-clear\fR flag is given,
the namespace's export pattern list is reset to empty before any
\fIpattern\fR arguments are appended.
-If no \fIpattern\fRs are given and the \-\fBclear\fR flag isn't given,
+If no \fIpattern\fRs are given and the \fB\-clear\fR flag is not given,
this command returns the namespace's current export list.
.TP
\fBnamespace forget \fR?\fIpattern pattern ...\fR?
@@ -129,24 +138,37 @@ Each \fIpattern\fR is a simple or qualified name such as
\fBx\fR, \fBfoo::x\fR or \fBa::b::p*\fR.
Qualified names contain double colons (\fB::\fR) and qualify a name
with the name of one or more namespaces.
-Each \fIqualified pattern\fR is qualified with the name of an
-exporting namespace
+Each
+.QW "qualified pattern"
+is qualified with the name of an exporting namespace
and may have glob-style special characters in the command name
at the end of the qualified name.
Glob characters may not appear in a namespace name.
-For each \fIsimple pattern\fR this command deletes the matching
-commands of the
+For each
+.QW "simple pattern"
+this command deletes the matching commands of the
current namespace that were imported from a different namespace.
-For \fIqualified patterns\fR, this command first finds the matching
-exported commands.
+For
+.QW "qualified patterns" ,
+this command first finds the matching exported commands.
It then checks whether any of those commands
were previously imported by the current namespace.
-If so, this command deletes the corresponding imported commands.
+If so, this command deletes the corresponding imported commands.
In effect, this un-does the action of a \fBnamespace import\fR command.
.TP
\fBnamespace import \fR?\fB\-force\fR? ?\fIpattern\fR \fIpattern ...\fR?
-Imports commands into a namespace.
-Each \fIpattern\fR is a qualified name like
+.VS 8.5
+Imports commands into a namespace, or queries the set of imported
+commands in a namespace. When no arguments are present,
+\fBnamespace import\fR returns the list of commands in
+the current namespace that have been imported from other
+namespaces. The commands in the returned list are in
+the format of simple names, with no namespace qualifiers at all.
+This format is suitable for composition with \fBnamespace forget\fR
+(see \fBEXAMPLES\fR below).
+.VE 8.5
+When \fIpattern\fR arguments are present,
+each \fIpattern\fR is a qualified name like
\fBfoo::x\fR or \fBa::p*\fR.
That is, it includes the name of an exporting namespace
and may have glob-style special characters in the command name
@@ -180,12 +202,18 @@ The \fBnamespace inscope\fR command is much like the \fBnamespace eval\fR
command except that the \fInamespace\fR must already exist,
and \fBnamespace inscope\fR appends additional \fIarg\fRs
as proper list elements.
-.br
+.RS
+.PP
+.CS
\fBnamespace inscope ::foo $script $x $y $z\fR
+.CE
is equivalent to
+.CS
\fBnamespace eval ::foo [concat $script [list $x $y $z]]\fR
+.CE
thus additional arguments will not undergo a second round of substitution,
as is the case with \fBnamespace eval\fR.
+.RE
.TP
\fBnamespace origin \fIcommand\fR
Returns the fully-qualified name of the original command
@@ -207,6 +235,17 @@ for namespace \fInamespace\fR.
If \fInamespace\fR is not specified,
the fully-qualified name of the current namespace's parent is returned.
.TP
+\fBnamespace path\fR ?\fInamespaceList\fR?
+.\" Should really have the .TP inside the .VS, but that triggers a groff bug
+.VS 8.5
+Returns the command resolution path of the current namespace. If
+\fInamespaceList\fR is specified as a list of named namespaces, the
+current namespace's command resolution path is set to those namespaces
+and returns the empty list. The default command resolution path is
+always empty. See the section \fBNAME RESOLUTION\fR below for an
+explanation of the rules regarding name resolution.
+.VE 8.5
+.TP
\fBnamespace qualifiers\fR \fIstring\fR
Returns any leading namespace qualifiers for \fIstring\fR.
Qualifiers are namespace names separated by double colons (\fB::\fR).
@@ -228,6 +267,27 @@ 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?\fIotherVar myVar \fR...
+This command arranges for one or more local variables in the current
+procedure to refer to variables in \fInamespace\fR. The namespace name is
+resolved as described in section \fBNAME RESOLUTION\fR.
+The command
+\fBnamespace upvar $ns a b\fR has the same behaviour as
+\fBupvar 0 ${ns}::a b\fR, with the sole exception of the resolution rules
+used for qualified namespace or variable names.
+\fBnamespace upvar\fR returns an empty string.
+.TP
+\fBnamespace unknown\fR ?\fIscript\fR?
+Sets or returns the unknown command handler for the current namespace.
+The handler is invoked when a command called from within the namespace
+cannot be found (in either the current namespace or the global namespace).
+The \fIscript\fR argument, if given, should be a well
+formed list representing a command name and optional arguments. When
+the handler is invoked, the full invocation line will be appended to the
+script and the result evaluated in the context of the namespace. The
+default handler for all namespaces is \fB::unknown\fR. If no argument
+is given, it returns the handler for the current namespace.
+.TP
\fBnamespace which\fR ?\-\fBcommand\fR? ?\-\fBvariable\fR? \fIname\fR
Looks up \fIname\fR as either a command or variable
and returns its fully-qualified name.
@@ -237,7 +297,7 @@ this command returns a fully-qualified name in the global namespace.
If the command or variable does not exist,
this command returns an empty string. If the variable has been
created but not defined, such as with the \fBvariable\fR command
-or through a \fBtrace\fR on the variable, this command will return the
+or through a \fBtrace\fR on the variable, this command will return the
fully-qualified name of the variable.
If no flag is given, \fIname\fR is treated as a command name.
See the section \fBNAME RESOLUTION\fR below for an explanation of
@@ -246,7 +306,7 @@ the rules regarding name resolution.
.PP
A namespace is a collection of commands and variables.
It encapsulates the commands and variables to ensure that they
-won't interfere with the commands and variables of other namespaces.
+will not interfere with the commands and variables of other namespaces.
Tcl has always had one such collection,
which we refer to as the \fIglobal namespace\fR.
The global namespace holds all global variables and commands.
@@ -317,8 +377,9 @@ Qualified names are similar to the hierarchical path names for
Unix files or Tk widgets,
except that \fB::\fR is used as the separator
instead of \fB/\fR or \fB.\fR.
-The topmost or global namespace has the name ``'' (i.e., an empty string),
-although \fB::\fR is a synonym.
+The topmost or global namespace has the name
+.MT
+(i.e., an empty string), although \fB::\fR is a synonym.
As an example, the name \fB::safe::interp::create\fR
refers to the command \fBcreate\fR in the namespace \fBinterp\fR
that is a child of namespace \fB::safe\fR,
@@ -377,11 +438,19 @@ If you provide a fully-qualified name that starts with a \fB::\fR,
there is no question about what command, variable, or namespace
you mean.
However, if the name does not start with a \fB::\fR
-(i.e., is \fIrelative\fR),
-Tcl follows a fixed rule for looking it up:
-Command and variable names are always resolved
+(i.e., is \fIrelative\fR),
+Tcl follows basic rules for looking it up:
+Variable names are always resolved
by looking first in the current namespace,
and then in the global namespace.
+.VS 8.5
+Command names are also always resolved by looking in the current
+namespace first. If not found there, they are searched for in every
+namespace on the current namespace's command path (which is empty by
+default). If not found there, command names are looked up in the
+global namespace (or, failing that, are processed by the \fBunknown\fR
+command.)
+.VE 8.5
Namespace names, on the other hand, are always resolved
by looking in only the current namespace.
.PP
@@ -409,7 +478,7 @@ set traceLevel 0
}
.CE
Here Tcl looks for \fBtraceLevel\fR first in the namespace \fBFoo::Debug\fR.
-Since it is not found there, Tcl then looks for it
+Since it is not found there, Tcl then looks for it
in the global namespace.
The variable \fBFoo::traceLevel\fR is completely ignored
during the name resolution process.
@@ -484,7 +553,7 @@ from a namespace that that namespace exported
with a \fBnamespace export\fR command.
.PP
Importing \fIevery\fR command from a namespace is generally
-a bad idea since you don't know what you will get.
+a bad idea since you do not know what you will get.
It is better to import just the specific commands you need.
For example, the command
.CS
@@ -561,12 +630,14 @@ may be imported by other namespaces.
If a \fBnamespace import\fR command specifies a command
that is not exported, the command is not imported.
.SH "SCOPED SCRIPTS"
+.PP
The \fBnamespace code\fR command is the means by which a script may be
packaged for evaluation in a namespace other than the one in which it
was created. It is used most often to create event handlers, Tk bindings,
and traces for evaluation in the global context. For instance, the following
-code indicates how to direct a variable trace callback into the current
+code indicates how to direct a variable \fBtrace\fR callback into the current
namespace:
+.PP
.CS
\fBnamespace eval\fR a {
variable b
@@ -575,14 +646,172 @@ namespace:
puts "the value of $n1 has changed to $var"
return
}
- trace variable b w [\fBnamespace code\fR theTraceCallback]
+ trace add variable b write [\fBnamespace code\fR theTraceCallback]
}
set a::b c
.CE
+.PP
When executed, it prints the message:
+.PP
.CS
the value of a::b has changed to c
.CE
+.SH ENSEMBLES
+.PP
+.VS 8.5
+The \fBnamespace ensemble\fR is used to create and manipulate ensemble
+commands, which are commands formed by grouping subcommands together.
+The commands typically come from the current namespace when the
+ensemble was created, though this is configurable. Note that there
+may be any number of ensembles associated with any namespace
+(including none, which is true of all namespaces by default), though
+all the ensembles associated with a namespace are deleted when that
+namespace is deleted. The link between an ensemble command and its
+namespace is maintained however the ensemble is renamed.
+.PP
+Three subcommands of the \fBnamespace ensemble\fR command are defined:
+.TP
+\fBnamespace ensemble create\fR ?\fIoption value ...\fR?
+Creates a new ensemble command linked to the current namespace,
+returning the fully qualified name of the command created. The
+arguments to \fBnamespace ensemble create\fR allow the configuration
+of the command as if with the \fBnamespace ensemble configure\fR
+command. If not overridden with the \fB\-command\fR option, this
+command creates an ensemble with exactly the same name as the linked
+namespace. See the section \fBENSEMBLE OPTIONS\fR below for a full
+list of options supported and their effects.
+.TP
+\fBnamespace ensemble configure \fIcommand\fR ?\fIoption\fR? ?\fIvalue ...\fR?
+Retrieves the value of an option associated with the ensemble command
+named \fIcommand\fR, or updates some options associated with that
+ensemble command. See the section \fBENSEMBLE OPTIONS\fR below for a
+full list of options supported and their effects.
+.TP
+\fBnamespace ensemble exists\fR \fIcommand\fR
+Returns a boolean value that describes whether the command
+\fIcommand\fR exists and is an ensemble command. This command only
+ever returns an error if the number of arguments to the command is
+wrong.
+.PP
+When called, an ensemble command takes its first argument and looks it
+up (according to the rules described below) to discover a list of
+words to replace the ensemble command and subcommand with. The
+resulting list of words is then evaluated (with no further
+substitutions) as if that was what was typed originally (i.e. by
+passing the list of words through \fBTcl_EvalObjv\fR) and returning
+the result of the command. Note that it is legal to make the target
+of an ensemble rewrite be another (or even the same) ensemble
+command. The ensemble command will not be visible through the use of
+the \fBuplevel\fR or \fBinfo level\fR commands.
+.SS "ENSEMBLE OPTIONS"
+.PP
+The following options, supported by the \fBnamespace ensemble
+create\fR and \fBnamespace ensemble configure\fR commands, control how
+an ensemble command behaves:
+.TP
+\fB\-map\fR
+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
+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
+will be exactly those words that have mappings in the dictionary.
+.TP
+\fB\-prefixes\fR
+This option (which is enabled by default) controls whether the
+ensemble command recognizes unambiguous prefixes of its subcommands.
+When turned off, the ensemble command requires exact matching of
+subcommand names.
+.TP
+\fB\-subcommands\fR
+When non-empty, this option lists exactly what subcommands are in the
+ensemble. The mapping for each of those commands will be either whatever
+is defined in the \fB\-map\fR option, or to the command with the same
+name in the namespace linked to the ensemble. If this option is
+empty, the subcommands of the namespace will either be the keys of the
+dictionary listed in the \fB\-map\fR option or the exported commands
+of the linked namespace at the time of the invocation of the ensemble
+command.
+.TP
+\fB\-unknown\fR
+When non-empty, this option provides a partial command (to which all
+the words that are arguments to the ensemble command, including the
+fully-qualified name of the ensemble, are appended) to handle the case
+where an ensemble subcommand is not recognized and would otherwise
+generate an error. When empty (the default) an error (in the style of
+\fBTcl_GetIndexFromObj\fR) is generated whenever the ensemble is
+unable to determine how to implement a particular subcommand. See
+\fBUNKNOWN HANDLER BEHAVIOUR\fR for more details.
+.PP
+The following extra option is allowed by \fBnamespace ensemble
+create\fR:
+.TP
+\fB\-command\fR
+This write-only option allows the name of the ensemble created by
+\fBnamespace ensemble create\fR to be anything in any existing
+namespace. The default value for this option is the fully-qualified
+name of the namespace in which the \fBnamespace ensemble create\fR
+command is invoked.
+.PP
+The following extra option is allowed by \fBnamespace ensemble
+configure\fR:
+.TP
+\fB\-namespace\fR
+This read-only option allows the retrieval of the fully-qualified name
+of the namespace which the ensemble was created within.
+.SS "UNKNOWN HANDLER BEHAVIOUR"
+.PP
+If an unknown handler is specified for an ensemble, that handler is
+called when the ensemble command would otherwise return an error due
+to it being unable to decide which subcommand to invoke. The exact
+conditions under which that occurs are controlled by the
+\fB\-subcommands\fR, \fB\-map\fR and \fB\-prefixes\fR options as
+described above.
+.PP
+To execute the unknown handler, the ensemble mechanism takes the
+specified \fB\-unknown\fR option and appends each argument of the
+attempted ensemble command invocation (including the ensemble command
+itself, expressed as a fully qualified name). It invokes the resulting
+command in the scope of the attempted call. If the execution of the
+unknown handler terminates normally, the ensemble engine reparses the
+subcommand (as described below) and tries to dispatch it again, which
+is ideal for when the ensemble's configuration has been updated by the
+unknown subcommand handler. Any other kind of termination of the
+unknown handler is treated as an error.
+.PP
+The result of the unknown handler is expected to be a list (it is an
+error if it is not). If the list is an empty list, the ensemble
+command attempts to look up the original subcommand again and, if it
+is not found this time, an error will be generated just as if the
+\fB\-unknown\fR handler was not there (i.e. for any particular
+invocation of an ensemble, its unknown handler will be called at most
+once.) This makes it easy for the unknown handler to update the
+ensemble or its backing namespace so as to provide an implementation
+of the desired subcommand and reparse.
+.PP
+When the result is a non-empty list, the words of that list are used
+to replace the ensemble command and subcommand, just as if they had
+been looked up in the \fB\-map\fR. It is up to the unknown handler to
+supply all namespace qualifiers if the implementing subcommand is not
+in the namespace of the caller of the ensemble command. Also note that
+when ensemble commands are chained (e.g. if you make one of the
+commands that implement an ensemble subcommand into an ensemble, in a
+manner similar to the \fBtext\fR widget's tag and mark subcommands) then the
+rewrite happens in the context of the caller of the outermost
+ensemble. That is to say that ensembles do not in themselves place any
+namespace contexts on the Tcl call stack.
+.PP
+Where an empty \fB\-unknown\fR handler is given (the default), the
+ensemble command will generate an error message based on the list of
+commands that the ensemble has defined (formatted similarly to the
+error message from \fBTcl_GetIndexFromObj\fR). This is the error that
+will be thrown when the subcommand is still not recognized during
+reparsing. It is also an error for an \fB\-unknown\fR handler to
+delete its namespace.
+.VE 8.5
.SH EXAMPLES
Create a namespace containing a variable and an exported command:
.CS
@@ -599,20 +828,38 @@ Create a namespace containing a variable and an exported command:
Call the command defined in the previous example in various ways.
.CS
# Direct call
-foo::grill
+::foo::grill
+
+# Use the command resolution path to find the name
+\fBnamespace eval\fR boo {
+ \fBnamespace path\fR ::foo
+ grill
+}
# Import into current namespace, then call local alias
-namespace import foo::grill
+\fBnamespace import\fR foo::grill
grill
+
+# Create two ensembles, one with the default name and one with a
+# specified name. Then call through the ensembles.
+\fBnamespace eval\fR foo {
+ \fBnamespace ensemble\fR create
+ \fBnamespace ensemble\fR create -command ::foobar
+}
+foo grill
+foobar grill
.CE
.PP
Look up where the command imported in the previous example came from:
.CS
puts "grill came from [\fBnamespace origin\fR grill]"
.CE
-
+.PP
+Remove all imported commands from the current namespace:
+.CS
+namespace forget {*}[namespace import]
+.CE
.SH "SEE ALSO"
-variable(n)
-
+interp(n), upvar(n), variable(n)
.SH KEYWORDS
-exported, internal, variable
+command, ensemble, exported, internal, variable
diff --git a/doc/open.n b/doc/open.n
index 1557ca9..88283bb 100644
--- a/doc/open.n
+++ b/doc/open.n
@@ -19,7 +19,6 @@ open \- Open a file-based or command pipeline channel
.br
\fBopen \fIfileName access permissions\fR
.BE
-
.SH DESCRIPTION
.PP
This command opens a file, serial port, or command pipeline and returns a
@@ -43,22 +42,30 @@ Open the file for both reading and writing; the file must
already exist.
.TP 15
\fBw\fR
-Open the file for writing only. Truncate it if it exists. If it doesn't
+Open the file for writing only. Truncate it if it exists. If it does not
exist, create a new file.
.TP 15
\fBw+\fR
Open the file for reading and writing. Truncate it if it exists.
-If it doesn't exist, create a new file.
+If it does not exist, create a new file.
.TP 15
\fBa\fR
-Open the file for writing only. If the file doesn't exist,
+Open the file for writing only. If the file does not exist,
create a new empty file.
Set the file pointer to the end of the file prior to each write.
.TP 15
\fBa+\fR
-Open the file for reading and writing. If the file doesn't exist,
+Open the file for reading and writing. If the file does not exist,
create a new empty file.
Set the initial access position to the end of the file.
+.VS 8.5
+.PP
+All of the legal \fIaccess\fR values above may have the character
+\fBb\fR added as the second or third character in the value to
+indicate that the opened channel should be configured with the
+\fB\-translation binary\fR option, making the channel suitable for
+reading or writing of binary data.
+.VE 8.5
.PP
In the second form, \fIaccess\fR consists of a list of any of the
following flags, all of which have the standard POSIX meanings.
@@ -75,9 +82,14 @@ Open the file for both reading and writing.
.TP 15
\fBAPPEND\fR
Set the file pointer to the end of the file prior to each write.
+.VS 8.5
+.TP 15
+\fBBINARY\fR
+Configure the opened channel with the \fB\-translation binary\fR option.
+.VE 8.5
.TP 15
\fBCREAT\fR
-Create the file if it doesn't already exist (without this flag it
+Create the file if it does not already exist (without this flag it
is an error for the file not to exist).
.TP 15
\fBEXCL\fR
@@ -104,18 +116,11 @@ If a new file is created as part of opening it, \fIpermissions\fR
(an integer) is used to set the permissions for the new file in
conjunction with the process's file mode creation mask.
\fIPermissions\fR defaults to 0666.
-.PP
-Note that if you are going to be reading or writing binary data from
-the channel created by this command, you should use the
-\fBfconfigure\fR command to change the \fB-translation\fR option of
-the channel to \fBbinary\fR before transferring any binary data. This
-is in contrast to the ``b'' character passed as part of the equivalent
-of the \fIaccess\fR parameter to some versions of the C library
-\fIfopen()\fR function.
-
.SH "COMMAND PIPELINES"
.PP
-If the first character of \fIfileName\fR is ``|'' then the
+If the first character of \fIfileName\fR is
+.QW |
+then the
remaining characters of \fIfileName\fR are treated as a list of arguments
that describe a command pipeline to invoke, in the same style as the
arguments for \fBexec\fR.
@@ -140,7 +145,6 @@ returned (a silent \fBclose\fR with -blocking 0).
It is often useful to use the \fBfileevent\fR command with pipelines
so other processing may happen at the same time as running the command
in the background.
-.VS 8.4
.SH "SERIAL COMMUNICATIONS"
.PP
If \fIfileName\fR refers to a serial port, then the specified serial port
@@ -156,8 +160,14 @@ This option is a set of 4 comma-separated values: the baud rate, parity,
number of data bits, and number of stop bits for this serial port. The
\fIbaud\fR rate is a simple integer that specifies the connection speed.
\fIParity\fR is one of the following letters: \fBn\fR, \fBo\fR, \fBe\fR,
-\fBm\fR, \fBs\fR; respectively signifying the parity options of ``none'',
-``odd'', ``even'', ``mark'', or ``space''. \fIData\fR is the number of
+\fBm\fR, \fBs\fR; respectively signifying the parity options of
+.QW none ,
+.QW odd ,
+.QW even ,
+.QW mark ,
+or
+.QW space .
+\fIData\fR is the number of
data bits and should be an integer from 5 to 8, while \fIstop\fR is the
number of stop bits and should be the integer 1 or 2.
.TP
@@ -165,19 +175,21 @@ number of stop bits and should be the integer 1 or 2.
(Windows and Unix). This option is used to setup automatic handshake
control. Note that not all handshake types maybe supported by your operating
system. The \fItype\fR parameter is case-independent.
-.sp
+.RS
+.PP
If \fItype\fR is \fBnone\fR then any handshake is switched off.
\fBrtscts\fR activates hardware handshake. Hardware handshake signals
are described below.
For software handshake \fBxonxoff\fR the handshake characters can be redefined
-with \fB-xchar\fR.
+with \fB\-xchar\fR.
An additional hardware handshake \fBdtrdsr\fR is available only under Windows.
There is no default handshake configuration, the initial value depends
on your operating system settings.
-The \fB-handshake\fR option cannot be queried.
+The \fB\-handshake\fR option cannot be queried.
+.RE
.TP
\fB\-queue\fR
-(Windows and Unix). The \fB-queue\fR option can only be queried.
+(Windows and Unix). The \fB\-queue\fR option can only be queried.
It returns a list of two integers representing the current number
of bytes in the input and output queue respectively.
.TP
@@ -186,7 +198,7 @@ of bytes in the input and output queue respectively.
read operations. It specifies the maximum interval between the
reception of two bytes in milliseconds.
For Unix systems the granularity is 100 milliseconds.
-The \fB-timeout\fR option does not affect write operations or
+The \fB\-timeout\fR option does not affect write operations or
nonblocking reads.
This option cannot be queried.
.TP
@@ -197,13 +209,13 @@ The \fIsignal\fR names are case-independent.
\fB{RTS 1 DTR 0}\fR sets the RTS output to high and the DTR output to low.
The BREAK condition (see below) is enabled and disabled with \fB{BREAK 1}\fR and
\fB{BREAK 0}\fR respectively.
-It's not a good idea to change the \fBRTS\fR (or \fBDTR\fR) signal
+It is not a good idea to change the \fBRTS\fR (or \fBDTR\fR) signal
with active hardware handshake \fBrtscts\fR (or \fBdtrdsr\fR).
The result is unpredictable.
-The \fB-ttycontrol\fR option cannot be queried.
+The \fB\-ttycontrol\fR option cannot be queried.
.TP
\fB\-ttystatus\fR
-(Windows and Unix). The \fB-ttystatus\fR option can only be
+(Windows and Unix). The \fB\-ttystatus\fR option can only be
queried. It returns the current modem status and handshake input signals
(see below).
The result is a list of signal,value pairs with a fixed order,
@@ -239,7 +251,6 @@ In case of a serial communication error, \fBread\fR or \fBputs\fR
returns a general Tcl file I/O error.
\fBfconfigure -lasterror\fR can be called to get a list of error details.
See below for an explanation of the various error codes.
-
.SH "SERIAL PORT SIGNALS"
.PP
RS-232 is the most commonly used standard electrical interface for serial
@@ -250,7 +261,6 @@ lines and handshaking. Here we are using the terms \fIworkstation\fR for
your computer and \fImodem\fR for the external device, because some signal
names (DCD, RI) come from modems. Of course your external device may use
these signal lines for other purposes.
-
.IP \fBTXD(output)\fR
\fBTransmitted Data:\fR Outgoing serial data.
.IP \fBRXD(input)\fR
@@ -270,8 +280,9 @@ serial port is opened.
\fBData Set Ready:\fR The complement to DTR. Tells the workstation that the
modem is ready to establish a link.
.IP \fBDCD(input)\fR
-\fBData Carrier Detect:\fR This line becomes active when a modem detects
-a "Carrier" signal.
+\fBData Carrier Detect:\fR This line becomes active when a modem detects a
+.QW Carrier
+signal.
.IP \fBRI(input)\fR
\fBRing Indicator:\fR Goes active when the modem detects an incoming call.
.IP \fBBREAK\fR
@@ -281,17 +292,15 @@ milliseconds. Normally a receive or transmit data signal stays at the mark
(on=1) voltage until the next character is transferred. A BREAK is sometimes
used to reset the communications line or change the operating mode of
communications hardware.
-
.SH "ERROR CODES (Windows only)"
.PP
A lot of different errors may occur during serial read operations or during
event polling in background. The external device may have been switched
off, the data lines may be noisy, system buffers may overrun or your mode
-settings may be wrong. That's why a reliable software should always
+settings may be wrong. That is why a reliable software should always
\fBcatch\fR serial read operations. In cases of an error Tcl returns a
general file I/O error. Then \fBfconfigure -lasterror\fR may help to
locate the problem. The following error codes may be returned.
-
.TP 10
\fBRXOVER\fR
Windows input buffer overrun. The data comes faster than your scripts reads
@@ -320,8 +329,6 @@ may cause this error.
.TP 10
\fBBREAK\fR
A BREAK condition has been detected by your UART (see above).
-.VE
-
.SH "PORTABILITY ISSUES"
.TP
\fBWindows \fR(all versions)
@@ -356,7 +363,8 @@ standard input from a pipe and send standard output to a pipe run
synchronously. Command pipelines that do not execute 16-bit DOS
applications run asynchronously and can be opened for both reading and
writing.
-.sp
+.RS
+.PP
When running Tcl interactively, there may be some strange interactions
between the real console, if one is present, and a command pipeline that uses
standard input or output. If a command pipeline is opened for reading from
@@ -369,7 +377,7 @@ console at the same time. If the command pipeline is started from a script,
so that Tcl is not accessing the console, or if the command pipeline does
not use standard input or output, but is redirected from or to a file, then
the above problems do not occur.
-.sp
+.PP
Whether or not Tcl is running interactively, if a command pipeline is opened
for reading from a 16-bit DOS application, the call to \fBopen\fR will not
return until end-of-file has been received from the command pipeline's
@@ -377,22 +385,16 @@ standard output. If a command pipeline is opened for writing to a 16-bit DOS
application, no data will be sent to the command pipeline's standard output
until the pipe is actually closed. This problem occurs because 16-bit DOS
applications are run synchronously, as described above.
-.TP
-\fBMacintosh\fR
-Opening a serial port is not currently implemented under Macintosh.
-.sp
-Opening a command pipeline is not supported under Macintosh, since
-applications do not support the concept of standard input or output.
+.RE
.TP
\fBUnix\fR\0\0\0\0\0\0\0
Valid values for \fIfileName\fR to open a serial port are generally of the
form \fB/dev/tty\fIX\fR, where \fIX\fR is \fBa\fR or \fBb\fR, but the name
of any pseudo-file that maps to a serial port may be used.
-.VS 8.4
Advanced configuration options are only supported for serial ports
when Tcl is built to use the POSIX serial interface.
-.VE 8.4
-.sp
+.RS
+.PP
When running Tcl interactively, there may be some strange interactions
between the console, if one is present, and a command pipeline that uses
standard input. If a command pipeline is opened for reading, some
@@ -402,9 +404,10 @@ both Tcl and the child application are competing for the console at the
same time. If the command pipeline is started from a script, so that Tcl is
not accessing the console, or if the command pipeline does not use standard
input, but is redirected from a file, then the above problem does not occur.
-.LP
-See the PORTABILITY ISSUES section of the \fBexec\fR command for additional
-information not specific to command pipelines about executing
+.RE
+.PP
+See the \fBPORTABILITY ISSUES\fR section of the \fBexec\fR command for
+additional information not specific to command pipelines about executing
applications on the various platforms
.SH "EXAMPLE"
Open a command pipeline and catch any errors:
@@ -415,11 +418,9 @@ if {[catch {close $fl} err]} {
puts "ls command failed: $err"
}
.CE
-
.SH "SEE ALSO"
file(n), close(n), filename(n), fconfigure(n), gets(n), read(n),
puts(n), exec(n), pid(n), fopen(3)
-
.SH KEYWORDS
access mode, append, create, file, non-blocking, open, permissions,
pipeline, process, serial
diff --git a/doc/package.n b/doc/package.n
index 60be18b..d4fe657 100644
--- a/doc/package.n
+++ b/doc/package.n
@@ -15,13 +15,16 @@ package \- Facilities for package loading and version control
\fBpackage forget ?\fIpackage package ...\fR?
\fBpackage ifneeded \fIpackage version\fR ?\fIscript\fR?
\fBpackage names\fR
-\fBpackage present \fR?\fB\-exact\fR? \fIpackage \fR?\fIversion\fR?
+\fBpackage present \fIpackage \fR?\fIrequirement...\fR?
+\fBpackage present \-exact \fIpackage version\fR
\fBpackage provide \fIpackage \fR?\fIversion\fR?
-\fBpackage require \fR?\fB\-exact\fR? \fIpackage \fR?\fIversion\fR?
+\fBpackage require \fIpackage \fR?\fIrequirement...\fR?
+\fBpackage require \-exact \fIpackage version\fR
\fBpackage unknown \fR?\fIcommand\fR?
\fBpackage vcompare \fIversion1 version2\fR
\fBpackage versions \fIpackage\fR
-\fBpackage vsatisfies \fIversion1 version2\fR
+\fBpackage vsatisfies \fIversion requirement...\fR
+\fBpackage prefer \fR?\fBlatest\fR|\fBstable\fR?
.fi
.BE
@@ -74,7 +77,8 @@ interpreter for which a version has been provided (via
script is available.
The order of elements in the list is arbitrary.
.TP
-\fBpackage present \fR?\fB\-exact\fR? \fIpackage \fR?\fIversion\fR?
+\fBpackage present\fR ?\fB\-exact\fR? \fIpackage\fR ?\fIrequirement...\fR?
+.
This command is equivalent to \fBpackage require\fR except that it
does not try and load the package if it is not already loaded.
.TP
@@ -90,25 +94,34 @@ returns the version number that is currently provided, or an
empty string if no \fBpackage provide\fR command has been
invoked for \fIpackage\fR in this interpreter.
.TP
-\fBpackage require \fR?\fB\-exact\fR? \fIpackage \fR?\fIversion\fR?
+\fBpackage require\fR \fIpackage \fR?\fIrequirement...\fR?
This command is typically invoked by Tcl code that wishes to use
a particular version of a particular package. The arguments
indicate which package is wanted, and the command ensures that
a suitable version of the package is loaded into the interpreter.
If the command succeeds, it returns the version number that is
loaded; otherwise it generates an error.
-If both the \fB\-exact\fR
-switch and the \fIversion\fR argument are specified then only the
-given version is acceptable. If \fB\-exact\fR is omitted but
-\fIversion\fR is specified, then versions later than \fIversion\fR
-are also acceptable as long as they have the same major version
-number as \fIversion\fR.
-If both \fB\-exact\fR and \fIversion\fR are omitted then any
-version whatsoever is acceptable.
+.RS
+.PP
+A suitable version of the package is any version which satisfies at
+least one of the requirements, per the rules of \fBpackage
+vsatisfies\fR. If multiple versions are suitable the implementation
+with the highest version is chosen. This last part is additionally
+influenced by the selection mode set with \fBpackage prefer\fR.
+.PP
+In the
+.QW stable
+selection mode the command will select the highest
+stable version satisfying the requirements, if any. If no stable
+version satisfies the requirements, the highest unstable version
+satisfying the requirements will be selected. In the
+.QW latest
+selection mode the command will accept the highest version satisfying
+all the requirements, regardless of its stableness.
+.PP
If a version of \fIpackage\fR has already been provided (by invoking
the \fBpackage provide\fR command), then its version number must
-satisfy the criteria given by \fB\-exact\fR and \fIversion\fR and
-the command returns immediately.
+satisfy the \fIrequirement\fRs and the command returns immediately.
Otherwise, the command searches the database of information provided by
previous \fBpackage ifneeded\fR commands to see if an acceptable
version of the package is available.
@@ -124,20 +137,28 @@ it completes, Tcl checks again to see if the package is now provided
or if there is a \fBpackage ifneeded\fR script for it.
If all of these steps fail to provide an acceptable version of the
package, then the command returns an error.
+.RE
+.TP
+\fBpackage require \-exact \fIpackage version\fR
+This form of the command is used when only the given \fIversion\fR
+of \fIpackage\fR is acceptable to the caller. This command is
+equivalent to \fBpackage require \fIpackage version\fR-\fIversion\fR.
.TP
\fBpackage unknown \fR?\fIcommand\fR?
-This command supplies a ``last resort'' command to invoke during
+This command supplies a
+.QW "last resort"
+command to invoke during
\fBpackage require\fR if no suitable version of a package can be found
in the \fBpackage ifneeded\fR database.
If the \fIcommand\fR argument is supplied, it contains the first part
of a command; when the command is invoked during a \fBpackage require\fR
-command, Tcl appends two additional arguments giving the desired package
-name and version.
+command, Tcl appends one or more additional arguments giving the desired
+package name and requirements.
For example, if \fIcommand\fR is \fBfoo bar\fR and later the command
\fBpackage require test 2.4\fR is invoked, then Tcl will execute
the command \fBfoo bar test 2.4\fR to load the package.
-If no version number is supplied to the \fBpackage require\fR command,
-then the version argument for the invoked command will be an empty string.
+If no requirements are supplied to the \fBpackage require\fR command,
+then only the name will be added to invoked command.
If the \fBpackage unknown\fR command is invoked without a \fIcommand\fR
argument, then the current \fBpackage unknown\fR script is returned,
or an empty string if there is none.
@@ -154,11 +175,107 @@ Returns a list of all the version numbers of \fIpackage\fR
for which information has been provided by \fBpackage ifneeded\fR
commands.
.TP
-\fBpackage vsatisfies \fIversion1 version2\fR
-Returns 1 if scripts written for \fIversion2\fR will work unchanged
-with \fIversion1\fR (i.e. \fIversion1\fR is equal to or greater
-than \fIversion2\fR and they both have the same major version
-number), 0 otherwise.
+\fBpackage vsatisfies \fIversion requirement...\fR
+Returns 1 if the \fIversion\fR satisfies at least one of the given
+requirements, and 0 otherwise. Each \fIrequirement\fR is allowed to
+have any of the forms:
+.RS
+.TP
+min
+This form is called
+.QW min-bounded .
+.TP
+min-
+This form is called
+.QW min-unbound .
+.TP
+min-max
+This form is called
+.QW bounded .
+.RE
+.RS
+.PP
+where
+.QW min
+and
+.QW max
+are valid version numbers. The legacy syntax is
+a special case of the extended syntax, keeping backward
+compatibility. Regarding satisfaction the rules are:
+.RE
+.RS
+.IP [1]
+The \fIversion\fR has to pass at least one of the listed
+\fIrequirement\fRs to be satisfactory.
+.IP [2]
+A version satisfies a
+.QW bounded
+requirement when
+.RS
+.IP [a]
+For \fImin\fR equal to the \fImax\fR if, and only if the \fIversion\fR
+is equal to the \fImin\fR.
+.IP [b]
+Otherwise if, and only if the \fIversion\fR is greater than or equal
+to the \fImin\fR, and less than the \fImax\fR, where both \fImin\fR
+and \fImax\fR have been padded internally with
+.QW a0 .
+Note that while the comparison to \fImin\fR is inclusive, the
+comparison to \fImax\fR is exclusive.
+.RE
+.IP [3]
+A
+.QW min-bounded
+requirement is a
+.QW bounded
+requirement in disguise,
+with the \fImax\fR part implicitly specified as the next higher major
+version number of the \fImin\fR part. A version satisfies it per the
+rules above.
+.IP [4]
+A \fIversion\fR satisfies a
+.QW min-unbound
+requirement if, and only if it is greater than or equal to the
+\fImin\fR, where the \fImin\fR has been padded internally with
+.QW a0 .
+There is no constraint to a maximum.
+.RE
+.TP
+\fBpackage prefer \fR?\fBlatest\fR|\fBstable\fR?
+With no arguments, the commands returns either
+.QW latest
+or
+.QW stable ,
+whichever describes the current mode of selection logic used by
+\fBpackage require\fR.
+.RS
+.PP
+When passed the argument
+.QW latest ,
+it sets the selection logic mode to
+.QW latest .
+.PP
+When passed the argument
+.QW stable ,
+if the mode is already
+.QW stable ,
+that value is kept. If the mode is already
+.QW latest ,
+then the attempt to set it back to
+.QW stable
+is ineffective and the mode value remains
+.QW latest .
+.PP
+When passed any other value as an argument, raise an invalid argument
+error.
+.PP
+When an interpreter is created, its initial selection mode value is set to
+.QW stable
+unless the environment variable \fBTCL_PKG_PREFER_LATEST\fR
+is set. If that environment variable is defined (with any value) then
+the initial (and permanent) selection mode value is set to
+.QW latest .
+.RE
.SH "VERSION NUMBERS"
.PP
Version numbers consist of one or more decimal numbers separated
@@ -170,6 +287,30 @@ For example, version 2.1 is later than 1.3 and version
3.4.6 is later than 3.3.5.
Missing fields are equivalent to zeroes: version 1.3 is the
same as version 1.3.0 and 1.3.0.0, so it is earlier than 1.3.1 or 1.3.0.2.
+In addition, the letters
+.QW a
+(alpha) and/or
+.QW b
+(beta) may appear
+exactly once to replace a dot for separation. These letters
+semantically add a negative specifier into the version, where
+.QW a
+is \-2, and
+.QW b
+is \-1. Each may be specified only once, and
+.QW a
+or
+.QW b
+are mutually exclusive in a specifier. Thus 1.3a1 becomes (semantically)
+1.3.\-2.1, 1.3b1 is 1.3.\-1.1. Negative numbers are not directly allowed
+in version specifiers.
+A version number not containing the letters
+.QW a
+or
+.QW b
+as specified
+above is called a \fBstable\fR version, whereas presence of the letters
+causes the version to be called is \fBunstable\fR.
A later version number is assumed to be upwards compatible with
an earlier version number as long as both versions have the same
major version number.
@@ -183,7 +324,7 @@ to work unmodified with either version 1.7.3 or version 3.1.
The recommended way to use packages in Tcl is to invoke \fBpackage require\fR
and \fBpackage provide\fR commands in scripts, and use the procedure
\fBpkg_mkIndex\fR to create package index files.
-Once you've done this, packages will be loaded automatically
+Once you have done this, packages will be loaded automatically
in response to \fBpackage require\fR commands.
See the documentation for \fBpkg_mkIndex\fR for details.
.SH EXAMPLES
@@ -205,9 +346,7 @@ if {[catch {\fBpackage require\fR Snack}]} {
# We have the package, configure the app to use it
}
.CE
-
.SH "SEE ALSO"
msgcat(n), packagens(n), pkgMkIndex(n)
-
.SH KEYWORDS
package, version
diff --git a/doc/packagens.n b/doc/packagens.n
index a0386f2..1220b20 100644
--- a/doc/packagens.n
+++ b/doc/packagens.n
@@ -7,8 +7,7 @@
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
-pkg::create \- Construct an appropriate \fBpackage ifneeded\fR
-command for a given package specification
+pkg::create \- Construct an appropriate 'package ifneeded' command for a given package specification
.SH SYNOPSIS
\fB::pkg::create \fI\-name packageName\fR \fI\-version packageVersion\fR ?\fI\-load filespec\fR? ... ?\fI\-source filespec\fR? ...
.BE
@@ -45,9 +44,7 @@ specifies a Tcl library that must be loaded with the
specified.
.PP
At least one \fB\-load\fR or \fB\-source\fR parameter must be given.
-
.SH "SEE ALSO"
package(n)
-
.SH KEYWORDS
auto-load, index, package, version
diff --git a/doc/pid.n b/doc/pid.n
index 1001ddc..97a42a7 100644
--- a/doc/pid.n
+++ b/doc/pid.n
@@ -23,7 +23,7 @@ In this case the \fBpid\fR command will return a list whose elements
are the process identifiers of all the processes in the pipeline,
in order.
The list will be empty if \fIfileId\fR refers to an open file
-that isn't a process pipeline.
+that is not a process pipeline.
If no \fIfileId\fR argument is given then \fBpid\fR returns the process
identifier of the current process.
All process identifiers are returned as decimal strings.
diff --git a/doc/pkgMkIndex.n b/doc/pkgMkIndex.n
index d0ea771..5895407 100644
--- a/doc/pkgMkIndex.n
+++ b/doc/pkgMkIndex.n
@@ -12,12 +12,9 @@
pkg_mkIndex \- Build an index for automatic loading of packages
.SH SYNOPSIS
.nf
-.VS 8.3.0
\fBpkg_mkIndex ?\fI\-direct\fR? ?\fI\-lazy\fR? ?\fI\-load pkgPat\fR? ?\fI\-verbose\fR? \fIdir\fR ?\fIpattern pattern ...\fR?
-.VE
.fi
.BE
-
.SH DESCRIPTION
.PP
\fBPkg_mkIndex\fR is a utility procedure that is part of the standard
@@ -39,10 +36,9 @@ Create the index by invoking \fBpkg_mkIndex\fR.
The \fIdir\fR argument gives the name of a directory and each
\fIpattern\fR argument is a \fBglob\fR-style pattern that selects
script or binary files in \fIdir\fR.
-.VS 8.0.3
The default pattern is \fB*.tcl\fR and \fB*.[info sharedlibextension]\fR.
-.VE
-.br
+.RS
+.PP
\fBPkg_mkIndex\fR will create a file \fBpkgIndex.tcl\fR in \fIdir\fR
with package information about all the files given by the \fIpattern\fR
arguments.
@@ -53,10 +49,10 @@ and new commands appear (this is why it is essential to have
in the files, as described above).
If you have a package split among scripts and binary files,
or if you have dependencies among files,
-you may have to use the \fB\-load\fP option
+you may have to use the \fB\-load\fR option
or adjust the order in which \fBpkg_mkIndex\fR processes
-the files. See COMPLEX CASES below.
-
+the files. See \fBCOMPLEX CASES\fR below.
+.RE
.IP [3]
Install the package as a subdirectory of one of the directories given by
the \fBtcl_pkgPath\fR variable. If \fB$tcl_pkgPath\fR contains more
@@ -70,7 +66,8 @@ the package's script and/or binary files as well as the \fBpkgIndex.tcl\fR
file. As long as the package is installed as a subdirectory of a
directory in \fB$tcl_pkgPath\fR it will automatically be found during
\fBpackage require\fR commands.
-.br
+.RS
+.PP
If you install the package anywhere else, then you must ensure that
the directory containing the package is in the \fBauto_path\fR global variable
or an immediate subdirectory of one of the directories in \fBauto_path\fR.
@@ -83,6 +80,7 @@ You can add a directory to \fBauto_path\fR explicitly in your
application, or you can add the directory to your \fBTCLLIBPATH\fR
environment variable: if this environment variable is present,
Tcl initializes \fBauto_path\fR from it during application startup.
+.RE
.IP [4]
Once the above steps have been taken, all you need to do to use a
package is to invoke \fBpackage require\fR.
@@ -96,7 +94,6 @@ in \fBauto_path\fR, but only one will actually be loaded in a given
interpreter, based on the first call to \fBpackage require\fR.
Different versions of a package may be loaded in different
interpreters.
-
.SH OPTIONS
The optional switches are:
.TP 15
@@ -107,22 +104,22 @@ upon \fBpackage require\fR. This is the default.
\fB\-lazy\fR
The generated index will manage to delay loading the package until the
use of one of the commands provided by the package, instead of loading
-it immediately upon \fBpackage require\fR.
+it immediately upon \fBpackage require\fR. This is not compatible with
+the use of \fIauto_reset\fR, and therefore its use is discouraged.
.TP 15
\fB\-load \fIpkgPat\fR
The index process will pre-load any packages that exist in the
-current interpreter and match \fIpkgPat\fP into the slave interpreter used to
+current interpreter and match \fIpkgPat\fR into the slave interpreter used to
generate the index. The pattern match uses string match rules, but without
making case distinctions.
See COMPLEX CASES below.
.TP 15
\fB\-verbose\fR
Generate output during the indexing process. Output is via
-the \fBtclLog\fP procedure, which by default prints to stderr.
+the \fBtclLog\fR procedure, which by default prints to stderr.
.TP 15
\fB\-\-\fR
-End of the flags, in case \fIdir\fP begins with a dash.
-
+End of the flags, in case \fIdir\fR begins with a dash.
.SH "PACKAGES AND THE AUTO-LOADER"
.PP
The package management facilities overlap somewhat with the auto-loader,
@@ -142,7 +139,6 @@ If you use \fBpkg_mkIndex\fR to index a package, its commands cannot
be invoked until \fBpackage require\fR has been used to select a
version; in contrast, packages indexed with \fBauto_mkindex\fR
can be used immediately since there is no version control.
-
.SH "HOW IT WORKS"
.PP
\fBPkg_mkIndex\fR depends on the \fBpackage unknown\fR command,
@@ -157,18 +153,14 @@ commands for each version of each available package; these commands
invoke \fBpackage provide\fR commands to announce the
availability of the package, and they setup auto-loader
information to load the files of the package.
-.VS 8.3
If the \fI\-lazy\fR flag was provided when the \fBpkgIndex.tcl\fR
was generated,
-.VE
-a given file of a given version of a given package isn't
+a given file of a given version of a given package is not
actually loaded until the first time one of its commands
is invoked.
Thus, after invoking \fBpackage require\fR you may
not see the package's commands in the interpreter, but you will be able
to invoke the commands and they will be auto-loaded.
-
-.VS 8.3
.SH "DIRECT LOADING"
.PP
Some packages, for instance packages which use namespaces and export
@@ -177,8 +169,6 @@ that their package files be loaded immediately upon \fBpackage require\fR
instead of delaying the actual loading to the first use of one of the
package's command. This is the default mode when generating the package
index. It can be overridden by specifying the \fI\-lazy\fR argument.
-.VE
-
.SH "COMPLEX CASES"
Most complex cases of dependencies among scripts
and binary files, and packages being split among scripts and
@@ -193,28 +183,28 @@ with some glob patterns.
.PP
In general, it is OK for scripts to have dependencies on other
packages.
-If scripts contain \fBpackage require\fP commands, these are
+If scripts contain \fBpackage require\fR commands, these are
stubbed out in the interpreter used to process the scripts,
so these do not cause problems.
If scripts call into other packages in global code,
-these calls are handled by a stub \fBunknown\fP command.
+these calls are handled by a stub \fBunknown\fR command.
However, if scripts make variable references to other package's
variables in global code, these will cause errors. That is
also bad coding style.
.PP
If binary files have dependencies on other packages, things
can become tricky because it is not possible to stub out
-C-level APIs such as \fBTcl_PkgRequire\fP API
+C-level APIs such as \fBTcl_PkgRequire\fR API
when loading a binary file.
For example, suppose the BLT package requires Tk, and expresses
-this with a call to \fBTcl_PkgRequire\fP in its \fBBlt_Init\fP routine.
+this with a call to \fBTcl_PkgRequire\fR in its \fBBlt_Init\fR routine.
To support this, you must run \fBpkg_mkIndex\fR in an interpreter that
has Tk loaded. You can achieve this with the
\fB\-load \fIpkgPat\fR option. If you specify this option,
\fBpkg_mkIndex\fR will load any packages listed by
-\fBinfo loaded\fP and that match \fIpkgPat\fP
+\fBinfo loaded\fR and that match \fIpkgPat\fR
into the interpreter used to process files.
-In most cases this will satisfy the \fBTcl_PkgRequire\fP calls
+In most cases this will satisfy the \fBTcl_PkgRequire\fR calls
made by binary files.
.PP
If you are indexing two binary files and one depends on the other,
@@ -224,19 +214,17 @@ and then the package it provides
will be available when the second file is processed.
You may also need to load the first package into the
temporary interpreter used to create the index by using
-the \fB\-load\fP flag;
-it won't hurt to specify package patterns that are not yet loaded.
+the \fB\-load\fR flag;
+it will not hurt to specify package patterns that are not yet loaded.
.PP
If you have a package that is split across scripts and a binary file,
-then you should avoid the \fB\-load\fP flag. The problem is that
+then you should avoid the \fB\-load\fR flag. The problem is that
if you load a package before computing the index it masks any
other files that provide part of the same package.
-If you must use \fB\-load\fP,
+If you must use \fB\-load\fR,
then you must specify the scripts first; otherwise the package loaded from
the binary file may mask the package defined by the scripts.
-
.SH "SEE ALSO"
package(n)
-
.SH KEYWORDS
auto-load, index, package, version
diff --git a/doc/platform.n b/doc/platform.n
new file mode 100644
index 0000000..053448d
--- /dev/null
+++ b/doc/platform.n
@@ -0,0 +1,66 @@
+'\"
+'\" Copyright (c) 2006 ActiveState Software Inc
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.TH "platform" n 1.0.4 platform "Tcl Bundled Packages"
+.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
+.sp
+\fBplatform::generic\fR
+\fBplatform::identify\fR
+\fBplatform::patterns \fIidentifier\fR
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBplatform\fR package provides several utility commands useful
+for the identification of the architecture of a machine running Tcl.
+.PP
+Whilst Tcl provides the \fBtcl_platform\fR array for identifying the
+current architecture (in particular, the platform and machine
+elements) this is not always sufficient. This is because (on Unix
+machines) \fBtcl_platform\fR reflects the values returned by the
+\fBuname\fR command and these are not standardized across platforms and
+architectures. In addition, on at least one platform (AIX) the
+\fBtcl_platform(machine)\fR contains the CPU serial number.
+.PP
+Consequently, individual applications need to manipulate the values in
+\fBtcl_platform\fR (along with the output of system specific
+utilities) - which is both inconvenient for developers, and introduces
+the potential for inconsistencies in identifying architectures and in
+naming conventions.
+.PP
+The \fBplatform\fR package prevents such fragmentation - i.e., it
+establishes a standard naming convention for architectures running Tcl
+and makes it more convenient for developers to identify the current
+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
+details like kernel version, libc version, etc., and this information
+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
+This command takes an identifier as returned by
+\fBplatform::identify\fR and returns a list of identifiers describing
+compatible architectures.
+.SH KEYWORDS
+operating system, cpu architecture, platform, architecture
diff --git a/doc/platform_shell.n b/doc/platform_shell.n
new file mode 100644
index 0000000..eef4d4e
--- /dev/null
+++ b/doc/platform_shell.n
@@ -0,0 +1,57 @@
+'\"
+'\" Copyright (c) 2006-2008 ActiveState Software Inc
+'\"
+'\" 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"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+platform::shell \- System identification support code and utilities
+.SH SYNOPSIS
+.nf
+\fBpackage require platform::shell ?1.1.4?\fR
+.sp
+\fBplatform::shell::generic \fIshell\fR
+\fBplatform::shell::identify \fIshell\fR
+\fBplatform::shell::platform \fIshell\fR
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBplatform::shell\fR package provides several utility commands useful
+for the identification of the architecture of a specific Tcl shell.
+.PP
+This package allows the identification of the architecture of a
+specific Tcl shell different from the shell running the package. The
+only requirement is that the other shell (identified by its path), is
+actually executable on the current machine.
+.PP
+While for most platform this means that the architecture of the
+interrogated shell is identical to the architecture of the running
+shell this is not generally true. A counter example are all platforms
+which have 32 and 64 bit variants and where a 64bit system is able to
+run 32bit code. For these running and interrogated shell may have
+different 32/64 bit settings and thus different identifiers.
+.PP
+For applications like a code repository it is important to identify
+the architecture of the shell which will actually run the installed
+packages, versus the architecture of the shell running the repository
+software.
+.SH COMMANDS
+.TP
+\fBplatform::shell::identify \fIshell\fR
+This command does the same identification as \fBplatform::identify\fR,
+for the specified Tcl shell, in contrast to the running shell.
+.TP
+\fBplatform::shell::generic \fIshell\fR
+This command does the same identification as \fBplatform::generic\fR,
+for the specified Tcl shell, in contrast to the running shell.
+.TP
+\fBplatform::shell::platform \fIshell\fR
+This command returns the contents of \fBtcl_platform(platform)\fR for
+the specified Tcl shell.
+.SH KEYWORDS
+operating system, cpu architecture, platform, architecture
diff --git a/doc/proc.n b/doc/proc.n
index c335b3e..4525207 100644
--- a/doc/proc.n
+++ b/doc/proc.n
@@ -33,17 +33,25 @@ elements specifies
one argument. Each argument specifier is also a list with either
one or two fields. If there is only a single field in the specifier
then it is the name of the argument; if there are two fields, then
-the first is the argument name and the second is its default value.
+the first is the argument name and the second is its default value.
+Arguments with default values that are followed by non-defaulted
+arguments become required arguments. In 8.6 this will be considered an
+error.
.PP
When \fIname\fR is invoked a local variable
will be created for each of the formal arguments to the procedure; its
value will be the value of corresponding argument in the invoking command
or the argument's default value.
+Actual arguments are assigned to formal arguments strictly in order.
Arguments with default values need not be
specified in a procedure invocation. However, there must be enough
actual arguments for all the
-formal arguments that don't have defaults, and there must not be any extra
-actual arguments. There is one special case to permit procedures with
+formal arguments that do not have defaults, and there must not be any extra
+actual arguments.
+Arguments with default values that are followed by non-defaulted
+arguments become required arguments (in 8.6 it will be considered an
+error).
+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
@@ -55,14 +63,12 @@ When \fIbody\fR is being executed, variable names normally refer to
local variables, which are created automatically when referenced and
deleted when the procedure returns. One local variable is automatically
created for each of the procedure's arguments.
-Global variables can only be accessed by invoking
-the \fBglobal\fR command or the \fBupvar\fR command.
-Namespace variables can only be accessed by invoking
-the \fBvariable\fR command or the \fBupvar\fR command.
+Other variables can only be accessed by invoking one of the \fBglobal\fR,
+\fBvariable\fR, \fBupvar\fR or \fBnamespace upvar\fR commands.
.PP
The \fBproc\fR command returns an empty string. When a procedure is
invoked, the procedure's return value is the value specified in a
-\fBreturn\fR command. If the procedure doesn't execute an explicit
+\fBreturn\fR command. If the procedure does not execute an explicit
\fBreturn\fR, then its return value is the value of the last command
executed in the procedure's body.
If an error occurs while executing the procedure
diff --git a/doc/puts.n b/doc/puts.n
index 9fa5f15..5cd8721 100644
--- a/doc/puts.n
+++ b/doc/puts.n
@@ -20,13 +20,11 @@ puts \- Write to a channel
Writes the characters given by \fIstring\fR to the channel given
by \fIchannelId\fR.
.PP
-.VS
\fIChannelId\fR must be an identifier for an open channel such as a
Tcl standard channel (\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. The channel
must have been opened for output.
-.VE
.PP
If no \fIchannelId\fR is specified then it defaults to
\fBstdout\fR. \fBPuts\fR normally outputs a newline character after
@@ -37,8 +35,7 @@ Newline characters in the output are translated by \fBputs\fR to
platform-specific end-of-line sequences according to the current
value of the \fB\-translation\fR option for the channel (for example,
on PCs newlines are normally replaced with carriage-return-linefeed
-sequences; on Macintoshes newlines are normally replaced with
-carriage-returns).
+sequences.
See the \fBfconfigure\fR manual entry for a discussion on ways in
which \fBfconfigure\fR will alter output.
.PP
@@ -64,7 +61,7 @@ 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 used in an event-driven fashion with the \fBfileevent\fR command
-(don't invoke \fBputs\fR unless you have recently been notified
+(do not invoke \fBputs\fR unless you have recently been notified
via a file event that the channel is ready for more output data).
.SH EXAMPLES
Write a short message to the console (or wherever \fBstdout\fR is
diff --git a/doc/pwd.n b/doc/pwd.n
index 99a438f..e63b815 100644
--- a/doc/pwd.n
+++ b/doc/pwd.n
@@ -22,7 +22,7 @@ Returns the absolute path name of the current working directory.
Sometimes it is useful to change to a known directory when running
some external command using \fBexec\fR, but it is important to keep
the application usually running in the directory that it was started
-in (unless the user specifies otherwise) since that minimises user
+in (unless the user specifies otherwise) since that minimizes user
confusion. The way to do this is to save the current directory while
the external command is being run:
.CS
@@ -32,7 +32,6 @@ cd /tmp
exec tar -xf $tarFile
cd $savedDir
.CE
-
.SH "SEE ALSO"
file(n), cd(n), glob(n), filename(n)
diff --git a/doc/re_syntax.n b/doc/re_syntax.n
index 8ec2deb..8701641 100644
--- a/doc/re_syntax.n
+++ b/doc/re_syntax.n
@@ -9,922 +9,820 @@
.TH re_syntax n "8.1" Tcl "Tcl Built-In Commands"
.BS
.SH NAME
-re_syntax \- Syntax of Tcl regular expressions.
+re_syntax \- Syntax of Tcl regular expressions
.BE
-
.SH DESCRIPTION
.PP
A \fIregular expression\fR describes strings of characters.
-It's a pattern that matches certain strings and doesn't match others.
-
+It's a pattern that matches certain strings and does not match others.
.SH "DIFFERENT FLAVORS OF REs"
-Regular expressions (``RE''s), as defined by POSIX, come in two
-flavors: \fIextended\fR REs (``EREs'') and \fIbasic\fR REs (``BREs'').
+Regular expressions
+.PQ RE s ,
+as defined by POSIX, come in two flavors: \fIextended\fR REs
+.PQ ERE s
+and \fIbasic\fR REs
+.PQ BRE s .
EREs are roughly those of the traditional \fIegrep\fR, while BREs are
-roughly those of the traditional \fIed\fR. This implementation adds
-a third flavor, \fIadvanced\fR REs (``AREs''), basically EREs with
-some significant extensions.
+roughly those of the traditional \fIed\fR. This implementation adds
+a third flavor, \fIadvanced\fR REs
+.PQ ARE s ,
+basically EREs with some significant extensions.
.PP
-This manual page primarily describes AREs. BREs mostly exist for
+This manual page primarily describes AREs. BREs mostly exist for
backward compatibility in some old programs; they will be discussed at
-the end. POSIX EREs are almost an exact subset of AREs. Features of
+the end. POSIX EREs are almost an exact subset of AREs. Features of
AREs that are not present in EREs will be indicated.
-
.SH "REGULAR EXPRESSION SYNTAX"
.PP
Tcl regular expressions are implemented using the package written by
Henry Spencer, based on the 1003.2 spec and some (not quite all) of
-the Perl5 extensions (thanks, Henry!). Much of the description of
+the Perl5 extensions (thanks, Henry!). Much of the description of
regular expressions below is copied verbatim from his manual entry.
.PP
An ARE is one or more \fIbranches\fR,
-separated by `\fB|\fR',
+separated by
+.QW \fB|\fR ,
matching anything that matches any of the branches.
.PP
A branch is zero or more \fIconstraints\fR or \fIquantified atoms\fR,
concatenated.
It matches a match for the first, followed by a match for the second, etc;
an empty branch matches the empty string.
-.PP
+.SS QUANTIFIERS
A quantified atom is an \fIatom\fR possibly followed
by a single \fIquantifier\fR.
-Without a quantifier, it matches a match for the atom.
+Without a quantifier, it matches a single match for the atom.
The quantifiers,
and what a so-quantified atom matches, are:
.RS 2
.TP 6
\fB*\fR
+.
a sequence of 0 or more matches of the atom
.TP
\fB+\fR
+.
a sequence of 1 or more matches of the atom
.TP
\fB?\fR
+.
a sequence of 0 or 1 matches of the atom
.TP
\fB{\fIm\fB}\fR
+.
a sequence of exactly \fIm\fR matches of the atom
.TP
\fB{\fIm\fB,}\fR
+.
a sequence of \fIm\fR or more matches of the atom
.TP
\fB{\fIm\fB,\fIn\fB}\fR
+.
a sequence of \fIm\fR through \fIn\fR (inclusive) matches of the atom;
\fIm\fR may not exceed \fIn\fR
.TP
\fB*? +? ?? {\fIm\fB}? {\fIm\fB,}? {\fIm\fB,\fIn\fB}?\fR
-\fInon-greedy\fR quantifiers,
-which match the same possibilities,
+.
+\fInon-greedy\fR quantifiers, which match the same possibilities,
but prefer the smallest number rather than the largest number
-of matches (see MATCHING)
+of matches (see \fBMATCHING\fR)
.RE
.PP
-The forms using
-\fB{\fR and \fB}\fR
-are known as \fIbound\fRs.
-The numbers
-\fIm\fR and \fIn\fR are unsigned decimal integers
-with permissible values from 0 to 255 inclusive.
-.PP
+The forms using \fB{\fR and \fB}\fR are known as \fIbound\fRs. The
+numbers \fIm\fR and \fIn\fR are unsigned decimal integers with
+permissible values from 0 to 255 inclusive.
+.SS ATOMS
An atom is one of:
.RS 2
-.TP 6
-\fB(\fIre\fB)\fR
-(where \fIre\fR is any regular expression)
-matches a match for
-\fIre\fR, with the match noted for possible reporting
-.TP
-\fB(?:\fIre\fB)\fR
-as previous,
-but does no reporting
-(a ``non-capturing'' set of parentheses)
-.TP
-\fB()\fR
-matches an empty string,
-noted for possible reporting
-.TP
-\fB(?:)\fR
-matches an empty string,
-without reporting
-.TP
-\fB[\fIchars\fB]\fR
-a \fIbracket expression\fR,
-matching any one of the \fIchars\fR (see BRACKET EXPRESSIONS for more detail)
-.TP
- \fB.\fR
+.IP \fB(\fIre\fB)\fR 6
+matches a match for \fIre\fR (\fIre\fR is any regular expression) with
+the match noted for possible reporting
+.IP \fB(?:\fIre\fB)\fR
+as previous, but does no reporting (a
+.QW non-capturing
+set of parentheses)
+.IP \fB()\fR
+matches an empty string, noted for possible reporting
+.IP \fB(?:)\fR
+matches an empty string, without reporting
+.IP \fB[\fIchars\fB]\fR
+a \fIbracket expression\fR, matching any one of the \fIchars\fR (see
+\fBBRACKET EXPRESSIONS\fR for more detail)
+.IP \fB.\fR
matches any single character
-.TP
-\fB\e\fIk\fR
-(where \fIk\fR is a non-alphanumeric character)
-matches that character taken as an ordinary character,
-e.g. \e\e matches a backslash character
-.TP
-\fB\e\fIc\fR
-where \fIc\fR is alphanumeric
-(possibly followed by other characters),
-an \fIescape\fR (AREs only),
-see ESCAPES below
-.TP
-\fB{\fR
-when followed by a character other than a digit,
-matches the left-brace character `\fB{\fR';
-when followed by a digit, it is the beginning of a
-\fIbound\fR (see above)
-.TP
-\fIx\fR
-where \fIx\fR is
-a single character with no other significance, matches that character.
+.IP \fB\e\fIk\fR
+matches the non-alphanumeric character \fIk\fR
+taken as an ordinary character, e.g. \fB\e\e\fR matches a backslash
+character
+.IP \fB\e\fIc\fR
+where \fIc\fR is alphanumeric (possibly followed by other characters),
+an \fIescape\fR (AREs only), see \fBESCAPES\fR below
+.IP \fB{\fR
+when followed by a character other than a digit, matches the
+left-brace character
+.QW \fB{\fR ;
+when followed by a digit, it is the beginning of a \fIbound\fR (see above)
+.IP \fIx\fR
+where \fIx\fR is a single character with no other significance,
+matches that character.
.RE
-.PP
+.SS CONSTRAINTS
A \fIconstraint\fR matches an empty string when specific conditions
-are met.
-A constraint may not be followed by a quantifier.
-The simple constraints are as follows; some more constraints are
-described later, under ESCAPES.
+are met. A constraint may not be followed by a quantifier. The
+simple constraints are as follows; some more constraints are described
+later, under \fBESCAPES\fR.
.RS 2
.TP 8
\fB^\fR
+.
matches at the beginning of a line
.TP
\fB$\fR
+.
matches at the end of a line
.TP
\fB(?=\fIre\fB)\fR
-\fIpositive lookahead\fR (AREs only), matches at any point
-where a substring matching \fIre\fR begins
+.
+\fIpositive lookahead\fR (AREs only), matches at any point where a
+substring matching \fIre\fR begins
.TP
\fB(?!\fIre\fB)\fR
-\fInegative lookahead\fR (AREs only), matches at any point
-where no substring matching \fIre\fR begins
+.
+\fInegative lookahead\fR (AREs only), matches at any point where no
+substring matching \fIre\fR begins
.RE
.PP
The lookahead constraints may not contain back references (see later),
and all parentheses within them are considered non-capturing.
.PP
-An RE may not end with `\fB\e\fR'.
-
+An RE may not end with
+.QW \fB\e\fR .
.SH "BRACKET EXPRESSIONS"
-A \fIbracket expression\fR is a list of characters enclosed in `\fB[\|]\fR'.
-It normally matches any single character from the list (but see below).
-If the list begins with `\fB^\fR',
-it matches any single character
-(but see below) \fInot\fR from the rest of the list.
-.PP
-If two characters in the list are separated by `\fB\-\fR',
-this is shorthand
-for the full \fIrange\fR of characters between those two (inclusive) in the
-collating sequence,
-e.g.
-\fB[0\-9]\fR
-in ASCII matches any decimal digit.
-Two ranges may not share an
+A \fIbracket expression\fR is a list of characters enclosed in
+.QW \fB[\|]\fR .
+It normally matches any single character from the list
+(but see below). If the list begins with
+.QW \fB^\fR ,
+it matches any single character (but see below) \fInot\fR from the
+rest of the list.
+.PP
+If two characters in the list are separated by
+.QW \fB\-\fR ,
+this is shorthand for the full \fIrange\fR of characters between those two
+(inclusive) in the collating sequence, e.g.
+.QW \fB[0\-9]\fR
+in Unicode matches any conventional decimal digit. Two ranges may not share an
endpoint, so e.g.
-\fBa\-c\-e\fR
-is illegal.
-Ranges are very collating-sequence-dependent,
-and portable programs should avoid relying on them.
-.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 collating element (see below).
-Alternatively,
-make it the first character
-(following a possible `\fB^\fR'),
-or (AREs only) precede it with `\fB\e\fR'.
-Alternatively, for `\fB\-\fR',
-make it the last character,
-or the second endpoint of a range.
-To use a literal
-\fB\-\fR
-as the first endpoint of a range,
-make it a collating element
-or (AREs only) precede it with `\fB\e\fR'.
-With the exception of these, some combinations using
-\fB[\fR
-(see next
-paragraphs), and escapes,
-all other special characters lose their
-special significance within a bracket expression.
-.PP
-Within a bracket expression, a collating element (a character,
-a multi-character sequence that collates as if it were a single character,
-or a collating-sequence name for either)
-enclosed in
-\fB[.\fR and \fB.]\fR
-stands for the
-sequence of characters of that collating element.
-The sequence is a single element of the bracket expression's list.
-A bracket expression in a locale that has
-multi-character collating elements
-can thus match more than one character.
-.VS 8.2
-So (insidiously), a bracket expression that starts with \fB^\fR
-can match multi-character collating elements even if none of them
-appear in the bracket expression!
-(\fINote:\fR Tcl currently has no multi-character collating elements.
-This information is only for illustration.)
-.PP
-For example, assume the collating sequence includes a \fBch\fR
-multi-character collating element.
-Then the RE \fB[[.ch.]]*c\fR (zero or more \fBch\fP's followed by \fBc\fP)
-matches the first five characters of `\fBchchcc\fR'.
-Also, the RE \fB[^c]b\fR matches all of `\fBchb\fR'
-(because \fB[^c]\fR matches the multi-character \fBch\fR).
-.VE 8.2
-.PP
-Within a bracket expression, a collating element enclosed in
-\fB[=\fR
-and
-\fB=]\fR
-is an equivalence class, standing for the sequences of characters
-of all collating elements equivalent to that one, including itself.
-(If there are no other equivalent collating elements,
-the treatment is as if the enclosing delimiters were `\fB[.\fR'\&
-and `\fB.]\fR'.)
-For example, if
-\fBo\fR
-and
-\fB\o'o^'\fR
-are the members of an equivalence class,
-then `\fB[[=o=]]\fR', `\fB[[=\o'o^'=]]\fR',
-and `\fB[o\o'o^']\fR'\&
-are all synonymous.
-An equivalence class may not be an endpoint
-of a range.
-.VS 8.2
-(\fINote:\fR
-Tcl currently implements only the Unicode locale.
-It doesn't define any equivalence classes.
-The examples above are just illustrations.)
-.VE 8.2
-.PP
-Within a bracket expression, the name of a \fIcharacter class\fR enclosed
-in
-\fB[:\fR
-and
-\fB:]\fR
-stands for the list of all characters
-(not all collating elements!)
-belonging to that
-class.
+.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.
+.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
+collating element (see below). Alternatively, make it the first
+character (following a possible
+.QW \fB^\fR ),
+or (AREs only) precede it with
+.QW \fB\e\fR .
+Alternatively, for
+.QW \fB\-\fR ,
+make it the last character, or the second endpoint of a range. To use
+a literal \fB\-\fR as the first endpoint of a range, make it a
+collating element or (AREs only) precede it with
+.QW \fB\e\fR .
+With the exception of
+these, some combinations using \fB[\fR (see next paragraphs), and
+escapes, all other special characters lose their special significance
+within a bracket expression.
+.SS "CHARACTER CLASSES"
+Within a bracket expression, the name of a \fIcharacter class\fR
+enclosed in \fB[:\fR and \fB:]\fR stands for the list of all
+characters (not all collating elements!) belonging to that class.
Standard character classes are:
-.PP
+.IP \fBalpha\fR 8
+A letter.
+.IP \fBupper\fR 8
+An upper-case letter.
+.IP \fBlower\fR 8
+A lower-case letter.
+.IP \fBdigit\fR 8
+A decimal digit.
+.IP \fBxdigit\fR 8
+A hexadecimal digit.
+.IP \fBalnum\fR 8
+An alphanumeric (letter or digit).
+.IP \fBprint\fR 8
+A "printable" (same as graph, except also including space).
+.IP \fBblank\fR 8
+A space or tab character.
+.IP \fBspace\fR 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).
+.IP \fBcntrl\fR 8
+A control character.
+.PP
+A locale may provide others. A character class may not be used as an endpoint
+of a range.
.RS
-.ne 5
-.ta 3c
-.nf
-\fBalpha\fR A letter.
-\fBupper\fR An upper-case letter.
-\fBlower\fR A lower-case letter.
-\fBdigit\fR A decimal digit.
-\fBxdigit\fR A hexadecimal digit.
-\fBalnum\fR An alphanumeric (letter or digit).
-\fBprint\fR A "printable" (same as graph, except also including space).
-\fBblank\fR A space or tab character.
-\fBspace\fR A character producing white space in displayed text.
-\fBpunct\fR A punctuation character.
-\fBgraph\fR A character with a visible representation.
-\fBcntrl\fR A control character.
-.fi
+.PP
+(\fINote:\fR the current Tcl implementation has only one locale, the Unicode
+locale, which supports exactly the above classes.)
.RE
+.SS "BRACKETED CONSTRAINTS"
+There are two special cases of bracket expressions: the bracket
+expressions
+.QW \fB[[:<:]]\fR
+and
+.QW \fB[[:>:]]\fR
+are constraints, matching empty strings at the beginning and end of a word
+respectively.
+.\" note, discussion of escapes below references this definition of word
+A word is defined as a sequence of word characters that is neither preceded
+nor followed by word characters. A word character is an \fIalnum\fR character
+or an underscore
+.PQ \fB_\fR "" .
+These special bracket expressions are deprecated; users of AREs should use
+constraint escapes instead (see below).
+.SS "COLLATING ELEMENTS"
+Within a bracket expression, a collating element (a character, a
+multi-character sequence that collates as if it were a single
+character, or a collating-sequence name for either) enclosed in
+\fB[.\fR and \fB.]\fR stands for the sequence of characters of that
+collating element. The sequence is a single element of the bracket
+expression's list. A bracket expression in a locale that has
+multi-character collating elements can thus match more than one
+character. So (insidiously), a bracket expression that starts with
+\fB^\fR can match multi-character collating elements even if none of
+them appear in the bracket expression!
+.RS
.PP
-A locale may provide others.
-.VS 8.2
-(Note that the current Tcl implementation has only one locale:
-the Unicode locale.)
-.VE 8.2
-A character class may not be used as an endpoint of a range.
+(\fINote:\fR Tcl has no multi-character collating elements. This information
+is only for illustration.)
+.RE
.PP
-There are two special cases of bracket expressions:
-the bracket expressions
-\fB[[:<:]]\fR
+For example, assume the collating sequence includes a \fBch\fR multi-character
+collating element. Then the RE
+.QW \fB[[.ch.]]*c\fR
+(zero or more
+.QW \fBch\fRs
+followed by
+.QW \fBc\fR )
+matches the first five characters of
+.QW \fBchchcc\fR .
+Also, the RE
+.QW \fB[^c]b\fR
+matches all of
+.QW \fBchb\fR
+(because
+.QW \fB[^c]\fR
+matches the multi-character
+.QW \fBch\fR ).
+.SS "EQUIVALENCE CLASSES"
+Within a bracket expression, a collating element enclosed in \fB[=\fR
+and \fB=]\fR is an equivalence class, standing for the sequences of
+characters of all collating elements equivalent to that one, including
+itself. (If there are no other equivalent collating elements, the
+treatment is as if the enclosing delimiters were
+.QW \fB[.\fR \&
and
-\fB[[:>:]]\fR
-are constraints, matching empty strings at
-the beginning and end of a word respectively.
-'\" note, discussion of escapes below references this definition of word
-A word is defined as a sequence of
-word characters
-that is neither preceded nor followed by
-word characters.
-A word character is an
-\fIalnum\fR
-character
-or an underscore
-(\fB_\fR).
-These special bracket expressions are deprecated;
-users of AREs should use constraint escapes instead (see below).
-.SH ESCAPES
-Escapes (AREs only), which begin with a
-\fB\e\fR
-followed by an alphanumeric character,
-come in several varieties:
-character entry, class shorthands, constraint escapes, and back references.
-A
-\fB\e\fR
-followed by an alphanumeric character but not constituting
-a valid escape is illegal in AREs.
-In EREs, there are no escapes:
-outside a bracket expression,
-a
-\fB\e\fR
-followed by an alphanumeric character merely stands for that
-character as an ordinary character,
-and inside a bracket expression,
-\fB\e\fR
-is an ordinary character.
-(The latter is the one actual incompatibility between EREs and AREs.)
+.QW \fB.]\fR .)
+For example, if \fBo\fR and \fB\N'244'\fR are the members of an
+equivalence class, then
+.QW \fB[[=o=]]\fR ,
+.QW \fB[[=\N'244'=]]\fR ,
+and
+.QW \fB[o\N'244']\fR \&
+are all synonymous. An equivalence class may not be an endpoint of a range.
+.RS
.PP
+(\fINote:\fR Tcl implements only the Unicode locale. It does not define any
+equivalence classes. The examples above are just illustrations.)
+.RE
+.SH ESCAPES
+Escapes (AREs only), which begin with a \fB\e\fR followed by an
+alphanumeric character, come in several varieties: character entry,
+class shorthands, constraint escapes, and back references. A \fB\e\fR
+followed by an alphanumeric character but not constituting a valid
+escape is illegal in AREs. In EREs, there are no escapes: outside a
+bracket expression, a \fB\e\fR followed by an alphanumeric character
+merely stands for that character as an ordinary character, and inside
+a bracket expression, \fB\e\fR is an ordinary character. (The latter
+is the one actual incompatibility between EREs and AREs.)
+.SS "CHARACTER-ENTRY ESCAPES"
Character-entry escapes (AREs only) exist to make it easier to specify
non-printing and otherwise inconvenient characters in REs:
.RS 2
.TP 5
\fB\ea\fR
+.
alert (bell) character, as in C
.TP
\fB\eb\fR
+.
backspace, as in C
.TP
\fB\eB\fR
-synonym for
-\fB\e\fR
-to help reduce backslash doubling in some
+.
+synonym for \fB\e\fR to help reduce backslash doubling in some
applications where there are multiple levels of backslash processing
.TP
\fB\ec\fIX\fR
-(where X is any character) the character whose
-low-order 5 bits are the same as those of
-\fIX\fR,
-and whose other bits are all zero
+.
+(where \fIX\fR is any character) the character whose low-order 5 bits
+are the same as those of \fIX\fR, and whose other bits are all zero
.TP
\fB\ee\fR
-the character whose collating-sequence name
-is `\fBESC\fR',
+.
+the character whose collating-sequence name is
+.QW \fBESC\fR ,
or failing that, the character with octal value 033
.TP
\fB\ef\fR
+.
formfeed, as in C
.TP
\fB\en\fR
+.
newline, as in C
.TP
\fB\er\fR
+.
carriage return, as in C
.TP
\fB\et\fR
+.
horizontal tab, as in C
.TP
\fB\eu\fIwxyz\fR
-(where
-\fIwxyz\fR
-is exactly four hexadecimal digits)
-the Unicode character
-\fBU+\fIwxyz\fR
-in the local byte ordering
+.
+(where \fIwxyz\fR is exactly 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 exactly eight hexadecimal digits) reserved
+for a somewhat-hypothetical Unicode extension to 32 bits
.TP
\fB\ev\fR
-vertical tab, as in C
-are all available.
+.
+vertical tab, as in C are all available.
.TP
\fB\ex\fIhhh\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 \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).
.TP
\fB\e0\fR
-the character whose value is
-\fB0\fR
+.
+the character whose value is \fB0\fR
.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
+.
+(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
+.
+(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 `\fB0\fR'-`\fB9\fR', `\fBa\fR'-`\fBf\fR',
-and `\fBA\fR'-`\fBF\fR'.
-Octal digits are `\fB0\fR'-`\fB7\fR'.
+Hexadecimal digits are
+.QR \fB0\fR \fB9\fR ,
+.QR \fBa\fR \fBf\fR ,
+and
+.QR \fBA\fR \fBF\fR .
+Octal digits are
+.QR \fB0\fR \fB7\fR .
.PP
The character-entry escapes are always taken as ordinary characters.
-For example,
-\fB\e135\fR
-is
-\fB]\fR
-in ASCII,
-but
-\fB\e135\fR
-does not terminate a bracket expression.
-Beware, however, that some applications (e.g., C compilers) interpret
-such sequences themselves before the regular-expression package
-gets to see them, which may require doubling (quadrupling, etc.) the `\fB\e\fR'.
-.PP
-Class-shorthand escapes (AREs only) provide shorthands for certain commonly-used
-character classes:
+For example, \fB\e135\fR is \fB]\fR in Unicode, but \fB\e135\fR does
+not terminate a bracket expression. Beware, however, that some
+applications (e.g., C compilers and the Tcl interpreter if the regular
+expression is not quoted with braces) interpret such sequences
+themselves before the regular-expression package gets to see them,
+which may require doubling (quadrupling, etc.) the
+.QW \fB\e\fR .
+.SS "CLASS-SHORTHAND ESCAPES"
+Class-shorthand escapes (AREs only) provide shorthands for certain
+commonly-used character classes:
.RS 2
.TP 10
\fB\ed\fR
+.
\fB[[:digit:]]\fR
.TP
\fB\es\fR
+.
\fB[[:space:]]\fR
.TP
\fB\ew\fR
-\fB[[:alnum:]_]\fR
-(note underscore)
+.
+\fB[[:alnum:]_]\fR (note underscore)
.TP
\fB\eD\fR
+.
\fB[^[:digit:]]\fR
.TP
\fB\eS\fR
+.
\fB[^[:space:]]\fR
.TP
\fB\eW\fR
-\fB[^[:alnum:]_]\fR
-(note underscore)
+.
+\fB[^[:alnum:]_]\fR (note underscore)
.RE
.PP
-Within bracket expressions, `\fB\ed\fR', `\fB\es\fR',
-and `\fB\ew\fR'\&
-lose their outer brackets,
-and `\fB\eD\fR', `\fB\eS\fR',
-and `\fB\eW\fR'\&
-are illegal.
-.VS 8.2
-(So, for example, \fB[a-c\ed]\fR is equivalent to \fB[a-c[:digit:]]\fR.
-Also, \fB[a-c\eD]\fR, which is equivalent to \fB[a-c^[:digit:]]\fR, is illegal.)
-.VE 8.2
-.PP
-A constraint escape (AREs only) is a constraint,
-matching the empty string if specific conditions are met,
-written as an escape:
+Within bracket expressions,
+.QW \fB\ed\fR ,
+.QW \fB\es\fR ,
+and
+.QW \fB\ew\fR \&
+lose their outer brackets, and
+.QW \fB\eD\fR ,
+.QW \fB\eS\fR ,
+and
+.QW \fB\eW\fR \&
+are illegal. (So, for example,
+.QW \fB[a-c\ed]\fR
+is equivalent to
+.QW \fB[a-c[:digit:]]\fR .
+Also,
+.QW \fB[a-c\eD]\fR ,
+which is equivalent to
+.QW \fB[a-c^[:digit:]]\fR ,
+is illegal.)
+.SS "CONSTRAINT ESCAPES"
+A constraint escape (AREs only) is a constraint, matching the empty
+string if specific conditions are met, written as an escape:
.RS 2
.TP 6
\fB\eA\fR
-matches only at the beginning of the string
-(see MATCHING, below, for how this differs from `\fB^\fR')
+.
+matches only at the beginning of the string (see \fBMATCHING\fR,
+below, for how this differs from
+.QW \fB^\fR )
.TP
\fB\em\fR
+.
matches only at the beginning of a word
.TP
\fB\eM\fR
+.
matches only at the end of a word
.TP
\fB\ey\fR
+.
matches only at the beginning or end of a word
.TP
\fB\eY\fR
+.
matches only at a point that is not the beginning or end of a word
.TP
\fB\eZ\fR
-matches only at the end of the string
-(see MATCHING, below, for how this differs from `\fB$\fR')
+.
+matches only at the end of the string (see \fBMATCHING\fR, below, for
+how this differs from
+.QW \fB$\fR )
.TP
\fB\e\fIm\fR
-(where
-\fIm\fR
-is a nonzero digit) a \fIback reference\fR, see below
+.
+(where \fIm\fR is a nonzero digit) a \fIback reference\fR, see below
.TP
\fB\e\fImnn\fR
-(where
-\fIm\fR
-is a nonzero digit, and
-\fInn\fR
-is some more digits,
-and the decimal value
-\fImnn\fR
-is not greater than the number of closing capturing parentheses seen so far)
-a \fIback reference\fR, see below
+.
+(where \fIm\fR is a nonzero digit, and \fInn\fR is some more digits,
+and the decimal value \fImnn\fR is not greater than the number of
+closing capturing parentheses seen so far) a \fIback reference\fR, see
+below
.RE
.PP
A word is defined as in the specification of
-\fB[[:<:]]\fR
+.QW \fB[[:<:]]\fR
and
-\fB[[:>:]]\fR
-above.
-Constraint escapes are illegal within bracket expressions.
-.PP
-A back reference (AREs only) matches the same string matched by the parenthesized
-subexpression specified by the number,
-so that (e.g.)
-\fB([bc])\e1\fR
+.QW \fB[[:>:]]\fR
+above. Constraint escapes are illegal within bracket expressions.
+.SS "BACK REFERENCES"
+A back reference (AREs only) matches the same string matched by the
+parenthesized subexpression specified by the number, so that (e.g.)
+.QW \fB([bc])\e1\fR
matches
-\fBbb\fR
+.QW \fBbb\fR
or
-\fBcc\fR
-but not `\fBbc\fR'.
+.QW \fBcc\fR
+but not
+.QW \fBbc\fR .
The subexpression must entirely precede the back reference in the RE.
Subexpressions are numbered in the order of their leading parentheses.
Non-capturing parentheses do not define subexpressions.
.PP
-There is an inherent historical ambiguity between octal character-entry
-escapes and back references, which is resolved by heuristics,
-as hinted at above.
-A leading zero always indicates an octal escape.
-A single non-zero digit, not followed by another digit,
-is always taken as a back reference.
-A multi-digit sequence not starting with a zero is taken as a back
-reference if it comes after a suitable subexpression
-(i.e. the number is in the legal range for a back reference),
-and otherwise is taken as octal.
+There is an inherent historical ambiguity between octal
+character-entry escapes and back references, which is resolved by
+heuristics, as hinted at above. A leading zero always indicates an
+octal escape. A single non-zero digit, not followed by another digit,
+is always taken as a back reference. A multi-digit sequence not
+starting with a zero is taken as a back reference if it comes after a
+suitable subexpression (i.e. the number is in the legal range for a
+back reference), and otherwise is taken as octal.
.SH "METASYNTAX"
In addition to the main syntax described above, there are some special
forms and miscellaneous syntactic facilities available.
.PP
Normally the flavor of RE being used is specified by
-application-dependent means.
-However, this can be overridden by a \fIdirector\fR.
-If an RE of any flavor begins with `\fB***:\fR',
-the rest of the RE is an ARE.
-If an RE of any flavor begins with `\fB***=\fR',
-the rest of the RE is taken to be a literal string,
-with all characters considered ordinary characters.
-.PP
-An ARE may begin with \fIembedded options\fR:
-a sequence
-\fB(?\fIxyz\fB)\fR
-(where
-\fIxyz\fR
-is one or more alphabetic characters)
-specifies options affecting the rest of the RE.
-These supplement, and can override,
-any options specified by the application.
-The available option letters are:
+application-dependent means. However, this can be overridden by a
+\fIdirector\fR. If an RE of any flavor begins with
+.QW \fB***:\fR ,
+the rest of the RE is an ARE. If an RE of any flavor begins with
+.QW \fB***=\fR ,
+the rest of the RE is taken to be a literal string, with
+all characters considered ordinary characters.
+.PP
+An ARE may begin with \fIembedded options\fR: a sequence
+\fB(?\fIxyz\fB)\fR (where \fIxyz\fR is one or more alphabetic
+characters) specifies options affecting the rest of the RE. These
+supplement, and can override, any options specified by the
+application. The available option letters are:
.RS 2
.TP 3
\fBb\fR
+.
rest of RE is a BRE
.TP 3
\fBc\fR
+.
case-sensitive matching (usual default)
.TP 3
\fBe\fR
+.
rest of RE is an ERE
.TP 3
\fBi\fR
-case-insensitive matching (see MATCHING, below)
+.
+case-insensitive matching (see \fBMATCHING\fR, below)
.TP 3
\fBm\fR
-historical synonym for
-\fBn\fR
+.
+historical synonym for \fBn\fR
.TP 3
\fBn\fR
-newline-sensitive matching (see MATCHING, below)
+.
+newline-sensitive matching (see \fBMATCHING\fR, below)
.TP 3
\fBp\fR
-partial newline-sensitive matching (see MATCHING, below)
+.
+partial newline-sensitive matching (see \fBMATCHING\fR, below)
.TP 3
\fBq\fR
-rest of RE is a literal (``quoted'') string, all ordinary characters
+.
+rest of RE is a literal
+.PQ quoted
+string, all ordinary characters
.TP 3
\fBs\fR
+.
non-newline-sensitive matching (usual default)
.TP 3
\fBt\fR
+.
tight syntax (usual default; see below)
.TP 3
\fBw\fR
-inverse partial newline-sensitive (``weird'') matching (see MATCHING, below)
+.
+inverse partial newline-sensitive
+.PQ weird
+matching (see \fBMATCHING\fR, below)
.TP 3
\fBx\fR
+.
expanded syntax (see below)
.RE
.PP
-Embedded options take effect at the
-\fB)\fR
-terminating the sequence.
-They are available only at the start of an ARE,
-and may not be used later within it.
-.PP
-In addition to the usual (\fItight\fR) RE syntax, in which all characters are
-significant, there is an \fIexpanded\fR syntax,
-available in all flavors of RE
-with the \fB-expanded\fR switch, or in AREs with the embedded x option.
-In the expanded syntax,
-white-space characters are ignored
-and all characters between a
-\fB#\fR
-and the following newline (or the end of the RE) are ignored,
-permitting paragraphing and commenting a complex RE.
-There are three exceptions to that basic rule:
-.RS 2
-.PP
-a white-space character or `\fB#\fR' preceded by `\fB\e\fR' is retained
-.PP
-white space or `\fB#\fR' within a bracket expression is retained
-.PP
+Embedded options take effect at the \fB)\fR terminating the sequence.
+They are available only at the start of an ARE, and may not be used
+later within it.
+.PP
+In addition to the usual (\fItight\fR) RE syntax, in which all
+characters are significant, there is an \fIexpanded\fR syntax,
+available in all flavors of RE with the \fB\-expanded\fR switch, or in
+AREs with the embedded x option. In the expanded syntax, white-space
+characters are ignored and all characters between a \fB#\fR and the
+following newline (or the end of the RE) are ignored, permitting
+paragraphing and commenting a complex RE. There are three exceptions
+to that basic rule:
+.IP \(bu 3
+a white-space character or
+.QW \fB#\fR
+preceded by
+.QW \fB\e\fR
+is retained
+.IP \(bu 3
+white space or
+.QW \fB#\fR
+within a bracket expression is retained
+.IP \(bu 3
white space and comments are illegal within multi-character symbols
-like the ARE `\fB(?:\fR' or the BRE `\fB\e(\fR'
-.RE
+like the ARE
+.QW \fB(?:\fR
+or the BRE
+.QW \fB\e(\fR
.PP
Expanded-syntax white-space characters are blank, tab, newline, and
-.VS 8.2
any character that belongs to the \fIspace\fR character class.
-.VE 8.2
-.PP
-Finally, in an ARE,
-outside bracket expressions, the sequence `\fB(?#\fIttt\fB)\fR'
-(where
-\fIttt\fR
-is any text not containing a `\fB)\fR')
-is a comment,
-completely ignored.
-Again, this is not allowed between the characters of
-multi-character symbols like `\fB(?:\fR'.
+.PP
+Finally, in an ARE, outside bracket expressions, the sequence
+.QW \fB(?#\fIttt\fB)\fR
+(where \fIttt\fR is any text not containing a
+.QW \fB)\fR )
+is a comment, completely ignored. Again, this is not
+allowed between the characters of multi-character symbols like
+.QW \fB(?:\fR .
Such comments are more a historical artifact than a useful facility,
-and their use is deprecated;
-use the expanded syntax instead.
-.PP
-\fINone\fR of these metasyntax extensions is available if the application
-(or an initial
-\fB***=\fR
-director)
-has specified that the user's input be treated as a literal string
-rather than as an RE.
+and their use is deprecated; use the expanded syntax instead.
+.PP
+\fINone\fR of these metasyntax extensions is available if the
+application (or an initial
+.QW \fB***=\fR
+director) has specified that the
+user's input be treated as a literal string rather than as an RE.
.SH MATCHING
In the event that an RE could match more than one substring of a given
-string,
-the RE matches the one starting earliest in the string.
-If the RE could match more than one substring starting at that point,
-its choice is determined by its \fIpreference\fR:
-either the longest substring, or the shortest.
-.PP
-Most atoms, and all constraints, have no preference.
-A parenthesized RE has the same preference (possibly none) as the RE.
-A quantified atom with quantifier
-\fB{\fIm\fB}\fR
-or
-\fB{\fIm\fB}?\fR
-has the same preference (possibly none) as the atom itself.
-A quantified atom with other normal quantifiers (including
-\fB{\fIm\fB,\fIn\fB}\fR
-with
-\fIm\fR
-equal to
-\fIn\fR)
-prefers longest match.
-A quantified atom with other non-greedy quantifiers (including
-\fB{\fIm\fB,\fIn\fB}?\fR
-with
-\fIm\fR
-equal to
-\fIn\fR)
-prefers shortest match.
-A branch has the same preference as the first quantified atom in it
-which has a preference.
-An RE consisting of two or more branches connected by the
-\fB|\fR
-operator prefers longest match.
-.PP
-Subject to the constraints imposed by the rules for matching the whole RE,
-subexpressions also match the longest or shortest possible substrings,
-based on their preferences,
-with subexpressions starting earlier in the RE taking priority over
-ones starting later.
-Note that outer subexpressions thus take priority over
-their component subexpressions.
-.PP
-Note that the quantifiers
-\fB{1,1}\fR
-and
-\fB{1,1}?\fR
-can be used to force longest and shortest preference, respectively,
-on a subexpression or a whole RE.
-.PP
-Match lengths are measured in characters, not collating elements.
-An empty string is considered longer than no match at all.
-For example,
-\fBbb*\fR
-matches the three middle characters of `\fBabbbc\fR',
-\fB(week|wee)(night|knights)\fR
-matches all ten characters of `\fBweeknights\fR',
+string, the RE matches the one starting earliest in the string. If
+the RE could match more than one substring starting at that point, its
+choice is determined by its \fIpreference\fR: either the longest
+substring, or the shortest.
+.PP
+Most atoms, and all constraints, have no preference. A parenthesized
+RE has the same preference (possibly none) as the RE. A quantified
+atom with quantifier \fB{\fIm\fB}\fR or \fB{\fIm\fB}?\fR has the same
+preference (possibly none) as the atom itself. A quantified atom with
+other normal quantifiers (including \fB{\fIm\fB,\fIn\fB}\fR with
+\fIm\fR equal to \fIn\fR) prefers longest match. A quantified atom
+with other non-greedy quantifiers (including \fB{\fIm\fB,\fIn\fB}?\fR
+with \fIm\fR equal to \fIn\fR) prefers shortest match. A branch has
+the same preference as the first quantified atom in it which has a
+preference. An RE consisting of two or more branches connected by the
+\fB|\fR operator prefers longest match.
+.PP
+Subject to the constraints imposed by the rules for matching the whole
+RE, subexpressions also match the longest or shortest possible
+substrings, based on their preferences, with subexpressions starting
+earlier in the RE taking priority over ones starting later. Note that
+outer subexpressions thus take priority over their component
+subexpressions.
+.PP
+Note that the quantifiers \fB{1,1}\fR and \fB{1,1}?\fR can be used to
+force longest and shortest preference, respectively, on a
+subexpression or a whole RE.
+.PP
+Match lengths are measured in characters, not collating elements. An
+empty string is considered longer than no match at all. For example,
+.QW \fBbb*\fR
+matches the three middle characters of
+.QW \fBabbbc\fR ,
+.QW \fB(week|wee)(night|knights)\fR
+matches all ten characters of
+.QW \fBweeknights\fR ,
when
-\fB(.*).*\fR
+.QW \fB(.*).*\fR
is matched against
-\fBabc\fR
-the parenthesized subexpression
-matches all three characters, and
-when
-\fB(a*)*\fR
+.QW \fBabc\fR
+the parenthesized subexpression matches all three characters, and when
+.QW \fB(a*)*\fR
is matched against
-\fBbc\fR
-both the whole RE and the parenthesized
-subexpression match an empty string.
-.PP
-If case-independent matching is specified,
-the effect is much as if all case distinctions had vanished from the
-alphabet.
-When an alphabetic that exists in multiple cases appears as an
-ordinary character outside a bracket expression, it is effectively
-transformed into a bracket expression containing both cases,
-so that
-\fBx\fR
-becomes `\fB[xX]\fR'.
-When it appears inside a bracket expression, all case counterparts
-of it are added to the bracket expression, so that
-\fB[x]\fR
+.QW \fBbc\fR
+both the whole RE and the parenthesized subexpression match an empty string.
+.PP
+If case-independent matching is specified, the effect is much as if
+all case distinctions had vanished from the alphabet. When an
+alphabetic that exists in multiple cases appears as an ordinary
+character outside a bracket expression, it is effectively transformed
+into a bracket expression containing both cases, so that \fBx\fR
becomes
-\fB[xX]\fR
-and
-\fB[^x]\fR
-becomes `\fB[^xX]\fR'.
-.PP
-If newline-sensitive matching is specified, \fB.\fR
-and bracket expressions using
-\fB^\fR
-will never match the newline character
-(so that matches will never cross newlines unless the RE
-explicitly arranges it)
-and
-\fB^\fR
-and
-\fB$\fR
-will match the empty string after and before a newline
-respectively, in addition to matching at beginning and end of string
-respectively.
-ARE
-\fB\eA\fR
+.QW \fB[xX]\fR .
+When it appears inside a bracket expression,
+all case counterparts of it are added to the bracket expression, so
+that
+.QW \fB[x]\fR
+becomes
+.QW \fB[xX]\fR
and
-\fB\eZ\fR
+.QW \fB[^x]\fR
+becomes
+.QW \fB[^xX]\fR .
+.PP
+If newline-sensitive matching is specified, \fB.\fR and bracket
+expressions using \fB^\fR will never match the newline character (so
+that matches will never cross newlines unless the RE explicitly
+arranges it) and \fB^\fR and \fB$\fR will match the empty string after
+and before a newline respectively, in addition to matching at
+beginning and end of string respectively. ARE \fB\eA\fR and \fB\eZ\fR
continue to match beginning or end of string \fIonly\fR.
.PP
-If partial newline-sensitive matching is specified,
-this affects \fB.\fR
-and bracket expressions
-as with newline-sensitive matching, but not
-\fB^\fR
-and `\fB$\fR'.
+If partial newline-sensitive matching is specified, this affects
+\fB.\fR and bracket expressions as with newline-sensitive matching,
+but not \fB^\fR and \fB$\fR.
.PP
-If inverse partial newline-sensitive matching is specified,
-this affects
-\fB^\fR
-and
-\fB$\fR
-as with
-newline-sensitive matching,
-but not \fB.\fR
-and bracket expressions.
-This isn't very useful but is provided for symmetry.
+If inverse partial newline-sensitive matching is specified, this
+affects \fB^\fR and \fB$\fR as with newline-sensitive matching, but
+not \fB.\fR and bracket expressions. This is not very useful but is
+provided for symmetry.
.SH "LIMITS AND COMPATIBILITY"
-No particular limit is imposed on the length of REs.
-Programs intended to be highly portable should not employ REs longer
-than 256 bytes,
-as a POSIX-compliant implementation can refuse to accept such REs.
-.PP
-The only feature of AREs that is actually incompatible with
-POSIX EREs is that
-\fB\e\fR
-does not lose its special
-significance inside bracket expressions.
-All other ARE features use syntax which is illegal or has
-undefined or unspecified effects in POSIX EREs;
-the
-\fB***\fR
-syntax of directors likewise is outside the POSIX
-syntax for both BREs and EREs.
-.PP
-Many of the ARE extensions are borrowed from Perl, but some have
-been changed to clean them up, and a few Perl extensions are not present.
-Incompatibilities of note include `\fB\eb\fR', `\fB\eB\fR',
-the lack of special treatment for a trailing newline,
-the addition of complemented bracket expressions to the things
-affected by newline-sensitive matching,
-the restrictions on parentheses and back references in lookahead constraints,
-and the longest/shortest-match (rather than first-match) matching semantics.
-.PP
-The matching rules for REs containing both normal and non-greedy quantifiers
-have changed since early beta-test versions of this package.
-(The new rules are much simpler and cleaner,
-but don't work as hard at guessing the user's real intentions.)
-.PP
-Henry Spencer's original 1986 \fIregexp\fR package,
-still in widespread use (e.g., in pre-8.1 releases of Tcl),
-implemented an early version of today's EREs.
-There are four incompatibilities between \fIregexp\fR's near-EREs
-(`RREs' for short) and AREs.
-In roughly increasing order of significance:
-.PP
-.RS
-In AREs,
-\fB\e\fR
-followed by an alphanumeric character is either an
-escape or an error,
-while in RREs, it was just another way of writing the
-alphanumeric.
-This should not be a problem because there was no reason to write
-such a sequence in RREs.
-.PP
-\fB{\fR
-followed by a digit in an ARE is the beginning of a bound,
-while in RREs,
-\fB{\fR
-was always an ordinary character.
-Such sequences should be rare,
-and will often result in an error because following characters
-will not look like a valid bound.
-.PP
-In AREs,
-\fB\e\fR
-remains a special character within `\fB[\|]\fR',
-so a literal
-\fB\e\fR
-within
-\fB[\|]\fR
-must be written `\fB\e\e\fR'.
-\fB\e\e\fR
-also gives a literal
-\fB\e\fR
-within
-\fB[\|]\fR
-in RREs,
+No particular limit is imposed on the length of REs. Programs
+intended to be highly portable should not employ REs longer than 256
+bytes, as a POSIX-compliant implementation can refuse to accept such
+REs.
+.PP
+The only feature of AREs that is actually incompatible with POSIX EREs
+is that \fB\e\fR does not lose its special significance inside bracket
+expressions. All other ARE features use syntax which is illegal or
+has undefined or unspecified effects in POSIX EREs; the \fB***\fR
+syntax of directors likewise is outside the POSIX syntax for both BREs
+and EREs.
+.PP
+Many of the ARE extensions are borrowed from Perl, but some have been
+changed to clean them up, and a few Perl extensions are not present.
+Incompatibilities of note include
+.QW \fB\eb\fR ,
+.QW \fB\eB\fR ,
+the lack of special treatment for a trailing newline, the addition of
+complemented bracket expressions to the things affected by
+newline-sensitive matching, the restrictions on parentheses and back
+references in lookahead constraints, and the longest/shortest-match
+(rather than first-match) matching semantics.
+.PP
+The matching rules for REs containing both normal and non-greedy
+quantifiers have changed since early beta-test versions of this
+package. (The new rules are much simpler and cleaner, but do not work
+as hard at guessing the user's real intentions.)
+.PP
+Henry Spencer's original 1986 \fIregexp\fR package, still in
+widespread use (e.g., in pre-8.1 releases of Tcl), implemented an
+early version of today's EREs. There are four incompatibilities
+between \fIregexp\fR's near-EREs
+.PQ RREs " for short"
+and AREs. In roughly increasing order of significance:
+.IP \(bu 3
+In AREs, \fB\e\fR followed by an alphanumeric character is either an
+escape or an error, while in RREs, it was just another way of writing
+the alphanumeric. This should not be a problem because there was no
+reason to write such a sequence in RREs.
+.IP \(bu 3
+\fB{\fR followed by a digit in an ARE is the beginning of a bound,
+while in RREs, \fB{\fR was always an ordinary character. Such
+sequences should be rare, and will often result in an error because
+following characters will not look like a valid bound.
+.IP \(bu 3
+In AREs, \fB\e\fR remains a special character within
+.QW \fB[\|]\fR ,
+so a literal \fB\e\fR within \fB[\|]\fR must be written
+.QW \fB\e\e\fR .
+\fB\e\e\fR also gives a literal \fB\e\fR within \fB[\|]\fR in RREs,
but only truly paranoid programmers routinely doubled the backslash.
-.PP
-AREs report the longest/shortest match for the RE,
-rather than the first found in a specified search order.
-This may affect some RREs which were written in the expectation that
-the first match would be reported.
-(The careful crafting of RREs to optimize the search order for fast
-matching is obsolete (AREs examine all possible matches
-in parallel, and their performance is largely insensitive to their
-complexity) but cases where the search order was exploited to deliberately
-find a match which was \fInot\fR the longest/shortest will need rewriting.)
-.RE
-
+.IP \(bu 3
+AREs report the longest/shortest match for the RE, rather than the
+first found in a specified search order. This may affect some RREs
+which were written in the expectation that the first match would be
+reported. (The careful crafting of RREs to optimize the search order
+for fast matching is obsolete (AREs examine all possible matches in
+parallel, and their performance is largely insensitive to their
+complexity) but cases where the search order was exploited to
+deliberately find a match which was \fInot\fR the longest/shortest
+will need rewriting.)
.SH "BASIC REGULAR EXPRESSIONS"
-BREs differ from EREs in several respects. `\fB|\fR', `\fB+\fR',
-and
-\fB?\fR
-are ordinary characters and there is no equivalent
-for their functionality.
-The delimiters for bounds are
-\fB\e{\fR
-and `\fB\e}\fR',
-with
-\fB{\fR
-and
-\fB}\fR
-by themselves ordinary characters.
-The parentheses for nested subexpressions are
-\fB\e(\fR
-and `\fB\e)\fR',
-with
-\fB(\fR
-and
-\fB)\fR
-by themselves ordinary characters.
-\fB^\fR
-is an ordinary character except at the beginning of the
-RE or the beginning of a parenthesized subexpression,
-\fB$\fR
-is an ordinary character except at the end of the
-RE or the end of a parenthesized subexpression,
-and
-\fB*\fR
-is an ordinary character if it appears at the beginning of the
-RE or the beginning of a parenthesized subexpression
-(after a possible leading `\fB^\fR').
-Finally,
-single-digit back references are available,
-and
-\fB\e<\fR
-and
-\fB\e>\fR
-are synonyms for
-\fB[[:<:]]\fR
+BREs differ from EREs in several respects.
+.QW \fB|\fR ,
+.QW \fB+\fR ,
+and \fB?\fR are ordinary characters and there is no equivalent for their
+functionality. The delimiters for bounds are \fB\e{\fR and
+.QW \fB\e}\fR ,
+with \fB{\fR and \fB}\fR by themselves ordinary characters. The
+parentheses for nested subexpressions are \fB\e(\fR and
+.QW \fB\e)\fR ,
+with \fB(\fR and \fB)\fR by themselves ordinary
+characters. \fB^\fR is an ordinary character except at the beginning
+of the RE or the beginning of a parenthesized subexpression, \fB$\fR
+is an ordinary character except at the end of the RE or the end of a
+parenthesized subexpression, and \fB*\fR is an ordinary character if
+it appears at the beginning of the RE or the beginning of a
+parenthesized subexpression (after a possible leading
+.QW \fB^\fR ).
+Finally, single-digit back references are available, and \fB\e<\fR and
+\fB\e>\fR are synonyms for
+.QW \fB[[:<:]]\fR
and
-\fB[[:>:]]\fR
-respectively;
-no other escapes are available.
-
+.QW \fB[[:>:]]\fR
+respectively; no other escapes are available.
.SH "SEE ALSO"
RegExp(3), regexp(n), regsub(n), lsearch(n), switch(n), text(n)
-
.SH KEYWORDS
match, regular expression, string
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/doc/read.n b/doc/read.n
index 9584756..5398b08 100644
--- a/doc/read.n
+++ b/doc/read.n
@@ -30,13 +30,11 @@ the channel is configured to use a multi-byte encoding, then the
number of characters read may not be the same as the number of bytes
read.
.PP
-.VS
\fIChannelId\fR must be an identifier for an open channel such as the
Tcl standard input channel (\fBstdin\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. The channel must have
been opened for input.
-.VE
.PP
If \fIchannelId\fR is in nonblocking mode, the command may not read as
many characters as requested: once all available input has been read,
@@ -78,7 +76,7 @@ with each line in the file corresponding to an element in the list:
set fl [open /proc/meminfo]
set data [\fBread\fR $fl]
close $fl
-set lines [split $data \\n]
+set lines [split $data \en]
.CE
.SH "SEE ALSO"
diff --git a/doc/refchan.n b/doc/refchan.n
new file mode 100644
index 0000000..577c78a
--- /dev/null
+++ b/doc/refchan.n
@@ -0,0 +1,340 @@
+'\"
+'\" Copyright (c) 2006 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+'\"
+'\" 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"
+.BS
+.\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+refchan \- Command handler API of reflected channels, version 1
+.SH SYNOPSIS
+\fBcmdPrefix \fIoption\fR ?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The Tcl-level handler for a reflected channel has to be a command with
+subcommands (termed an \fIensemble\fR, as it is a command such as that
+created by \fBnamespace ensemble create\fR, though the implementation
+of handlers for reflected channel \fIis not\fR tied to \fBnamespace
+ensemble\fRs in any way). Note that \fIcmdPrefix\fR is whatever was
+specified in the call to \fBchan create\fR, and may consist of
+multiple arguments; this will be expanded to multiple words in place
+of the prefix.
+.PP
+Of all the possible subcommands, the handler \fImust\fR support
+\fBinitialize\fR, \fBfinalize\fR, and \fBwatch\fR. Support for the
+other subcommands is optional.
+.SS "MANDATORY SUBCOMMANDS"
+.TP
+\fIcmdPrefix \fBinitialize \fIchannelId mode\fR
+.
+An invocation of this subcommand will be the first call the
+\fIcmdPrefix\fR will receive for the specified new \fIchannelId\fR. It
+is the responsibility of this subcommand to set up any internal data
+structures required to keep track of the channel and its state.
+.RS
+.PP
+The return value of the method has to be a list containing the names
+of all subcommands supported by the \fIcmdPrefix\fR. This also tells
+the Tcl core which version of the API for reflected channels is used by
+this command handler.
+.PP
+Any error thrown by the method will abort the creation of the channel
+and no channel will be created. The thrown error will appear as error
+thrown by \fBchan create\fR. Any exception other than an \fBerror\fR
+(e.g. \fBbreak\fR, etc.) is treated as (and converted to) an error.
+.PP
+\fBNote:\fR If the creation of the channel was aborted due to failures
+here, then the \fBfinalize\fR subcommand will not be called.
+.PP
+The \fImode\fR argument tells the handler whether the channel was
+opened for reading, writing, or both. It is a list containing any of
+the strings \fBread\fR or \fBwrite\fR. The list will always
+contain at least one element.
+.PP
+The subcommand must throw an error if the chosen mode is not
+supported by the \fIcmdPrefix\fR.
+.RE
+.TP
+\fIcmdPrefix \fBfinalize \fIchannelId\fR
+.
+An invocation of this subcommand will be the last call the
+\fIcmdPrefix\fR will receive for the specified \fIchannelId\fR. It will
+be generated just before the destruction of the data structures of the
+channel held by the Tcl core. The command handler \fImust not\fR
+access the \fIchannelId\fR anymore in no way. Upon this subcommand being
+called, any internal resources allocated to this channel must be
+cleaned up.
+.RS
+.PP
+The return value of this subcommand is ignored.
+.PP
+If the subcommand throws an error the command which caused its
+invocation (usually \fBclose\fR) will appear to have thrown this
+error. Any exception beyond \fIerror\fR (e.g. \fIbreak\fR, etc.) is
+treated as (and converted to) an error.
+.PP
+This subcommand is not invoked if the creation of the channel was
+aborted during \fBinitialize\fR (See above).
+.RE
+.TP
+\fIcmdPrefix \fBwatch \fIchannelId eventspec\fR
+.
+This subcommand notifies the \fIcmdPrefix\fR that the specified
+\fIchannelId\fR is interested in the events listed in the
+\fIeventspec\fR. This argument is a list containing any of \fBread\fR
+and \fBwrite\fR. The list may be empty, which signals that the
+channel does not wish to be notified of any events. In that situation,
+the handler should disable event generation completely.
+.RS
+.PP
+\fBWarning:\fR Any return value of the subcommand is ignored. This
+includes all errors thrown by the subcommand, break, continue, and
+custom return codes.
+.PP
+This subcommand interacts with \fBchan postevent\fR. Trying to post an
+event which was not listed in the last call to \fBwatch\fR will cause
+\fBchan postevent\fR to throw an error.
+.RE
+.SS "OPTIONAL SUBCOMMANDS"
+.TP
+\fIcmdPrefix \fBread \fIchannelId count\fR
+.
+This \fIoptional\fR subcommand is called when the user requests data from the
+channel \fIchannelId\fR. \fIcount\fR specifies how many \fBbytes\fR have been
+requested. If the subcommand is not supported then it is not possible to read
+from the channel handled by the command.
+.RS
+.PP
+The return value of this subcommand is taken as the requested data
+\fIbytes\fR. If the returned data contains more bytes than requested,
+an error will be signaled and later thrown by the command which
+performed the read (usually \fBgets\fR or \fBread\fR). However,
+returning fewer bytes than requested is acceptable.
+.PP
+Note that returning nothing (0 bytes) is a signal to the higher layers
+that \fBEOF\fR has been reached on the channel. To signal that the
+channel is out of data right now, but has not yet reached \fBEOF\fR,
+it is necessary to throw the error "EAGAIN", i.e. to either
+.PP
+.CS
+return -code error EAGAIN
+.CE
+or
+.CS
+error EAGAIN
+.CE
+.PP
+For extensibility any error whose value is a negative integer number
+will cause the higher layers to set the C-level variable "\fBerrno\fR"
+to the absolute value of this number, signaling a system error. This
+means that both
+.PP
+.CS
+return -code error -11
+.CE
+and
+.CS
+error -11
+.CE
+.PP
+are equivalent to the examples above, using the more readable string "EAGAIN".
+No other error value has such a mapping to a symbolic string.
+.PP
+If the subcommand throws any other error, the command which caused its
+invocation (usually \fBgets\fR, or \fBread\fR) will appear to have
+thrown this error. Any exception beyond \fIerror\fR, (e.g.
+\fIbreak\fR, etc.) is treated as and converted to an error.
+.RE
+.TP
+\fIcmdPrefix \fBwrite \fIchannelId data\fR
+.
+This \fIoptional\fR subcommand is called when the user writes data to
+the channel \fIchannelId\fR. The \fIdata\fR argument contains \fIbytes\fR, not
+characters. Any type of transformation (EOL, encoding) configured for
+the channel has already been applied at this point. If this subcommand
+is not supported then it is not possible to write to the channel
+handled by the command.
+.RS
+.PP
+The return value of the subcommand is taken as the number of bytes
+written by the channel. Anything non-numeric will cause an error to be
+signaled and later thrown by the command which performed the write. A
+negative value implies that the write failed. Returning a value
+greater than the number of bytes given to the handler, or zero, is
+forbidden and will cause the Tcl core to throw an error.
+.PP
+To signal that the channel is not able to accept data for writing
+right now, it is necessary to throw the error "EAGAIN", i.e. to either
+.PP
+.CS
+return -code error EAGAIN
+.CE
+or
+.CS
+error EAGAIN
+.CE
+.PP
+For extensibility any error whose value is a negative integer number
+will cause the higher layers to set the C-level variable "\fBerrno\fR"
+to the absolute value of this number, signaling a system error.
+However, note that the exact mapping between these error numbers and
+their meanings is operating system dependent.
+.PP
+For example, while on Linux both
+.PP
+.CS
+return -code error -11
+.CE
+and
+.CS
+error -11
+.CE
+.PP
+are equivalent to the examples above, using the more readable string "EAGAIN",
+this is not true for BSD, where the equivalent number is -35.
+.PP
+The symbolic string however is the same across systems, and internally
+translated to the correct number. No other error value has such a mapping
+to a symbolic string.
+.PP
+If the subcommand throws any other error the command which caused its
+invocation (usually \fBputs\fR) will appear to have thrown this error.
+Any exception beyond \fIerror\fR (e.g.\ \fIbreak\fR, etc.) is treated
+as and converted to an error.
+.RE
+.TP
+\fIcmdPrefix \fBseek \fIchannelId offset base\fR
+.
+This \fIoptional\fR subcommand is responsible for the handling of
+\fBseek\fR and \fBtell\fR requests on the channel \fIchannelId\fR. If it is not
+supported then seeking will not be possible for the channel.
+.RS
+.PP
+The \fIbase\fR argument is one of
+.TP 10
+\fBstart\fR
+.
+Seeking is relative to the beginning of the channel.
+.TP 10
+\fBcurrent\fR
+.
+Seeking is relative to the current seek position.
+.TP 10
+\fBend\fR
+.
+Seeking is relative to the end of the channel.
+.PP
+The \fIbase\fR argument of the builtin \fBchan seek\fR command takes
+the same names.
+.PP
+The \fIoffset\fR is an integer number specifying the amount of
+\fBbytes\fR to seek forward or backward. A positive number should seek
+forward, and a negative number should seek backward.
+.PP
+A channel may provide only limited seeking. For example sockets can
+seek forward, but not backward.
+.PP
+The return value of the subcommand is taken as the (new) location of
+the channel, counted from the start. This has to be an integer number
+greater than or equal to zero.
+.PP
+If the subcommand throws an error the command which caused its
+invocation (usually \fBseek\fR, or \fBtell\fR) will appear to have
+thrown this error. Any exception beyond \fIerror\fR (e.g. \fIbreak\fR,
+etc.) is treated as and converted to an error.
+.PP
+The offset/base combination of 0/\fBcurrent\fR signals a \fBtell\fR
+request, i.e. seek nothing relative to the current location, making
+the new location identical to the current one, which is then returned.
+.RE
+.TP
+\fIcmdPrefix \fBconfigure \fIchannelId option value\fR
+.
+This \fIoptional\fR subcommand is for setting the type-specific options of
+channel \fIchannelId\fR. The \fIoption\fR argument indicates the option to be
+written, and the \fIvalue\fR argument indicates the value to set the option to.
+.RS
+.PP
+This subcommand will never try to update more than one option at a
+time; that is behavior implemented in the Tcl channel core.
+.PP
+The return value of the subcommand is ignored.
+.PP
+If the subcommand throws an error the command which performed the
+(re)configuration or query (usually \fBfconfigure\fR or \fBchan
+configure\fR) will appear to have thrown this error. Any exception
+beyond \fIerror\fR (e.g. \fIbreak\fR, etc.) is treated as and
+converted to an error.
+.RE
+.TP
+\fIcmdPrefix \fBcget \fIchannelId option\fR
+.
+This \fIoptional\fR subcommand is used when reading a single type-specific
+option of channel \fIchannelId\fR. If this subcommand is supported then the
+subcommand \fBcgetall\fR must be supported as well.
+.RS
+.PP
+The subcommand should return the value of the specified \fIoption\fR.
+.PP
+If the subcommand throws an error, the command which performed the
+(re)configuration or query (usually \fBfconfigure\fR) will appear to
+have thrown this error. Any exception beyond \fIerror\fR (e.g.
+\fIbreak\fR, etc.) is treated as and converted to an error.
+.RE
+.TP
+\fIcmdPrefix \fBcgetall \fIchannelId\fR
+.
+This \fIoptional\fR subcommand is used for reading all type-specific options
+of channel \fIchannelId\fR. If this subcommand is supported then the
+subcommand \fBcget\fR has to be supported as well.
+.RS
+.PP
+The subcommand should return a list of all options and their values.
+This list must have an even number of elements.
+.PP
+If the subcommand throws an error the command which performed the
+(re)configuration or query (usually \fBfconfigure\fR) will appear to
+have thrown this error. Any exception beyond \fIerror\fR (e.g.
+\fIbreak\fR, etc.) is treated as and converted to an error.
+.RE
+.TP
+\fIcmdPrefix \fBblocking \fIchannelId mode\fR
+.
+This \fIoptional\fR subcommand handles changes to the blocking mode of the
+channel \fIchannelId\fR. The \fImode\fR is a boolean flag. A true value means
+that the channel has to be set to blocking, and a false value means that the
+channel should be non-blocking.
+.RS
+.PP
+The return value of the subcommand is ignored.
+.PP
+If the subcommand throws an error the command which caused its
+invocation (usually \fBfconfigure\fR) will appear to have thrown this
+error. Any exception beyond \fIerror\fR (e.g. \fIbreak\fR, etc.) is
+treated as and converted to an error.
+.RE
+.SH NOTES
+Some of the functions supported in channels defined in Tcl's C
+interface are not available to channels reflected to the Tcl level.
+.PP
+The function \fBTcl_DriverGetHandleProc\fR is not supported; i.e.
+reflected channels do not have OS specific handles.
+.PP
+The function \fBTcl_DriverHandlerProc\fR is not supported. This driver
+function is relevant only for stacked channels, i.e. transformations.
+Reflected channels are always base channels, not transformations.
+.PP
+The function \fBTcl_DriverFlushProc\fR is not supported. This is
+because the current generic I/O layer of Tcl does not use this
+function anywhere at all. Therefore support at the Tcl level makes no
+sense either. This may be altered in the future (through extending the
+API defined here and changing its version number) should the function
+be used at some time in the future.
+.SH "SEE ALSO"
+chan(n)
+.SH KEYWORDS
+channel, reflection
diff --git a/doc/regexp.n b/doc/regexp.n
index a1692bd..100f0d8 100644
--- a/doc/regexp.n
+++ b/doc/regexp.n
@@ -18,8 +18,8 @@ regexp \- Match a regular expression against a string
.SH DESCRIPTION
.PP
Determines whether the regular expression \fIexp\fR matches part or
-all of \fIstring\fR and returns 1 if it does, 0 if it doesn't, unless
-\fB-inline\fR is specified (see below).
+all of \fIstring\fR and returns 1 if it does, 0 if it does not, unless
+\fB\-inline\fR is specified (see below).
(Regular expression matching is described in the \fBre_syntax\fR
reference page.)
.LP
@@ -60,20 +60,37 @@ range of characters.
\fB\-line\fR
Enables newline-sensitive matching. By default, newline is a
completely ordinary character with no special meaning. With this
-flag, `[^' bracket expressions and `.' never match newline, `^'
+flag,
+.QW [^
+bracket expressions and
+.QW .
+never match newline,
+.QW ^
matches an empty string after any newline in addition to its normal
-function, and `$' matches an empty string before any newline in
+function, and
+.QW $
+matches an empty string before any newline in
addition to its normal function. This flag is equivalent to
specifying both \fB\-linestop\fR and \fB\-lineanchor\fR, or the
\fB(?n)\fR embedded option (see the \fBre_syntax\fR manual page).
.TP 15
\fB\-linestop\fR
-Changes the behavior of `[^' bracket expressions and `.' so that they
+Changes the behavior of
+.QW [^
+bracket expressions and
+.QW .
+so that they
stop at newlines. This is the same as specifying the \fB(?p)\fR
embedded option (see the \fBre_syntax\fR manual page).
.TP 15
\fB\-lineanchor\fR
-Changes the behavior of `^' and `$' (the ``anchors'') so they match the
+Changes the behavior of
+.QW ^
+and
+.QW $
+(the
+.QW anchors )
+so they match the
beginning and end of a line respectively. This is the same as
specifying the \fB(?w)\fR embedded option (see the \fBre_syntax\fR
manual page).
@@ -81,7 +98,6 @@ manual page).
\fB\-nocase\fR
Causes upper-case characters in \fIstring\fR to be treated as
lower case during the matching process.
-.VS 8.3
.TP 15
\fB\-all\fR
Causes the regular expression to be matched as many times as possible
@@ -91,69 +107,85 @@ the last match only.
.TP 15
\fB\-inline\fR
Causes the command to return, as a list, the data that would otherwise
-be placed in match variables. When using \fB-inline\fR,
-match variables may not be specified. If used with \fB-all\fR, the
+be placed in match variables. When using \fB\-inline\fR,
+match variables may not be specified. If used with \fB\-all\fR, the
list will be concatenated at each iteration, such that a flat list is
always returned. For each match iteration, the command will append the
overall match data, plus one element for each subexpression in the
regular expression. Examples are:
.CS
- regexp -inline -- {\\w(\\w)} " inlined "
- => {in n}
- regexp -all -inline -- {\\w(\\w)} " inlined "
- => {in n li i ne e}
+\fBregexp\fR -inline -- {\ew(\ew)} " inlined "
+ \fI\(-> in n\fR
+\fBregexp\fR -all -inline -- {\ew(\ew)} " inlined "
+ \fI\(-> in n li i ne e\fR
.CE
.TP 15
\fB\-start\fR \fIindex\fR
Specifies a character index offset into the string to start
-matching the regular expression at. When using this switch, `^'
-will not match the beginning of the line, and \\A will still
+matching the regular expression at.
+.VS 8.5
+The \fIindex\fR value is interpreted in the same manner
+as the \fIindex\fR argument to \fBstring index\fR.
+.VE 8.5
+When using this switch,
+.QW ^
+will not match the beginning of the line, and \eA will still
match the start of the string at \fIindex\fR. If \fB\-indices\fR
is specified, the indices will be indexed starting from the
absolute beginning of the input string.
\fIindex\fR will be constrained to the bounds of the input string.
-.VE 8.3
.TP 15
\fB\-\|\-\fR
Marks the end of switches. The argument following this one will
be treated as \fIexp\fR even if it starts with a \fB\-\fR.
.PP
-If there are more \fIsubMatchVar\fR's than parenthesized
+If there are more \fIsubMatchVar\fRs than parenthesized
subexpressions within \fIexp\fR, or if a particular subexpression
-in \fIexp\fR doesn't match the string (e.g. because it was in a
-portion of the expression that wasn't matched), then the corresponding
-\fIsubMatchVar\fR will be set to ``\fB\-1 \-1\fR'' if \fB\-indices\fR
-has been specified or to an empty string otherwise.
+in \fIexp\fR does not match the string (e.g. because it was in a
+portion of the expression that was not matched), then the corresponding
+\fIsubMatchVar\fR will be set to
+.QW "\fB\-1 \-1\fR"
+if \fB\-indices\fR has been specified or to an empty string otherwise.
.SH EXAMPLES
+.PP
Find the first occurrence of a word starting with \fBfoo\fR in a
string that is not actually an instance of \fBfoobar\fR, and get the
letters following it up to the end of the word into a variable:
.CS
-\fBregexp\fR {\\<foo(?!bar\\>)(\\w*)} $string \-> restOfWord
+\fBregexp\fR {\emfoo(?!bar\eM)(\ew*)} $string \-> restOfWord
.CE
Note that the whole matched substring has been placed in the variable
-\fB\->\fR which is a name chosen to look nice given that we are not
+.QW \fB\->\fR ,
+which is a name chosen to look nice given that we are not
actually interested in its contents.
.PP
Find the index of the word \fBbadger\fR (in any case) within a string
and store that in the variable \fBlocation\fR:
.CS
-\fBregexp\fR \-indices {(?i)\\<badger\\>} $string location
+\fBregexp\fR \-indices {(?i)\embadger\eM} $string location
+.CE
+This could also be written as a \fIbasic\fR regular expression (as opposed
+to using the default syntax of \fIadvanced\fR regular expressions) match by
+prefixing the expression with a suitable flag:
+.CS
+\fBregexp\fR \-indices {(?ib)\e<badger\e>} $string location
.CE
.PP
-Count the number of octal digits in a string:
+This counts the number of octal digits in a string:
.CS
\fBregexp\fR \-all {[0\-7]} $string
.CE
.PP
-List all words (consisting of all sequences of non-whitespace
-characters) in a string:
+This lists all words (consisting of all sequences of non-whitespace
+characters) in a string, and is useful as a more powerful version of the
+\fBsplit\fR command:
.CS
-\fBregexp\fR \-all \-inline {\\S+} $string
+\fBregexp\fR \-all \-inline {\eS+} $string
.CE
-
.SH "SEE ALSO"
-re_syntax(n), regsub(n)
-
+re_syntax(n), regsub(n),
+.VS 8.5
+string(n)
+.VE
.SH KEYWORDS
-match, regular expression, string
+match, parsing, pattern, regular expression, splitting, string
diff --git a/doc/registry.n b/doc/registry.n
index 6809cb7..e4371e6 100644
--- a/doc/registry.n
+++ b/doc/registry.n
@@ -17,7 +17,6 @@ registry \- Manipulate the Windows registry
.sp
\fBregistry \fIoption\fR \fIkeyName\fR ?\fIarg arg ...\fR?
.BE
-
.SH DESCRIPTION
.PP
The \fBregistry\fR package provides a general set of operations for
@@ -28,29 +27,28 @@ as a corrupted registry can leave your system in an unusable state.
.PP
\fIKeyName\fR is the name of a registry key. Registry keys must be
one of the following forms:
-.IP
+.RS
+.PP
\fB\e\e\fIhostname\fB\e\fIrootname\fB\e\fIkeypath\fR
-.IP
+.PP
\fIrootname\fB\e\fIkeypath\fR
-.IP
+.PP
\fIrootname\fR
+.RE
.PP
\fIHostname\fR specifies the name of any valid Windows
host that exports its registry. The \fIrootname\fR component must be
one of \fBHKEY_LOCAL_MACHINE\fR, \fBHKEY_USERS\fR,
-.VS
\fBHKEY_CLASSES_ROOT\fR, \fBHKEY_CURRENT_USER\fR,
\fBHKEY_CURRENT_CONFIG\fR, \fBHKEY_PERFORMANCE_DATA\fR, or
\fBHKEY_DYN_DATA\fR. The \fIkeypath\fR can be one or more
-.VE
registry key names separated by backslash (\fB\e\fR) characters.
.PP
\fIOption\fR indicates what to do with the registry key name. Any
unique abbreviation for \fIoption\fR is acceptable. The valid options
are:
-.VS 8.4
.TP
-\fBregistry broadcast \fIkeyName\fR ?\fI-timeout milliseconds\fR?
+\fBregistry broadcast \fIkeyName\fR ?\fB\-timeout \fImilliseconds\fR?
.
Sends a broadcast message to the system and running programs to notify them
of certain updates. This is necessary to propagate changes to key registry
@@ -59,13 +57,22 @@ milliseconds, to wait for applications to respond to the broadcast message.
It defaults to 3000. The following example demonstrates how to add a path
to the global Environment and notify applications of the change without
requiring a logoff/logon step (assumes admin privileges):
+.RS
+.PP
.CS
-set regPath {HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment}
-set curPath [registry get $regPath "Path"]
-registry set $regPath "Path" "$curPath;$addPath"
-registry broadcast "Environment"
+set regPath [join {
+ HKEY_LOCAL_MACHINE
+ SYSTEM
+ CurrentControlSet
+ Control
+ {Session Manager}
+ Environment
+} "\e\e"]
+set curPath [\fBregistry get\fR $regPath "Path"]
+\fBregistry set\fR $regPath "Path" "$curPath;$addPath"
+\fBregistry broadcast\fR "Environment"
.CE
-.VE 8.4
+.RE
.TP
\fBregistry delete \fIkeyName\fR ?\fIvalueName\fR?
.
@@ -81,11 +88,11 @@ did not exist, the command has no effect.
Returns the data associated with the value \fIvalueName\fR under the key
\fIkeyName\fR. If either the key or the value does not exist, then an
error is generated. For more details on the format of the returned
-data, see SUPPORTED TYPES, below.
+data, see \fBSUPPORTED TYPES\fR, below.
.TP
\fBregistry keys \fIkeyName\fR ?\fIpattern\fR?
.
-If \fIpattern\fR isn't specified, returns a list of names of all the
+If \fIpattern\fR is not specified, returns a list of names of all the
subkeys of \fIkeyName\fR. If \fIpattern\fR is specified, only those
names matching \fIpattern\fR are returned. Matching is determined
using the same rules as for \fBstring\fR \fBmatch\fR. If the
@@ -93,27 +100,26 @@ specified \fIkeyName\fR does not exist, then an error is generated.
.TP
\fBregistry set \fIkeyName\fR ?\fIvalueName data \fR?\fItype\fR??
.
-If \fIvalueName\fR isn't specified, creates the key \fIkeyName\fR if
-it doesn't already exist. If \fIvalueName\fR is specified, creates
+If \fIvalueName\fR is not specified, creates the key \fIkeyName\fR if
+it does not already exist. If \fIvalueName\fR is specified, creates
the key \fIkeyName\fR and value \fIvalueName\fR if necessary. The
contents of \fIvalueName\fR are set to \fIdata\fR with the type
-indicated by \fItype\fR. If \fItype\fR isn't specified, the type
+indicated by \fItype\fR. If \fItype\fR is not specified, the type
\fBsz\fR is assumed. For more details on the data and type arguments,
-see SUPPORTED TYPES below.
+see \fBSUPPORTED TYPES\fR below.
.TP
\fBregistry type \fIkeyName valueName\fR
.
Returns the type of the value \fIvalueName\fR in the key
\fIkeyName\fR. For more information on the possible types, see
-SUPPORTED TYPES, below.
+\fBSUPPORTED TYPES\fR, below.
.TP
\fBregistry values \fIkeyName\fR ?\fIpattern\fR?
.
-If \fIpattern\fR isn't specified, returns a list of names of all the
+If \fIpattern\fR is not specified, returns a list of names of all the
values of \fIkeyName\fR. If \fIpattern\fR is specified, only those
names matching \fIpattern\fR are returned. Matching is determined
using the same rules as for \fBstring\fR \fBmatch\fR.
-
.SH "SUPPORTED TYPES"
Each value under a key in the registry contains some data of a
particular type in a type-specific representation. The \fBregistry\fR
@@ -145,8 +151,9 @@ represented in Tcl as a string.
.
The registry value contains a null-terminated string that contains
unexpanded references to environment variables in the normal Windows
-style (for example, "%PATH%"). The data is represented in Tcl as a
-string.
+style (for example,
+.QW %PATH% ).
+The data is represented in Tcl as a string.
.TP
\fBdword\fR
.
@@ -182,6 +189,7 @@ The registry command is only available on Windows.
.SH EXAMPLE
Print out how double-clicking on a Tcl script file will invoke a Tcl
interpreter:
+.PP
.CS
package require registry
set ext .tcl
@@ -195,6 +203,5 @@ set command [\fBregistry get\fR $path {}]
puts "$ext opens with $command"
.CE
-
.SH KEYWORDS
registry
diff --git a/doc/regsub.n b/doc/regsub.n
index 4e5e88d..5adfd61 100644
--- a/doc/regsub.n
+++ b/doc/regsub.n
@@ -13,40 +13,41 @@
.SH NAME
regsub \- Perform substitutions based on regular expression pattern matching
.SH SYNOPSIS
-.VS 8.4
\fBregsub \fR?\fIswitches\fR? \fIexp string subSpec \fR?\fIvarName\fR?
-.VE 8.4
.BE
-
.SH DESCRIPTION
.PP
This command matches the regular expression \fIexp\fR against
\fIstring\fR,
-.VS 8.4
and either copies \fIstring\fR to the variable whose name is
given by \fIvarName\fR or returns \fIstring\fR if \fIvarName\fR is not
present.
-.VE 8.4
(Regular expression matching is described in the \fBre_syntax\fR
reference page.)
If there is a match, then while copying \fIstring\fR to \fIvarName\fR
-.VS 8.4
(or to the result of this command if \fIvarName\fR is not present)
-.VE 8.4
the portion of \fIstring\fR that
matched \fIexp\fR is replaced with \fIsubSpec\fR.
-If \fIsubSpec\fR contains a ``&'' or ``\e0'', then it is replaced
-in the substitution with the portion of \fIstring\fR that
-matched \fIexp\fR.
-If \fIsubSpec\fR contains a ``\e\fIn\fR'', where \fIn\fR is a digit
+If \fIsubSpec\fR contains a
+.QW &
+or
+.QW \e0 ,
+then it is replaced in the substitution with the portion of
+\fIstring\fR that matched \fIexp\fR.
+If \fIsubSpec\fR contains a
+.QW \e\fIn\fR ,
+where \fIn\fR is a digit
between 1 and 9, then it is replaced in the substitution with
-the portion of \fIstring\fR that matched the \fIn\fR-th
+the portion of \fIstring\fR that matched the \fIn\fR'th
parenthesized subexpression of \fIexp\fR.
Additional backslashes may be used in \fIsubSpec\fR to prevent special
-interpretation of ``&'' or ``\e0'' or ``\e\fIn\fR'' or
-backslash.
+interpretation of
+.QW & ,
+.QW \e0 ,
+.QW \e\fIn\fR
+and backslashes.
The use of backslashes in \fIsubSpec\fR tends to interact badly
-with the Tcl parser's use of backslashes, so it's generally
+with the Tcl parser's use of backslashes, so it is generally
safest to enclose \fIsubSpec\fR in braces if it includes
backslashes.
.LP
@@ -59,7 +60,10 @@ All ranges in \fIstring\fR that match \fIexp\fR are found and
substitution is performed for each of these ranges.
Without this switch only the first
matching range is found and substituted.
-If \fB\-all\fR is specified, then ``&'' and ``\e\fIn\fR''
+If \fB\-all\fR is specified, then
+.QW &
+and
+.QW \e\fIn\fR
sequences are handled for each substitution using the information
from the corresponding match.
.TP 15
@@ -70,21 +74,37 @@ the \fB(?x)\fR embedded option (see the \fBre_syntax\fR manual page).
.TP 15
\fB\-line\fR
Enables newline-sensitive matching. By default, newline is a
-completely ordinary character with no special meaning. With this
-flag, `[^' bracket expressions and `.' never match newline, `^'
+completely ordinary character with no special meaning. With this flag,
+.QW [^
+bracket expressions and
+.QW .
+never match newline,
+.QW ^
matches an empty string after any newline in addition to its normal
-function, and `$' matches an empty string before any newline in
+function, and
+.QW $
+matches an empty string before any newline in
addition to its normal function. This flag is equivalent to
specifying both \fB\-linestop\fR and \fB\-lineanchor\fR, or the
\fB(?n)\fR embedded option (see the \fBre_syntax\fR manual page).
.TP 15
\fB\-linestop\fR
-Changes the behavior of `[^' bracket expressions and `.' so that they
+Changes the behavior of
+.QW [^
+bracket expressions and
+.QW .
+so that they
stop at newlines. This is the same as specifying the \fB(?p)\fR
embedded option (see the \fBre_syntax\fR manual page).
.TP 15
\fB\-lineanchor\fR
-Changes the behavior of `^' and `$' (the ``anchors'') so they match the
+Changes the behavior of
+.QW ^
+and
+.QW $
+(the
+.QW anchors )
+so they match the
beginning and end of a line respectively. This is the same as
specifying the \fB(?w)\fR embedded option (see the \fBre_syntax\fR
manual page).
@@ -96,8 +116,14 @@ by \fIsubSpec\fR use the original unconverted form of \fIstring\fR.
.TP 10
\fB\-start\fR \fIindex\fR
Specifies a character index offset into the string to start
-matching the regular expression at. When using this switch, `^'
-will not match the beginning of the line, and \\A will still
+matching the regular expression at.
+.VS 8.5
+The \fIindex\fR value is interpreted in the same manner
+as the \fIindex\fR argument to \fBstring index\fR.
+.VE 8.5
+When using this switch,
+.QW ^
+will not match the beginning of the line, and \eA will still
match the start of the string at \fIindex\fR.
\fIindex\fR will be constrained to the bounds of the input string.
.TP 10
@@ -105,42 +131,51 @@ match the start of the string at \fIindex\fR.
Marks the end of switches. The argument following this one will
be treated as \fIexp\fR even if it starts with a \fB\-\fR.
.PP
-.VS 8.4
If \fIvarName\fR is supplied, the command returns a count of the
number of matching ranges that were found and replaced, otherwise the
string after replacement is returned.
-.VE 8.4
See the manual entry for \fBregexp\fR for details on the interpretation
of regular expressions.
.SH EXAMPLES
+.PP
Replace (in the string in variable \fIstring\fR) every instance of
\fBfoo\fR which is a word by itself with \fBbar\fR:
.CS
-\fBregsub\fR -all {\e<foo\e>} $string bar string
+\fBregsub\fR -all {\emfoo\eM} $string bar string
+.CE
+or (using the
+.QW "basic regular expression"
+syntax):
+.CS
+\fBregsub\fR -all {(?b)\e<foo\e>} $string bar string
.CE
.PP
Insert double-quotes around the first instance of the word
-\fBinteresting\fR, however it is capitalised.
+\fBinteresting\fR, however it is capitalized.
.CS
-\fBregsub\fR -nocase {\e<interesting\e>} $string {"&"} string
+\fBregsub\fR -nocase {\eyinteresting\ey} $string {"&"} string
.CE
.PP
Convert all non-ASCII and Tcl-significant characters into \eu escape
sequences by using \fBregsub\fR and \fBsubst\fR in combination:
.CS
-# This RE is just a character class for everything "bad"
-set RE {[][{}\e$\es\eu0100-\euffff]}
+# This RE is just a character class for almost everything "bad"
+set RE {[][{};#\e\e\e$ \er\et\eu0080-\euffff]}
# We will substitute with a fragment of Tcl script in brackets
set substitution {[format \e\e\e\eu%04x [scan "\e\e&" %c]]}
# Now we apply the substitution to get a subst-string that
-# will perform the computational parts of the conversion.
-set quoted [subst [\fBregsub\fR -all $RE $string $substitution]]
+# will perform the computational parts of the conversion. Note
+# that newline is handled specially through \fBstring map\fR since
+# backslash-newline is a special sequence.
+set quoted [subst [string map {\en {\e\eu000a}} \e
+ [\fBregsub\fR -all $RE $string $substitution]]]
.CE
-
.SH "SEE ALSO"
-regexp(n), re_syntax(n), subst(n)
-
+regexp(n), re_syntax(n), subst(n),
+.VS 8.5
+string(n)
+.VE
.SH KEYWORDS
-match, pattern, regular expression, substitute
+match, pattern, quoting, regular expression, substitute
diff --git a/doc/resource.n b/doc/resource.n
deleted file mode 100644
index d8d2fbf..0000000
--- a/doc/resource.n
+++ /dev/null
@@ -1,154 +0,0 @@
-'\"
-'\" Copyright (c) 1997 Sun Microsystems, Inc.
-'\"
-'\" 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 resource n 8.0 Tcl "Tcl Built-In Commands"
-.BS
-'\" Note: do not modify the .SH NAME line immediately below!
-.SH NAME
-resource \- Manipulate Macintosh resources
-.SH SYNOPSIS
-\fBresource \fIoption\fR ?\fIarg arg ...\fR?
-.BE
-
-.SH DESCRIPTION
-.PP
-The \fBresource\fR command provides some generic operations for
-dealing with Macintosh resources. This command is only supported on
-the Macintosh platform. Each Macintosh file consists of two
-\fIforks\fR: a \fIdata\fR fork and a \fIresource\fR fork. You use the
-normal open, puts, close, etc. commands to manipulate the data fork.
-You must use this command, however, to interact with the resource
-fork. \fIOption\fR indicates what resource command to perform. Any
-unique abbreviation for \fIoption\fR is acceptable. The valid options
-are:
-.TP
-\fBresource close \fIrsrcRef\fR
-Closes the given resource reference (obtained from \fBresource
-open\fR). Resources from that resource file will no longer be
-available.
-.TP
-\fBresource delete\fR ?\fIoptions\fR? \fIresourceType\fR
-This command will delete the resource specified by \fIoptions\fR and
-type \fIresourceType\fR (see RESOURCE TYPES below). The options
-give you several ways to specify the resource to be deleted.
-.RS
-.TP
-\fB\-id\fR \fIresourceId\fR
-If the \fB-id\fR option is given the id \fIresourceId\fR (see RESOURCE
-IDS below) is used to specify the resource to be deleted. The id must
-be a number - to specify a name use the \fB\-name\fR option.
-.TP
-\fB\-name\fR \fIresourceName\fR
-If \fB-name\fR is specified, the resource named
-\fIresourceName\fR will be deleted. If the \fB-id\fR is also
-provided, then there must be a resource with BOTH this name and
-this id. If no name is provided, then the id will be used regardless
-of the name of the actual resource.
-.TP
-\fB\-file\fR \fIresourceRef\fR
-If the \fB-file\fR option is specified then the resource will be
-deleted from the file pointed to by \fIresourceRef\fR. Otherwise the
-first resource with the given \fIresourceName\fR and or
-\fIresourceId\fR which is found on the resource file path will be
-deleted. To inspect the file path, use the \fIresource files\fR command.
-.RE
-.TP
-\fBresource files ?\fIresourceRef\fR?
-If \fIresourceRef\fRis not provided, this command returns a Tcl list
-of the resource references for all the currently open resource files.
-The list is in the normal Macintosh search order for resources. If
-\fIresourceRef\fR is specified, the command will
-return the path to the file whose resource fork is represented by that
-token.
-.TP
-\fBresource list \fIresourceType\fR ?\fIresourceRef\fR?
-List all of the resources ids of type \fIresourceType\fR (see RESOURCE
-TYPES below). If \fIresourceRef\fR is specified then the command will
-limit the search to that particular resource file. Otherwise, all
-resource files currently opened by the application will be searched.
-A Tcl list of either the resource name's or resource id's of the found
-resources will be returned. See the RESOURCE IDS section below for
-more details about what a resource id is.
-.TP
-\fBresource open \fIfileName\fR ?\fIaccess\fR?
-Open the resource for the file \fIfileName\fR. Standard file access
-permissions may also be specified (see the manual entry for \fBopen\fR
-for details). A resource reference (\fIresourceRef\fR) is returned
-that can be used by the other resource commands. An error can occur
-if the file doesn't exist or the file does not have a resource fork.
-However, if you open the file with write permissions the file and/or
-resource fork will be created instead of generating an error.
-.TP
-\fBresource read \fIresourceType\fR \fIresourceId\fR ?\fIresourceRef\fR?
-Read the entire resource of type \fIresourceType\fR (see RESOURCE
-TYPES below) and the name or id of \fIresourceId\fR (see RESOURCE IDS
-below) into memory and return the result. If \fIresourceRef\fR is
-specified we limit our search to that resource file, otherwise we
-search all open resource forks in the application. It is important to
-note that most Macintosh resource use a binary format and the data
-returned from this command may have embedded NULLs or other non-ASCII
-data.
-.TP
-\fBresource types ?\fIresourceRef\fR?
-This command returns a Tcl list of all resource types (see RESOURCE
-TYPES below) found in the resource file pointed to by
-\fIresourceRef\fR. If \fIresourceRef\fR is not specified it will
-return all the resource types found in every resource file currently
-opened by the application.
-.TP
-\fBresource write\fR ?\fIoptions\fR? \fIresourceType\fR \fIdata\fR
-This command will write the passed in \fIdata\fR as a new resource of
-type \fIresourceType\fR (see RESOURCE TYPES below). Several options
-are available that describe where and how the resource is stored.
-.RS
-.TP
-\fB\-id\fR \fIresourceId\fR
-If the \fB-id\fR option is given the id \fIresourceId\fR (see RESOURCE
-IDS below) is used for the new resource, otherwise a unique id will be
-generated that will not conflict with any existing resource. However,
-the id must be a number - to specify a name use the \fB\-name\fR option.
-.TP
-\fB\-name\fR \fIresourceName\fR
-If \fB-name\fR is specified the resource will be named
-\fIresourceName\fR, otherwise it will have the empty string as the
-name.
-.TP
-\fB\-file\fR \fIresourceRef\fR
-If the \fB-file\fR option is specified then the resource will be
-written in the file pointed to by \fIresourceRef\fR, otherwise the
-most recently open resource will be used.
-.TP
-\fB\-force\fR
-If the target resource already exists, then by default Tcl will not
-overwrite it, but raise an error instead. Use the -force flag to
-force overwriting the extant resource.
-.RE
-
-.SH "RESOURCE TYPES"
-Resource types are defined as a four character string that is then
-mapped to an underlying id. For example, \fBTEXT\fR refers to the
-Macintosh resource type for text. The type \fBSTR#\fR is a list of
-counted strings. All Macintosh resources must be of some type. See
-Macintosh documentation for a more complete list of resource types
-that are commonly used.
-
-.SH "RESOURCE IDS"
-For this command the notion of a resource id actually refers to two
-ideas in Macintosh resources. Every place you can use a resource Id
-you can use either the resource name or a resource number. Names are
-always searched or returned in preference to numbers. For example,
-the \fBresource list\fR command will return names if they exist or
-numbers if the name is NULL.
-
-.SH "PORTABILITY ISSUES"
-The resource command is only available on Macintosh.
-
-.SH "SEE ALSO"
-open(n)
-
-.SH KEYWORDS
-open, resource
diff --git a/doc/return.n b/doc/return.n
index 25cf8b4..b08de4a 100644
--- a/doc/return.n
+++ b/doc/return.n
@@ -1,32 +1,45 @@
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Contributions from Don Porter, NIST, 2003. (not subject to US copyright)
'\"
'\" 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 7.0 Tcl "Tcl Built-In Commands"
+.TH return n 8.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
-return \- Return from a procedure
+return \- Return from a procedure, or set return code of a script
.SH SYNOPSIS
-\fBreturn \fR?\fB\-code \fIcode\fR? ?\fB\-errorinfo \fIinfo\fR? ?\fB\-errorcode\fI code\fR? ?\fIstring\fR?
+\fBreturn \fR?\fIresult\fR?
+.sp
+\fBreturn \fR?\fB\-code \fIcode\fR? ?\fIresult\fR?
+.sp
+\fBreturn \fR?\fIoption value \fR...? ?\fIresult\fR?
.BE
-
.SH DESCRIPTION
.PP
-Return immediately from the current procedure
-(or top-level command or \fBsource\fR command),
-with \fIstring\fR as the return value. If \fIstring\fR is not specified then
-an empty string will be returned as result.
+In its simplest usage, the \fBreturn\fR command is used without options
+in the body of a procedure to immediately return control to the caller
+of the procedure. If a \fIresult\fR argument is provided, its value
+becomes the result of the procedure passed back to the caller.
+If \fIresult\fR is not specified then an empty string will be returned
+to the caller as the result of the procedure.
+.PP
+The \fBreturn\fR command serves a similar function within script
+files that are evaluated by the \fBsource\fR command. When \fBsource\fR
+evaluates the contents of a file as a script, an invocation of
+the \fBreturn\fR command will cause script evaluation
+to immediately cease, and the value \fIresult\fR (or an empty string)
+will be returned as the result of the \fBsource\fR command.
.SH "EXCEPTIONAL RETURN CODES"
.PP
In addition to the result of a procedure, the return
code of a procedure may also be set by \fBreturn\fR
-through use of the \fB-code\fR option.
-In the usual case where the \fB\-code\fR option isn't
+through use of the \fB\-code\fR option.
+In the usual case where the \fB\-code\fR option is not
specified the procedure will return normally.
However, the \fB\-code\fR option may be used to generate an
exceptional return from the procedure.
@@ -61,29 +74,135 @@ were the command \fBcontinue\fR.
\fIValue\fR must be an integer; it will be returned as the
return code for the current procedure.
.LP
-The \fB\-code\fR option is rarely used.
-It is provided so that procedures that implement
-new control structures can reflect exceptional conditions back to
-their callers.
-.PP
-Two additional options, \fB\-errorinfo\fR and \fB\-errorcode\fR,
-may be used to provide additional information during error
-returns.
-These options are ignored unless \fIcode\fR is \fBerror\fR.
-.PP
-The \fB\-errorinfo\fR option specifies an initial stack
-trace for the \fBerrorInfo\fR variable; if it is not specified then
-the stack trace left in \fBerrorInfo\fR will include the call to
-the procedure and higher levels on the stack but it will not include
-any information about the context of the error within the procedure.
-Typically the \fIinfo\fR value is supplied from the value left
-in \fBerrorInfo\fR after a \fBcatch\fR command trapped an error within
-the procedure.
-.PP
-If the \fB\-errorcode\fR option is specified then \fIcode\fR provides
-a value for the \fBerrorCode\fR variable.
-If the option is not specified then \fBerrorCode\fR will
-default to \fBNONE\fR.
+When a procedure wants to signal that it has received invalid
+arguments from its caller, it may use \fBreturn -code error\fR
+with \fIresult\fR set to a suitable error message. Otherwise
+usage of the \fBreturn -code\fR option is mostly limited to
+procedures that implement a new control structure.
+.PP
+The \fBreturn \-code\fR command acts similarly within script
+files that are evaluated by the \fBsource\fR command. During the
+evaluation of the contents of a file as a script by \fBsource\fR,
+an invocation of the \fBreturn \-code \fIcode\fR command will cause
+the return code of \fBsource\fR to be \fIcode\fR.
+.SH "RETURN OPTIONS"
+.PP
+.VS 8.5
+In addition to a result and a return code, evaluation of a command
+in Tcl also produces a dictionary of return options. In general
+usage, all \fIoption value\fR pairs given as arguments to \fBreturn\fR
+become entries in the return options dictionary, and any values at all
+are acceptable except as noted below. The \fBcatch\fR command may be
+used to capture all of this information \(em the return code, the result,
+and the return options dictionary \(em that arise from evaluation of a
+script.
+.VE 8.5
+.PP
+As documented above, the \fB\-code\fR entry in the return options dictionary
+receives special treatment by Tcl. There are other return options also
+recognized and treated specially by Tcl. They are:
+.TP
+\fB\-errorcode \fIlist\fR
+The \fB\-errorcode\fR option receives special treatment only when the value
+of the \fB\-code\fR option is \fBTCL_ERROR\fR. Then the \fIlist\fR value
+is meant to be additional information about the error,
+presented as a Tcl list for further processing by programs.
+If no \fB\-errorcode\fR option is provided to \fBreturn\fR when
+the \fB\-code error\fR option is provided, Tcl will set the value
+of the \fB\-errorcode\fR entry in the return options dictionary
+to the default value of \fBNONE\fR. The \fB\-errorcode\fR return
+option will also be stored in the global variable \fBerrorCode\fR.
+.TP
+\fB\-errorinfo \fIinfo\fR
+The \fB\-errorinfo\fR option receives special treatment only when the value
+of the \fB\-code\fR option is \fBTCL_ERROR\fR. Then \fIinfo\fR is the initial
+stack trace, meant to provide to a human reader additional information
+about the context in which the error occurred. The stack trace will
+also be stored in the global variable \fBerrorInfo\fR.
+If no \fB\-errorinfo\fR option is provided to \fBreturn\fR when
+the \fB\-code error\fR option is provided, Tcl will provide its own
+initial stack trace value in the entry for \fB\-errorinfo\fR. Tcl's
+initial stack trace will include only the call to the procedure, and
+stack unwinding will append information about higher stack levels, but
+there will be no information about the context of the error within
+the procedure. Typically the \fIinfo\fR value is supplied from
+the value of \fB\-errorinfo\fR in a return options dictionary captured
+by the \fBcatch\fR command (or from the copy of that information
+stored in the global variable \fBerrorInfo\fR).
+.TP
+\fB\-level \fIlevel\fR
+.VS 8.5
+The \fB\-level\fR and \fB\-code\fR options work together to set the return
+code to be returned by one of the commands currently being evaluated.
+The \fIlevel\fR value must be a non-negative integer representing a number
+of levels on the call stack. It defines the number of levels up the stack
+at which the return code of a command currently being evaluated should
+be \fIcode\fR. If no \fB\-level\fR option is provided, the default value
+of \fIlevel\fR is 1, so that \fBreturn\fR sets the return code that the
+current procedure returns to its caller, 1 level up the call stack. The
+mechanism by which these options work is described in more detail below.
+.VE 8.5
+.TP
+\fB\-options \fIoptions\fR
+.VS 8.5
+The value \fIoptions\fR must be a valid dictionary. The entries of that
+dictionary are treated as additional \fIoption value\fR pairs for the
+\fBreturn\fR command.
+.VE 8.5
+.SH "RETURN CODE HANDLING MECHANISMS"
+.PP
+Return codes are used in Tcl to control program flow. A Tcl script
+is a sequence of Tcl commands. So long as each command evaluation
+returns a return code of \fBTCL_OK\fR, evaluation will continue to the next
+command in the script. Any exceptional return code (non-\fBTCL_OK\fR)
+returned by a command evaluation causes the flow on to the next
+command to be interrupted. Script evaluation ceases, and the
+exceptional return code from the command becomes the return code
+of the full script evaluation. This is the mechanism by which
+errors during script evaluation cause an interruption and unwinding
+of the call stack. It is also the mechanism by which commands
+like \fBbreak\fR, \fBcontinue\fR, and \fBreturn\fR cause script
+evaluation to terminate without evaluating all commands in sequence.
+.PP
+Some of Tcl's built-in commands evaluate scripts as part of their
+functioning. These commands can make use of exceptional return
+codes to enable special features. For example, the built-in
+Tcl commands that provide loops \(em such as \fBwhile\fR, \fBfor\fR,
+and \fBforeach\fR \(em evaluate a script that is the body of the
+loop. If evaluation of the loop body returns the return code
+of \fBTCL_BREAK\fR or \fBTCL_CONTINUE\fR, the loop command can react in such
+a way as to give the \fBbreak\fR and \fBcontinue\fR commands
+their documented interpretation in loops.
+.PP
+.VS 8.5
+Procedure invocation also involves evaluation of a script, the body
+of the procedure. Procedure invocation provides special treatment
+when evaluation of the procedure body returns the return code
+\fBTCL_RETURN\fR. In that circumstance, the \fB\-level\fR entry in the
+return options dictionary is decremented. If after decrementing,
+the value of the \fB\-level\fR entry is 0, then the value of
+the \fB\-code\fR entry becomes the return code of the procedure.
+If after decrementing, the value of the \fB\-level\fR entry is
+greater than zero, then the return code of the procedure is
+\fBTCL_RETURN\fR. If the procedure invocation occurred during the
+evaluation of the body of another procedure, the process will
+repeat itself up the call stack, decrementing the value of the
+\fB\-level\fR entry at each level, so that the \fIcode\fR will
+be the return code of the current command \fIlevel\fR levels
+up the call stack. The \fBsource\fR command performs the
+same handling of the \fBTCL_RETURN\fR return code, which explains
+the similarity of \fBreturn\fR invocation during a \fBsource\fR
+to \fBreturn\fR invocation within a procedure.
+.PP
+The return code of the \fBreturn\fR command itself triggers this
+special handling by procedure invocation. If \fBreturn\fR
+is provided the option \fB\-level 0\fR, then the return code
+of the \fBreturn\fR command itself will be the value \fIcode\fR
+of the \fB\-code\fR option (or \fBTCL_OK\fR by default). Any other value
+for the \fB\-level\fR option (including the default value of 1)
+will cause the return code of the \fBreturn\fR command itself
+to be \fBTCL_RETURN\fR, triggering a return from the enclosing procedure.
+.VE 8.5
.SH EXAMPLES
First, a simple example of using \fBreturn\fR to return from a
procedure, interrupting the procedure body.
@@ -107,9 +226,9 @@ to report invalid arguments.
.CS
proc factorial {n} {
if {![string is integer $n] || ($n < 0)} {
- \fBreturn\fR -code error \\
- "expected non-negative integer,\\
- but got \\"$n\\""
+ \fBreturn\fR -code error \e
+ "expected non-negative integer,\e
+ but got \e"$n\e""
}
if {$n < 2} {
\fBreturn\fR 1
@@ -121,7 +240,7 @@ proc factorial {n} {
}
set product [expr {$n * $factor}]
if {$product < 0} {
- \fBreturn\fR -code error \\
+ \fBreturn\fR -code error \e
"overflow computing factorial of $n"
}
\fBreturn\fR $product
@@ -134,9 +253,44 @@ proc myBreak {} {
\fBreturn\fR -code break
}
.CE
-
+.PP
+.VS 8.5
+With the \fB\-level 0\fR option, \fBreturn\fR itself can serve
+as a replacement for \fBbreak\fR.
+.CS
+interp alias {} Break {} \fBreturn\fR -level 0 -code break
+.CE
+.PP
+An example of using \fBcatch\fR and \fBreturn -options\fR to
+re-raise a caught error:
+.CS
+proc doSomething {} {
+ set resource [allocate]
+ catch {
+ # Long script of operations
+ # that might raise an error
+ } result options
+ deallocate $resource
+ \fBreturn\fR -options $options $result
+}
+.CE
+.PP
+Finally an example of advanced use of the \fBreturn\fR options
+to create a procedure replacement for \fBreturn\fR itself:
+.CS
+proc myReturn {args} {
+ set result ""
+ if {[llength $args] % 2} {
+ set result [lindex $args end]
+ set args [lrange $args 0 end-1]
+ }
+ set options [dict merge {-level 1} $args]
+ dict incr options -level
+ \fBreturn\fR -options $options $result
+}
+.CE
+.VE 8.5
.SH "SEE ALSO"
-break(n), catch(n), continue(n), error(n), proc(n), source(n), tclvars(n)
-
+break(n), catch(n), continue(n), dict(n), error(n), proc(n), source(n), tclvars(n)
.SH KEYWORDS
break, catch, continue, error, procedure, return
diff --git a/doc/safe.n b/doc/safe.n
index 6eabd79..78fa6ad 100644
--- a/doc/safe.n
+++ b/doc/safe.n
@@ -9,7 +9,7 @@
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
-Safe\ Base \- A mechanism for creating and manipulating safe interpreters.
+Safe\ Base \- A mechanism for creating and manipulating safe interpreters
.SH SYNOPSIS
\fB::safe::interpCreate\fR ?\fIslave\fR? ?\fIoptions...\fR?
.sp
@@ -24,14 +24,13 @@ Safe\ Base \- A mechanism for creating and manipulating safe interpreters.
\fB::safe::interpFindInAccessPath\fR \fIslave\fR \fIdirectory\fR
.sp
\fB::safe::setLogCmd\fR ?\fIcmd arg...\fR?
-.SH OPTIONS
+.SS OPTIONS
.PP
?\fB\-accessPath\fR \fIpathList\fR?
?\fB\-statics\fR \fIboolean\fR? ?\fB\-noStatics\fR?
?\fB\-nested\fR \fIboolean\fR? ?\fB\-nestedLoadOk\fR?
?\fB\-deleteHook\fR \fIscript\fR?
.BE
-
.SH DESCRIPTION
Safe Tcl is a mechanism for executing untrusted Tcl scripts
safely and for providing mediated access by such scripts to
@@ -61,8 +60,7 @@ Different levels of security can be selected by using the optional flags
of the commands described below.
.PP
All commands provided in the master interpreter by the Safe Base reside in
-the \fBsafe\fR namespace:
-
+the \fBsafe\fR namespace.
.SH COMMANDS
The following commands are provided in the master interpreter:
.TP
@@ -93,14 +91,17 @@ safe interpreter and change each and only the provided options.
See the section on \fBOPTIONS\fR below for options description.
Example of use:
.RS
+.PP
.CS
-# Create a new interp with the same configuration as "$i0" :
-set i1 [eval safe::interpCreate [safe::interpConfigure $i0]]
+# Create new interp with the same configuration as "$i0":
+set i1 [safe::interpCreate {*}[safe::interpConfigure $i0]]
+
# Get the current deleteHook
set dh [safe::interpConfigure $i0 \-del]
-# Change (only) the statics loading ok attribute of an interp
-# and its deleteHook (leaving the rest unchanged) :
-safe::interpConfigure $i0 \-delete {foo bar} \-statics 0 ;
+
+# Change (only) the statics loading ok attribute of an
+# interp and its deleteHook (leaving the rest unchanged):
+safe::interpConfigure $i0 \-delete {foo bar} \-statics 0
.CE
.RE
.TP
@@ -117,8 +118,10 @@ This command finds and returns the token for the real directory
It generates an error if the directory is not found.
Example of use:
.RS
+.PP
.CS
-$slave eval [list set tk_library [::safe::interpFindInAccessPath $name $tk_library]]
+$slave eval [list set tk_library \e
+ [::safe::interpFindInAccessPath $name $tk_library]]
.CE
.RE
.TP
@@ -130,8 +133,10 @@ If the directory is already in the virtual path, it only returns the token
without adding the directory to the virtual path again.
Example of use:
.RS
+.PP
.CS
-$slave eval [list set tk_library [::safe::interpAddToAccessPath $name $tk_library]]
+$slave eval [list set tk_library \e
+ [::safe::interpAddToAccessPath $name $tk_library]]
.CE
.RE
.TP
@@ -150,14 +155,18 @@ This prevents a safe interpreter from seeing messages about failures
and other events that might contain sensitive information such as real
directory names.
.RS
+.PP
Example of use:
+.PP
.CS
::safe::setLogCmd puts stderr
.CE
+.PP
Below is the output of a sample session in which a safe interpreter
attempted to source a file not found in its virtual access path.
Note that the safe interpreter only received an error message saying that
the file was not found:
+.PP
.CS
NOTICE for slave interp10 : Created
NOTICE for slave interp10 : Setting accessPath=(/foo/bar) staticsok=1 nestedok=0 deletehook=()
@@ -165,8 +174,7 @@ NOTICE for slave interp10 : auto_path in interp10 has been set to {$p(:0:)}
ERROR for slave interp10 : /foo/bar/init.tcl: no such file or directory
.CE
.RE
-
-.SH OPTIONS
+.SS OPTIONS
The following options are common to
\fB::safe::interpCreate\fR, \fB::safe::interpInit\fR,
and \fB::safe::interpConfigure\fR.
@@ -190,7 +198,7 @@ The default value is \fBtrue\fR :
safe interpreters are allowed to load statically linked packages.
.TP
\fB\-noStatics\fR
-This option is a convenience shortcut for \fB-statics false\fR and
+This option is a convenience shortcut for \fB\-statics false\fR and
thus specifies that the safe interpreter will not be allowed
to load statically linked packages.
.TP
@@ -202,7 +210,7 @@ safe interpreters are not allowed to load packages into
their own sub-interpreters.
.TP
\fB\-nestedLoadOk\fR
-This option is a convenience shortcut for \fB-nested true\fR and
+This option is a convenience shortcut for \fB\-nested true\fR and
thus specifies the safe interpreter will be allowed
to load packages into its own sub-interpreters.
.TP
@@ -252,7 +260,6 @@ the system encoding, but allows all other subcommands including
\fBexit\fR
The calling interpreter is deleted and its computation is stopped, but the
Tcl process in which this interpreter exists is not terminated.
-
.SH SECURITY
The Safe Base does not attempt to completely prevent annoyance and
denial of service attacks. These forms of attack prevent the
@@ -288,8 +295,7 @@ 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, \fItoken\fR\fB\\\fIfilename\fR on Windows,
-and \fItoken\fR\fB:\fR\fIfilename\fR on the Mac),
+on Unix and \fItoken\fR\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).
@@ -305,8 +311,12 @@ To further prevent potential information leakage from sensitive files that
are accidentally included in the set of files that can be sourced by a safe
interpreter, the \fBsource\fR alias restricts access to files
meeting the following constraints: the file name must
-fourteen characters or shorter, must not contain more than one dot ("\fB.\fR"),
-must end up with the extension \fB.tcl\fR or be called \fBtclIndex\fR.
+fourteen characters or shorter, must not contain more than one dot
+.PQ \fB.\fR "" ,
+must end up with the extension
+.PQ \fB.tcl\fR
+or be called
+.PQ \fBtclIndex\fR .
.PP
Each element of the initial access path
list will be assigned a token that will be set in
@@ -316,9 +326,9 @@ the \fBtcl_library\fR for that slave.
If the access path argument is not given or is the empty list,
the default behavior is to let the slave access the same packages
as the master has access to (Or to be more precise:
-only packages written in Tcl (which by definition can't be dangerous
+only packages written in Tcl (which by definition cannot be dangerous
as they run in the slave interpreter) and C extensions that
-provides a Safe_Init entry point). For that purpose, the master's
+provides a _SafeInit entry point). For that purpose, the master's
\fBauto_path\fR will be used to construct the slave access path.
In order that the slave successfully loads the Tcl library files
(which includes the auto-loading mechanism itself) the \fBtcl_library\fR will be
@@ -339,10 +349,8 @@ When the \fIaccessPath\fR is changed after the first creation or
initialization (i.e. through \fBinterpConfigure -accessPath \fR\fIlist\fR),
an \fBauto_reset\fR is automatically evaluated in the safe interpreter
to synchronize its \fBauto_index\fR with the new token list.
-
.SH "SEE ALSO"
interp(n), library(n), load(n), package(n), source(n), unknown(n)
-
.SH KEYWORDS
alias, auto\-loading, auto_mkindex, load, master interpreter, safe
interpreter, slave interpreter, source
diff --git a/doc/scan.n b/doc/scan.n
index 320280a..ca096da 100644
--- a/doc/scan.n
+++ b/doc/scan.n
@@ -15,17 +15,17 @@ scan \- Parse string using conversion specifiers in the style of sscanf
.SH SYNOPSIS
\fBscan \fIstring format \fR?\fIvarName varName ...\fR?
.BE
-
.SH INTRODUCTION
.PP
-This command parses fields from an input string in the same fashion as the
-ANSI C \fBsscanf\fR procedure and returns a count of the number of
+This command parses substrings from an input string in a fashion similar
+to the ANSI C \fBsscanf\fR procedure and returns a count of the number of
conversions performed, or -1 if the end of the input string is reached
before any conversions have been performed. \fIString\fR gives the input
to be parsed and \fIformat\fR indicates how to parse it, using \fB%\fR
conversion specifiers as in \fBsscanf\fR. Each \fIvarName\fR gives the
-name of a variable; when a field is scanned from \fIstring\fR the result is
-converted back into a string and assigned to the corresponding variable.
+name of a variable; when a substring is scanned from \fIstring\fR that
+matches a conversion specifier, the substring is assigned to the
+corresponding variable.
If no \fIvarName\fR variables are specified, then \fBscan\fR works in an
inline manner, returning the data that would otherwise be stored in the
variables as a list. In the inline case, an empty string is returned when
@@ -37,29 +37,28 @@ performed.
If the next character in \fIformat\fR is a blank or tab then it
matches any number of white space characters in \fIstring\fR (including
zero).
-Otherwise, if it isn't a \fB%\fR character then it
+Otherwise, if it is not a \fB%\fR character then it
must match the next character of \fIstring\fR.
When a \fB%\fR is encountered in \fIformat\fR, it indicates
the start of a conversion specifier.
-.VS 8.4
A conversion specifier contains up to four fields after the \fB%\fR:
-a \fB*\fR, which indicates that the converted value is to be discarded
-instead of assigned to a variable; a XPG3 position specifier; a number
-indicating a maximum field width; a field size modifier; and a
+a XPG3 position specifier (or a \fB*\fR to indicate the converted
+value is to be discarded instead of assigned to any variable); a number
+indicating a maximum substring width; a size modifier; and a
conversion character.
-.VE 8.4
All of these fields are optional except for the conversion character.
The fields that are present must appear in the order given above.
.PP
When \fBscan\fR finds a conversion specifier in \fIformat\fR, it
first skips any white-space characters in \fIstring\fR (unless the
-specifier is \fB[\fR or \fBc\fR).
+conversion character is \fB[\fR or \fBc\fR).
Then it converts the next input characters according to the
conversion specifier and stores the result in the variable given
by the next argument to \fBscan\fR.
.PP
If the \fB%\fR is followed by a decimal number and a \fB$\fR, as in
-``\fB%2$d\fR'', then the variable to use is not taken from the next
+.QW \fB%2$d\fR ,
+then the variable to use is not taken from the next
sequential argument. Instead, it is taken from the argument indicated
by the number, where 1 corresponds to the first \fIvarName\fR. If
there are any positional specifiers in \fIformat\fR then all of the
@@ -68,86 +67,75 @@ list must correspond to exactly one conversion specifier or an error
is generated, or in the inline case, any position can be specified
at most once and the empty positions will be filled in with empty strings.
.PP
+.VS 8.5
+The size modifier field is used only when scanning a substring into
+one of Tcl's integer values. The size modifier field dictates the
+integer range acceptable to be stored in a variable, or, for the inline
+case, in a position in the result list.
+The syntactically valid values for the size modifier are \fBh\fR, \fBL\fR,
+\fBl\fR, and \fBll\fR. The \fBh\fR size modifier value is equivalent
+to the absence of a size modifier in the the conversion specifier.
+Either one indicates the integer range to be stored is limited to
+the same range produced by the \fBint()\fR function of the \fBexpr\fR
+command. The \fBL\fR size modifier is equivalent to the \fBl\fR size
+modifier. Either one indicates the integer range to be stored is
+limited to the same range produced by the \fBwide()\fR function of
+the \fBexpr\fR command. The \fBll\fR size modifier indicates that
+the integer range to be stored is unlimited.
+.VE 8.5
+.PP
The following conversion characters are supported:
.TP 10
\fBd\fR
-The input field must be a decimal integer.
-It is read in and the value is stored in the variable as a decimal string.
-.VS 8.4
-If the \fBl\fR or \fBL\fR field size modifier is given, the scanned
-value will have an internal representation that is at least 64-bits in
-size.
-.VE 8.4
+The input substring must be a decimal integer.
+It is read in and the integer value is stored in the variable,
+truncated as required by the size modifier value.
.TP 10
\fBo\fR
-The input field must be an octal integer. It is read in and the
-value is stored in the variable as a decimal string.
-.VS 8.4
-If the \fBl\fR or \fBL\fR field size modifier is given, the scanned
-value will have an internal representation that is at least 64-bits in
-size.
-If the value exceeds MAX_INT (017777777777 on platforms using 32-bit
-integers when the \fBl\fR and \fBL\fR modifiers are not given), it
-will be truncated to a signed integer. Hence, 037777777777 will
-appear as -1 on a 32-bit machine by default.
-.VE 8.4
+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 10
\fBx\fR
-The input field must be a hexadecimal integer. It is read in
-and the value is stored in the variable as a decimal string.
-.VS 8.4
-If the \fBl\fR or \fBL\fR field size modifier is given, the scanned
-value will have an internal representation that is at least 64-bits in
-size.
-If the value exceeds MAX_INT (0x7FFFFFFF on platforms using 32-bit
-integers when the \fBl\fR and \fBL\fR modifiers are not given), it
-will be truncated to a signed integer. Hence, 0xFFFFFFFF will appear
-as -1 on a 32-bit machine.
-.VE 8.4
+The input substring must be a hexadecimal integer.
+It is read in and the integer value is stored in the variable,
+truncated as required by the size modifier value.
.TP 10
\fBu\fR
-The input field must be a decimal integer. The value is stored in the
-variable as an unsigned decimal integer string.
-.VS 8.4
-If the \fBl\fR or \fBL\fR field size modifier is given, the scanned
-value will have an internal representation that is at least 64-bits in
-size.
-.VE 8.4
+The input substring must be a decimal integer.
+The integer value is truncated as required by the size modifier
+value, and the corresponding unsigned value for that truncated
+range is computed and stored in the variable as a decimal string.
+The conversion makes no sense without reference to a truncation range,
+so the size modifier \fBll\fR is not permitted in combination
+with conversion character \fBu\fR.
.TP 10
\fBi\fR
-The input field must be an integer. The base (i.e. decimal, octal, or
-hexadecimal) is determined in the same fashion as described in
-\fBexpr\fR. The value is stored in the variable as a decimal string.
-.VS 8.4
-If the \fBl\fR or \fBL\fR field size modifier is given, the scanned
-value will have an internal representation that is at least 64-bits in
-size.
-.VE 8.4
+The input substring must be an integer. The base (i.e. decimal, binary,
+octal, or hexadecimal) is determined in the same fashion as described in
+\fBexpr\fR. The integer value is stored in the variable,
+truncated as required by the size modifier value.
.TP 10
\fBc\fR
-A single character is read in and its binary value is stored in
-the variable as a decimal string.
+A single character is read in and its Unicode value is stored in
+the variable as an integer value.
Initial white space is not skipped in this case, so the input
-field may be a white-space character.
-This conversion is different from the ANSI standard in that the
-input field always consists of a single character and no field
-width may be specified.
+substring may be a white-space character.
.TP 10
\fBs\fR
-The input field consists of all the characters up to the next
+The input substring consists of all the characters up to the next
white-space character; the characters are copied to the variable.
.TP 10
\fBe\fR or \fBf\fR or \fBg\fR
-The input field must be a floating-point number consisting
+The input substring must be a floating-point number consisting
of an optional sign, a string of decimal digits possibly
containing a decimal point, and an optional exponent consisting
of an \fBe\fR or \fBE\fR followed by an optional sign and a string of
decimal digits.
-It is read in and stored in the variable as a floating-point string.
+It is read in and stored in the variable as a floating-point value.
.TP 10
\fB[\fIchars\fB]\fR
-The input field consists of any number of characters in
-\fIchars\fR.
+The input substring consists of one or more characters in \fIchars\fR.
The matching string is stored in the variable.
If the first character between the brackets is a \fB]\fR then
it is treated as part of \fIchars\fR rather than the closing
@@ -159,8 +147,7 @@ If the first or last character between the brackets is a \fB\-\fR, then
it is treated as part of \fIchars\fR rather than indicating a range.
.TP 10
\fB[^\fIchars\fB]\fR
-The input field consists of any number of characters not in
-\fIchars\fR.
+The input substring consists of one or more characters not in \fIchars\fR.
The matching string is stored in the variable.
If the character immediately following the \fB^\fR is a \fB]\fR then it is
treated as part of the set rather than the closing bracket for
@@ -170,7 +157,7 @@ contains a sequence of the form \fIa\fB\-\fIb\fR then any
character between \fIa\fR and \fIb\fR (inclusive) will be excluded
from the set.
If the first or last character between the brackets is a \fB\-\fR, then
-it is treated as part of \fIchars\fR rather than indicating a range.
+it is treated as part of \fIchars\fR rather than indicating a range value.
.TP 10
\fBn\fR
No input is consumed from the input string. Instead, the total number
@@ -180,8 +167,8 @@ The number of characters read from the input for a conversion is the
largest number that makes sense for that particular conversion (e.g.
as many decimal digits as possible for \fB%d\fR, as
many octal digits as possible for \fB%o\fR, and so on).
-The input field for a given conversion terminates either when a
-white-space character is encountered or when the maximum field
+The input substring for a given conversion terminates either when a
+white-space character is encountered or when the maximum substring
width has been reached, whichever comes first.
If a \fB*\fR is present in the conversion specifier
then no variable is assigned and the next scan argument is not consumed.
@@ -190,24 +177,29 @@ then no variable is assigned and the next scan argument is not consumed.
The behavior of the \fBscan\fR command is the same as the behavior of
the ANSI C \fBsscanf\fR procedure except for the following differences:
.IP [1]
-\fB%p\fR conversion specifier is not currently supported.
+\fB%p\fR conversion specifier is not supported.
.IP [2]
For \fB%c\fR conversions a single character value is
converted to a decimal string, which is then assigned to the
corresponding \fIvarName\fR;
-no field width may be specified for this conversion.
+no substring width may be specified for this conversion.
.IP [3]
-.VS 8.4
The \fBh\fR modifier is always ignored and the \fBl\fR and \fBL\fR
modifiers are ignored when converting real values (i.e. type
-\fBdouble\fR is used for the internal representation).
-.VE 8.4
+\fBdouble\fR is used for the internal representation). The \fBll\fR
+modifier has no \fBsscanf\fR counterpart.
.IP [4]
If the end of the input string is reached before any conversions have been
performed and no variables are given, an empty string is returned.
.SH EXAMPLES
+Convert a UNICODE character to its numeric value:
+.CS
+set char "x"
+set value [\fBscan\fR $char %c]
+.CE
+.PP
Parse a simple color specification of the form \fI#RRGGBB\fR using
-hexadecimal conversions with field sizes:
+hexadecimal conversions with substring sizes:
.CS
set string "#08D03F"
\fBscan\fR $string "#%2x%2x%2x" r g b
@@ -245,7 +237,7 @@ looking for the terminating character explicitly:
set string "(5.2,-4e-2)"
# Note that the spaces before the literal parts of
# the scan pattern are significant, and that ")" is
-# the Unicode character \\u0029
+# the Unicode character \eu0029
if {
[\fBscan\fR $string " (%f ,%f %c" x y last] != 3
|| $last != 0x0029
@@ -254,9 +246,22 @@ if {
}
puts "X=$x, Y=$y"
.CE
-
+.PP
+.VS 8.5
+An interactive session demonstrating the truncation of integer
+values determined by size modifiers:
+.CS
+% set tcl_platform(wordSize)
+4
+% scan 20000000000000000000 %d
+2147483647
+% scan 20000000000000000000 %ld
+9223372036854775807
+% scan 20000000000000000000 %lld
+20000000000000000000
+.CE
+.VE 8.5
.SH "SEE ALSO"
format(n), sscanf(3)
-
.SH KEYWORDS
conversion specifier, parse, scan
diff --git a/doc/seek.n b/doc/seek.n
index bbc586f..d4ce9b7 100644
--- a/doc/seek.n
+++ b/doc/seek.n
@@ -19,12 +19,10 @@ seek \- Change the access position for an open channel
.PP
Changes the current access position for \fIchannelId\fR.
.PP
-.VS
\fIChannelId\fR must be an identifier for an open channel such as a
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.
-.VE
.PP
The \fIoffset\fR and \fIorigin\fR
arguments specify the position at which the next read or write will occur
@@ -55,11 +53,9 @@ 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.
.PP
-.VS 8.1
Note that \fIoffset\fR values are byte offsets, not character
offsets. Both \fBseek\fR and \fBtell\fR operate in terms of bytes,
not characters, unlike \fBread\fR.
-.VE 8.1
.SH EXAMPLES
Read a file twice:
.CS
diff --git a/doc/set.n b/doc/set.n
index 3233475..fb8dfac 100644
--- a/doc/set.n
+++ b/doc/set.n
@@ -14,13 +14,12 @@ set \- Read and write variables
.SH SYNOPSIS
\fBset \fIvarName \fR?\fIvalue\fR?
.BE
-
.SH DESCRIPTION
.PP
Returns the value of variable \fIvarName\fR.
If \fIvalue\fR is specified, then set
the value of \fIvarName\fR to \fIvalue\fR, creating a new variable
-if one doesn't already exist, and return its value.
+if one does not already exist, and return its value.
If \fIvarName\fR contains an open parenthesis and ends with a
close parenthesis, then it refers to an array element: the characters
before the first open parenthesis are the name of the array,
@@ -42,7 +41,7 @@ unless \fIvarName\fR was declared to resolve differently through one of the
.SH EXAMPLES
Store a random number in the variable \fIr\fR:
.CS
-\fBset\fR r [expr rand()]
+\fBset\fR r [expr {rand()}]
.CE
.PP
Store a short message in an array element:
@@ -65,9 +64,7 @@ practice instead of doing double-dereferencing):
\fBset\fR vbl in[expr {rand() >= 0.5}]
\fBset\fR out [\fBset\fR $vbl]
.CE
-
.SH "SEE ALSO"
expr(n), global(n), namespace(n), proc(n), trace(n), unset(n), upvar(n), variable(n)
-
.SH KEYWORDS
read, write, variable
diff --git a/doc/socket.n b/doc/socket.n
index a4dda4a..c020839 100644
--- a/doc/socket.n
+++ b/doc/socket.n
@@ -75,7 +75,16 @@ connection attempt succeeds or fails, if the socket is in blocking mode, the
operation will wait until the connection is completed or fails. If the
socket is in nonblocking mode and a \fBgets\fR or \fBflush\fR is done on
the socket before the connection attempt succeeds or fails, the operation
-returns immediately and \fBfblocked\fR on the socket returns 1.
+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
+.CS
+\fBfconfigure \fIchan \fB\-blocking 0\fR
+.CE
+.PP
+See the \fBfconfigure\fR command for more details.
+.RE
.SH "SERVER SOCKETS"
.PP
If the \fB\-server\fR option is specified then the new socket
@@ -91,7 +100,7 @@ with three additional arguments: the name of the new channel, the
address, in network address notation, of the client's host, and
the client's port number.
.PP
-The following additional option may also be specified before \fIhost\fR:
+The following additional option may also be specified before \fIport\fR:
.TP
\fB\-myaddr\fI addr\fR
\fIAddr\fR gives the domain-style name or numerical IP address of
@@ -108,7 +117,7 @@ channel shuts down the server so that no new connections will be
accepted; however, existing connections will be unaffected.
.PP
Server sockets depend on the Tcl event mechanism to find out when
-new connections are opened. If the application doesn't enter the
+new connections are opened. If the application does not enter the
event loop, for example by invoking the \fBvwait\fR command or
calling the C procedure \fBTcl_DoOneEvent\fR, then no connections
will be accepted.
@@ -127,6 +136,9 @@ 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.
+
+Note that the error status is reset by the read operation; this mimics
+the underlying getsockopt(SO_ERROR) call.
.TP
\fB\-sockname\fR
This option returns a list of three elements, the address, the host name
diff --git a/doc/source.n b/doc/source.n
index 18004a8..69d383e 100644
--- a/doc/source.n
+++ b/doc/source.n
@@ -15,11 +15,10 @@ source \- Evaluate a file or resource as a Tcl script
.SH SYNOPSIS
\fBsource \fIfileName\fR
.sp
-\fBsource\fR \fB\-rsrc \fIresourceName \fR?\fIfileName\fR?
-.sp
-\fBsource\fR \fB\-rsrcid \fIresourceId \fR?\fIfileName\fR?
+.VS 8.5
+\fBsource\fR \fB\-encoding \fIencodingName fileName\fR
+.VE 8.5
.BE
-
.SH DESCRIPTION
.PP
This command takes the contents of the specified file or resource
@@ -31,23 +30,26 @@ If a \fBreturn\fR command is invoked from within the script then the
remainder of the file will be skipped and the \fBsource\fR command
will return normally with the result from the \fBreturn\fR command.
.PP
-.VS 8.4
-The end-of-file character for files is '\\32' (^Z) for all platforms.
+The end-of-file character for files is
+.QW \e32
+(^Z) for all platforms.
The source command will read files up to this character. This
restriction does not exist for the \fBread\fR or \fBgets\fR commands,
allowing for files containing code and data segments (scripted documents).
-If you require a ``^Z'' in code for string comparison, you can use
-``\\032'' or ``\\u001a'', which will be safely substituted by the Tcl
-interpreter into ``^Z''.
-.VE 8.4
+If you require a
+.QW ^Z
+in code for string comparison, you can use
+.QW \e032
+or
+.QW \eu001a ,
+which will be safely substituted by the Tcl interpreter into
+.QW ^Z .
.PP
-The \fI\-rsrc\fR and \fI\-rsrcid\fR forms of this command are only
-available on Macintosh computers. These versions of the command
-allow you to source a script from a \fBTEXT\fR resource. You may specify
-what \fBTEXT\fR resource to source by either name or id. By default Tcl
-searches all open resource files, which include the current
-application and any loaded C extensions. Alternatively, you may
-specify the \fIfileName\fR where the \fBTEXT\fR resource can be found.
+.VS 8.5
+The \fB\-encoding\fR option is used to specify the encoding of
+the data stored in \fIfileName\fR. When the \fB\-encoding\fR option
+is omitted, the system encoding is assumed.
+.VE 8.5
.SH EXAMPLE
Run the script in the file \fBfoo.tcl\fR and then the script in the
file \fBbar.tcl\fR:
@@ -61,9 +63,7 @@ foreach scriptFile {foo.tcl bar.tcl} {
\fBsource\fR $scriptFile
}
.CE
-
.SH "SEE ALSO"
-file(n), cd(n), info(n)
-
+file(n), cd(n), encoding(n), info(n)
.SH KEYWORDS
file, script
diff --git a/doc/split.n b/doc/split.n
index 11e4013..c289be0 100644
--- a/doc/split.n
+++ b/doc/split.n
@@ -32,7 +32,7 @@ If \fIsplitChars\fR is an empty string then each character of
Divide up a USENET group name into its hierarchical components:
.CS
\fBsplit\fR "comp.lang.tcl.announce" .
- \fI=> comp lang tcl announce\fR
+ \fI\(-> comp lang tcl announce\fR
.CE
.PP
See how the \fBsplit\fR command splits on \fIevery\fR character in
@@ -40,21 +40,21 @@ See how the \fBsplit\fR command splits on \fIevery\fR character in
careful:
.CS
\fBsplit\fR "alpha beta gamma" "temp"
- \fI=> al {ha b} {} {a ga} {} a\fR
+ \fI\(-> al {ha b} {} {a ga} {} a\fR
.CE
.PP
Extract the list words from a string that is not a well-formed list:
.CS
\fBsplit\fR "Example with {unbalanced brace character"
- \fI=> Example with \\{unbalanced brace character\fR
+ \fI\(-> Example with \e{unbalanced brace character\fR
.CE
.PP
Split a string into its constituent characters
.CS
\fBsplit\fR "Hello world" {}
- \fI=> H e l l o { } w o r l d\fR
+ \fI\(-> H e l l o { } w o r l d\fR
.CE
-.SH "PARSING RECORD-ORIENTED FILES"
+.SS "PARSING RECORD-ORIENTED FILES"
Parse a Unix /etc/passwd file, which consists of one entry per line,
with each line consisting of a colon-separated list of fields:
.CS
@@ -64,7 +64,7 @@ set content [read $fid]
close $fid
## Split into records on newlines
-set records [\fBsplit\fR $content "\\n"]
+set records [\fBsplit\fR $content "\en"]
## Iterate over the records
foreach rec $records {
@@ -73,7 +73,7 @@ foreach rec $records {
set fields [\fBsplit\fR $rec ":"]
## Assign fields to variables and print some out...
- lassign $fields \\
+ lassign $fields \e
userName password uid grp longName homeDir shell
puts "$longName uses [file tail $shell] for a login shell"
}
diff --git a/doc/string.n b/doc/string.n
index ef49f15..dfb5a90 100644
--- a/doc/string.n
+++ b/doc/string.n
@@ -1,14 +1,14 @@
-'\"
-'\" Copyright (c) 1993 The Regents of the University of California.
-'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
-'\"
-'\" See the file "license.terms" for information on usage and redistribution
-'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-'\"
+.\"
+.\" Copyright (c) 1993 The Regents of the University of California.
+.\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+.\"
+.\" 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"
.BS
-'\" Note: do not modify the .SH NAME line immediately below!
+.\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
string \- Manipulate strings
.SH SYNOPSIS
@@ -39,7 +39,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 int\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
identical, or 0 when not. If \fB\-length\fR is specified, then only
@@ -47,13 +47,13 @@ the 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 first \fIstring1 string2\fR ?\fIstartIndex\fR?
-Search \fIstring2\fR for a sequence of characters that exactly match
-the characters in \fIstring1\fR. If found, return the index of the
-first character in the first such match within \fIstring2\fR. If not
+\fBstring first \fIneedleString haystackString\fR ?\fIstartIndex\fR?
+Search \fIhaystackString\fR for a sequence of characters that exactly match
+the characters in \fIneedleString\fR. If found, return the index of the
+first character in the first such match within \fIhaystackString\fR. If not
found, return \-1. If \fIstartIndex\fR is specified (in any of the
forms accepted by the \fBindex\fR method), then the search is
-constrained to start with the character in \fIstring2\fR specified by
+constrained to start with the character in \fIhaystackString\fR specified by
the index. For example,
.RS
.CS
@@ -70,23 +70,61 @@ will return \fB\-1\fR.
Returns the \fIcharIndex\fR'th character of the \fIstring\fR argument.
A \fIcharIndex\fR of 0 corresponds to the first character of the
string. \fIcharIndex\fR may be specified as follows:
+.VS 8.5
.RS
.IP \fIinteger\fR 10
-The char specified at this integral index.
+For any index value that passes \fBstring is integer -strict\fR,
+the char specified at this integral index
+(e.g. \fB2\fR would refer to the
+.QW c
+in
+.QW abcd ).
.IP \fBend\fR 10
-The last char of the string.
-.IP \fBend\-\fIinteger\fR 10
-The last char of the string minus the specified integer offset
-(e.g. \fBend\-1\fR would refer to the "c" in "abcd").
+The last char of the string
+(e.g. \fBend\fR would refer to the
+.QW d
+in
+.QW abcd ).
+.IP \fBend\fR\-\fIN\fR 10
+The last char of the string minus the specified integer offset \fIN\fR
+(e.g. \fBend\fR\-1 would refer to the
+.QW c
+in
+.QW abcd ).
+.IP \fBend\fR+\fIN\fR 10
+The last char of the string plus the specified integer offset \fIN\fR
+(e.g. \fBend\fR+\-1 would refer to the
+.QW c
+in
+.QW abcd ).
+.IP \fIM\fR+\fIN\fR 10
+The char specified at the integral index that is the sum of
+integer values \fIM\fR and \fIN\fR
+(e.g. \fB1+1\fR would refer to the
+.QW c
+in
+.QW abcd ).
+.IP \fIM\fR\-\fIN\fR 10
+The char specified at the integral index that is the difference of
+integer values \fIM\fR and \fIN\fR
+(e.g. \fB2\-1\fR would refer to the
+.QW b
+in
+.QW abcd ).
+.PP
+In the specifications above, the integer value \fIM\fR contains no
+trailing whitespace and the integer value \fIN\fR contains no
+leading whitespace.
.PP
If \fIcharIndex\fR is less than 0 or greater than or equal to the
-length of the string then an empty string is returned.
+length of the string then this command returns an empty string.
.RE
+.VE
.TP
\fBstring is \fIclass\fR ?\fB\-strict\fR? ?\fB\-failindex \fIvarname\fR? \fIstring\fR
Returns 1 if \fIstring\fR is a valid member of the specified character
class, otherwise returns 0. If \fB\-strict\fR is specified, then an
-empty string returns 0, otherwise and empty string will return 1 on
+empty string returns 0, otherwise an empty string will return 1 on
any class. If \fB\-failindex\fR is specified, then if the function
returns 0, the index in the string where the class was no longer valid
will be stored in the variable named \fIvarname\fR. The \fIvarname\fR
@@ -98,7 +136,7 @@ Any Unicode alphabet or digit character.
.IP \fBalpha\fR 12
Any Unicode alphabet character.
.IP \fBascii\fR 12
-Any character with a value less than \\u0080 (those that are in the
+Any character with a value less than \eu0080 (those that are in the
7\-bit ascii range).
.IP \fBboolean\fR 12
Any of the forms allowed to \fBTcl_GetBoolean\fR.
@@ -117,9 +155,15 @@ false.
.IP \fBgraph\fR 12
Any Unicode printing character, except space.
.IP \fBinteger\fR 12
-Any of the valid forms for an ordinary integer in Tcl, with optional
-surrounding whitespace. In case of under/overflow in the value, 0 is
-returned and the \fIvarname\fR will contain \-1.
+Any of the valid string formats for a 32-bit integer value 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 \fBlist\fR 12
+Any proper list structure, with optional surrounding whitespace. In
+case of improper list structure, 0 is returned and the \fIvarname\fR
+will contain the index of the
+.QW element
+where the list parsing fails, or \-1 if this cannot be determined.
.IP \fBlower\fR 12
Any Unicode lower case alphabet character.
.IP \fBprint\fR 12
@@ -133,6 +177,12 @@ Any of the forms allowed to \fBTcl_GetBoolean\fR where the value is
true.
.IP \fBupper\fR 12
Any upper case alphabet character in the Unicode character set.
+.VS 8.5
+.IP \fBwideinteger\fR 12
+Any of the valid forms for a wide integer in Tcl, with optional
+surrounding whitespace. In case of under/overflow in the value, 0 is
+returned and the \fIvarname\fR will contain \-1.
+.VE 8.5
.IP \fBwordchar\fR 12
Any Unicode word character. That is any alphanumeric character, and
any Unicode connector punctuation characters (e.g. underscore).
@@ -144,13 +194,13 @@ function will return 0, then the \fIvarname\fR will always be set to
0, due to the varied nature of a valid boolean value.
.RE
.TP
-\fBstring last \fIstring1 string2\fR ?\fIlastIndex\fR?
-Search \fIstring2\fR for a sequence of characters that exactly match
-the characters in \fIstring1\fR. If found, return the index of the
-first character in the last such match within \fIstring2\fR. If there
+\fBstring last \fIneedleString haystackString\fR ?\fIlastIndex\fR?
+Search \fIhaystackString\fR for a sequence of characters that exactly match
+the characters in \fIneedleString\fR. If found, return the index of the
+first character in the last such match within \fIhaystackString\fR. If there
is no match, then return \-1. If \fIlastIndex\fR is specified (in any
of the forms accepted by the \fBindex\fR method), then only the
-characters in \fIstring2\fR at or before the specified \fIlastIndex\fR
+characters in \fIhaystackString\fR at or before the specified \fIlastIndex\fR
will be considered by the search. For example,
.RS
.CS
@@ -198,7 +248,7 @@ it will return the string \fB02c322c222c\fR.
.TP
\fBstring match\fR ?\fB\-nocase\fR? \fIpattern\fR \fIstring\fR
See if \fIpattern\fR matches \fIstring\fR; return 1 if it does, 0 if
-it doesn't. If \fB\-nocase\fR is specified, then the pattern attempts
+it does not. If \fB\-nocase\fR is specified, then the pattern attempts
to match against the string in a case insensitive manner. For the two
strings to match, their contents must be identical except that the
following special sequences may appear in \fIpattern\fR:
@@ -213,10 +263,16 @@ Matches any character in the set given by \fIchars\fR. If a sequence
of the form \fIx\fB\-\fIy\fR appears in \fIchars\fR, then any
character between \fIx\fR and \fIy\fR, inclusive, will match. When
used with \fB\-nocase\fR, the end points of the range are converted to
-lower case first. Whereas {[A\-z]} matches '_' when matching
-case-sensitively ('_' falls between the 'Z' and 'a'), with
-\fB\-nocase\fR this is considered like {[A\-Za\-z]} (and probably what
-was meant in the first place).
+lower case first. Whereas {[A\-z]} matches
+.QW _
+when matching case-sensitively (since
+.QW _
+falls between the
+.QW Z
+and
+.QW a ),
+with \fB\-nocase\fR this is considered like {[A\-Za\-z]} (and
+probably what was meant in the first place).
.IP \fB\e\fIx\fR 10
Matches the single character \fIx\fR. This provides a way of avoiding
the special interpretation of the characters \fB*?[]\e\fR in
@@ -249,6 +305,12 @@ and if \fIlast\fR is greater than or equal to the length of the string
then it is treated as if it were \fBend\fR. If \fIfirst\fR is greater
than \fIlast\fR or the length of the initial string, or \fIlast\fR is
less than 0, then the initial string is returned untouched.
+.VS 8.5
+.TP
+\fBstring reverse \fIstring\fR
+Returns a string that is the same length as \fIstring\fR but with its
+characters in the reverse order.
+.VE 8.5
.TP
\fBstring tolower \fIstring\fR ?\fIfirst\fR? ?\fIlast\fR?
Returns a value equal to \fIstring\fR except that all upper (or title)
@@ -278,19 +340,19 @@ specified as for the \fBindex\fR method.
.TP
\fBstring trim \fIstring\fR ?\fIchars\fR?
Returns a value equal to \fIstring\fR except that any leading or
-trailing characters from the set given by \fIchars\fR are removed. If
+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).
.TP
\fBstring trimleft \fIstring\fR ?\fIchars\fR?
Returns a value equal to \fIstring\fR except that any leading
-characters from the set given by \fIchars\fR are removed. If
+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).
.TP
\fBstring trimright \fIstring\fR ?\fIchars\fR?
Returns a value equal to \fIstring\fR except that any trailing
-characters from the set given by \fIchars\fR are removed. If
+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).
.TP
@@ -325,4 +387,9 @@ if {$length == 0} {
expr(n), list(n)
.SH KEYWORDS
-case conversion, compare, index, match, pattern, string, word, equal, ctype
+case conversion, compare, index, match, pattern, string, word, equal,
+ctype, character, reverse
+
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/doc/subst.n b/doc/subst.n
index b161de6..5a162c4 100644
--- a/doc/subst.n
+++ b/doc/subst.n
@@ -15,7 +15,6 @@ subst \- Perform backslash, command, and variable substitutions
.SH SYNOPSIS
\fBsubst \fR?\fB\-nobackslashes\fR? ?\fB\-nocommands\fR? ?\fB\-novariables\fR? \fIstring\fR
.BE
-
.SH DESCRIPTION
.PP
This command performs variable substitutions, command substitutions,
@@ -34,15 +33,14 @@ For example, if \fB\-nocommands\fR is specified, command substitution
is not performed: open and close brackets are treated as ordinary characters
with no special interpretation.
.PP
-.VS 8.4
Note that the substitution of one kind can include substitution of
-other kinds. For example, even when the \fB-novariables\fR option
+other kinds. For example, even when the \fB\-novariables\fR option
is specified, command substitution is performed without restriction.
This means that any variable substitution necessary to complete the
command substitution will still take place. Likewise, any command
substitution necessary to complete a variable substitution will
-take place, even when \fB-nocommands\fR is specified. See the
-EXAMPLES below.
+take place, even when \fB\-nocommands\fR is specified. See the
+\fBEXAMPLES\fR below.
.PP
If an error occurs during substitution, then \fBsubst\fR will return
that error. If a break exception occurs during command or variable
@@ -54,10 +52,11 @@ will be substituted for that entire command or variable substitution
(as long as it is well-formed Tcl.) If a return exception occurs,
or any other return code is returned during command or variable
substitution, then the returned value is substituted for that
-substitution. See the EXAMPLES below. In this way, all exceptional
-return codes are ``caught'' by \fBsubst\fR. The \fBsubst\fR command
+substitution. See the \fBEXAMPLES\fR below. In this way, all exceptional
+return codes are
+.QW caught
+by \fBsubst\fR. The \fBsubst\fR command
itself will either return an error, or will complete successfully.
-.VE
.SH EXAMPLES
.PP
When it performs its substitutions, \fIsubst\fR does not give any
@@ -67,22 +66,31 @@ command substitutions) so the script
set a 44
\fBsubst\fR {xyz {$a}}
.CE
-returns ``\fBxyz {44}\fR'', not ``\fBxyz {$a}\fR''
-.VS 8.4
+returns
+.QW "\fBxyz {44}\fR" ,
+not
+.QW "\fBxyz {$a}\fR"
and the script
.CS
-set a "p\\} q \\{r"
+set a "p\e} q \e{r"
\fBsubst\fR {xyz {$a}}
.CE
-return ``\fBxyz {p} q {r}\fR'', not ``\fBxyz {p\\} q \\{r}\fR''.
+returns
+.QW "\fBxyz {p} q {r}\fR" ,
+not
+.QW "\fBxyz {p\e} q \e{r}\fR".
.PP
When command substitution is performed, it includes any variable
-substitution necessary to evaluate the script.
+substitution necessary to evaluate the script.
.CS
set a 44
\fBsubst\fR -novariables {$a [format $a]}
.CE
-returns ``\fB$a 44\fR'', not ``\fB$a $a\fR''. Similarly, when
+returns
+.QW "\fB$a 44\fR" ,
+not
+.QW "\fB$a $a\fR" .
+Similarly, when
variable substitution is performed, it includes any command
substitution necessary to retrieve the value of the variable.
.CS
@@ -90,7 +98,10 @@ proc b {} {return c}
array set a {c c [b] tricky}
\fBsubst\fR -nocommands {[b] $a([b])}
.CE
-returns ``\fB[b] c\fR'', not ``\fB[b] tricky\fR''.
+returns
+.QW "\fB[b] c\fR" ,
+not
+.QW "\fB[b] tricky\fR" .
.PP
The continue and break exceptions allow command substitutions to
prevent substitution of the rest of the command substitution and the
@@ -99,25 +110,36 @@ when processing text using \fIsubst\fR. For example, the script
.CS
\fBsubst\fR {abc,[break],def}
.CE
-returns ``\fBabc,\fR'', not ``\fBabc,,def\fR'' and the script
+returns
+.QW \fBabc,\fR ,
+not
+.QW \fBabc,,def\fR
+and the script
.CS
-\fBsubst\fR {abc,[continue;expr 1+2],def}
+\fBsubst\fR {abc,[continue;expr {1+2}],def}
.CE
-returns ``\fBabc,,def\fR'', not ``\fBabc,3,def\fR''.
+returns
+.QW \fBabc,,def\fR ,
+not
+.QW \fBabc,3,def\fR .
.PP
Other exceptional return codes substitute the returned value
.CS
-\fBsubst\fR {abc,[return foo;expr 1+2],def}
+\fBsubst\fR {abc,[return foo;expr {1+2}],def}
.CE
-returns ``\fBabc,foo,def\fR'', not ``\fBabc,3,def\fR'' and
+returns
+.QW \fBabc,foo,def\fR ,
+not
+.QW \fBabc,3,def\fR
+and
.CS
-\fBsubst\fR {abc,[return -code 10 foo;expr 1+2],def}
+\fBsubst\fR {abc,[return -code 10 foo;expr {1+2}],def}
.CE
-also returns ``\fBabc,foo,def\fR'', not ``\fBabc,3,def\fR''.
-.VE
-
+also returns
+.QW \fBabc,foo,def\fR ,
+not
+.QW \fBabc,3,def\fR .
.SH "SEE ALSO"
Tcl(n), eval(n), break(n), continue(n)
-
.SH KEYWORDS
backslash substitution, command substitution, variable substitution
diff --git a/doc/switch.n b/doc/switch.n
index 32da66c..defa849 100644
--- a/doc/switch.n
+++ b/doc/switch.n
@@ -6,7 +6,7 @@
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.so man.macros
-.TH switch n 7.0 Tcl "Tcl Built-In Commands"
+.TH switch n 8.5 Tcl "Tcl Built-In Commands"
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
@@ -16,7 +16,6 @@ switch \- Evaluate one of several scripts, depending on a given value
.sp
\fBswitch \fR?\fIoptions\fR?\fI string \fR{\fIpattern body \fR?\fIpattern body \fR...?}
.BE
-
.SH DESCRIPTION
.PP
The \fBswitch\fR command matches its \fIstring\fR argument against each of
@@ -31,8 +30,13 @@ matches \fIstring\fR and no default is given, then the \fBswitch\fR
command returns an empty string.
.PP
If the initial arguments to \fBswitch\fR start with \fB\-\fR then
-they are treated as options. The following options are
-currently supported:
+they are treated as options
+.VS 8.5
+unless there are exactly two arguments to \fBswitch\fR (in which case the
+first must the \fIstring\fR and the second must be the
+\fIpattern\fR/\fIbody\fR list).
+.VE 8.5
+The following options are currently supported:
.TP 10
\fB\-exact\fR
Use exact matching when comparing \fIstring\fR to a pattern. This
@@ -46,10 +50,48 @@ When matching \fIstring\fR to the patterns, use glob-style matching
When matching \fIstring\fR to the patterns, use regular
expression matching
(as described in the \fBre_syntax\fR reference page).
+'\" Options defined by TIP#75
+.VS 8.5
+.TP 10
+\fB\-nocase\fR
+Causes comparisons to be handled in a case-insensitive manner.
+.TP 10
+\fB\-matchvar\fR \fIvarName\fR
+This option (only legal when \fB\-regexp\fR is also specified)
+specifies the name of a variable into which the list of matches
+found by the regular expression engine will be written. The first
+element of the list written will be the overall substring of the input
+string (i.e. the \fIstring\fR argument to \fBswitch\fR) matched, the
+second element of the list will be the substring matched by the first
+capturing parenthesis in the regular expression that matched, and so
+on. When a \fBdefault\fR branch is taken, the variable will have the
+empty list written to it. This option may be specified at the same
+time as the \fB\-indexvar\fR option.
+.TP 10
+\fB\-indexvar\fR \fIvarName\fR
+This option (only legal when \fB\-regexp\fR is also specified)
+specifies the name of a variable into which the list of indices
+referring to matching substrings
+found by the regular expression engine will be written. The first
+element of the list written will be a two-element list specifying the
+index of the start and index of the first character after the end of
+the overall substring of the input
+string (i.e. the \fIstring\fR argument to \fBswitch\fR) matched, in a
+similar way to the \fB\-indices\fR option to the \fBregexp\fR can
+obtain. Similarly, the second element of the list refers to the first
+capturing parenthesis in the regular expression that matched, and so
+on. When a \fBdefault\fR branch is taken, the variable will have the
+empty list written to it. This option may be specified at the same
+time as the \fB\-matchvar\fR option.
+.VE 8.5
.TP 10
\fB\-\|\-\fR
Marks the end of options. The argument following this one will
be treated as \fIstring\fR even if it starts with a \fB\-\fR.
+.VS 8.5
+This is not required when the matching patterns and bodies are grouped
+together in a single argument.
+.VE 8.5
.PP
Two syntaxes are provided for the \fIpattern\fR and \fIbody\fR arguments.
The first uses a separate argument for each of the patterns and commands;
@@ -66,9 +108,12 @@ no command or variable substitutions are performed on them; this makes
the behavior of the second form different than the first form in some
cases.
.PP
-If a \fIbody\fR is specified as ``\fB\-\fR'' it means that the \fIbody\fR
+If a \fIbody\fR is specified as
+.QW \fB\-\fR
+it means that the \fIbody\fR
for the next pattern should also be used as the body for this
-pattern (if the next pattern also has a body of ``\fB\-\fR''
+pattern (if the next pattern also has a body of
+.QW \fB\-\fR
then the body after that is used, and so on).
This feature makes it possible to share a single \fIbody\fR among
several patterns.
@@ -81,7 +126,7 @@ The \fBswitch\fR command can match against variables and not just
literals, as shown here (the result is \fI2\fR):
.CS
set foo "abc"
-\fBswitch\fR abc a \- b {expr 1} $foo {expr 2} default {expr 3}
+\fBswitch\fR abc a \- b {expr {1}} $foo {expr {2}} default {expr {3}}
.CE
.PP
Using glob matching and the fall-through body is an alternative to
@@ -90,9 +135,9 @@ writing regular expressions with alternations, as can be seen here
.CS
\fBswitch\fR \-glob aaab {
a*b \-
- b {expr 1}
- a* {expr 2}
- default {expr 3}
+ b {expr {1}}
+ a* {expr {2}}
+ default {expr {3}}
}
.CE
.PP
@@ -100,22 +145,39 @@ Whenever nothing matches, the \fBdefault\fR clause (which must be
last) is taken. This example has a result of \fI3\fR:
.CS
\fBswitch\fR xyz {
- a \-
+ a \-
b {
# Correct Comment Placement
- expr 1
+ expr {1}
}
c {
- expr 2
+ expr {2}
}
default {
- expr 3
+ expr {3}
+ }
+}
+.CE
+.PP
+.VS 8.5
+When matching against regular expressions, information about what
+exactly matched is easily obtained using the \fB\-matchvar\fR option:
+.CS
+\fBswitch\fR \-regexp \-matchvar foo \-\- $bar {
+ a(b*)c {
+ puts "Found [string length [lindex $foo 1]] 'b's"
+ }
+ d(e*)f(g*)h {
+ puts "Found [string length [lindex $foo 1]] 'e's and\e
+ [string length [lindex $foo 2]] 'g's"
}
}
.CE
-
+.VE 8.5
.SH "SEE ALSO"
for(n), if(n), regexp(n)
-
.SH KEYWORDS
switch, match, regular expression
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/doc/tclsh.1 b/doc/tclsh.1
index 53782a6..d9fe95e 100644
--- a/doc/tclsh.1
+++ b/doc/tclsh.1
@@ -12,7 +12,7 @@
.SH NAME
tclsh \- Simple shell containing Tcl interpreter
.SH SYNOPSIS
-\fBtclsh\fR ?\fIfileName arg arg ...\fR?
+\fBtclsh\fR ?-encoding \fIname\fR? ?\fIfileName arg arg ...\fR?
.BE
.SH DESCRIPTION
@@ -26,26 +26,33 @@ It runs until the \fBexit\fR command is invoked or until it
reaches end-of-file on its standard input.
If there exists a file \fB.tclshrc\fR (or \fBtclshrc.tcl\fR on
the Windows platforms) in the home directory of
-the user, \fBtclsh\fR evaluates the file as a Tcl script
+the user, interactive \fBtclsh\fR evaluates the file as a Tcl script
just before reading the first command from standard input.
.SH "SCRIPT FILES"
.PP
-If \fBtclsh\fR is invoked with arguments then the first argument
-is the name of a script file and any additional arguments
+.VS 8.5
+If \fBtclsh\fR is invoked with arguments then the first few arguments
+specify the name of a script file, and, optionally, the encoding of
+the text data stored in that script file.
+.VE 8.5
+Any additional arguments
are made available to the script as variables (see below).
Instead of reading commands from standard input \fBtclsh\fR will
read Tcl commands from the named file; \fBtclsh\fR will exit
when it reaches the end of the file.
-.VS 8.4
The end of the file may be marked either by the physical end of
-the medium, or by the character, '\\032' ('\\u001a', control-Z).
+the medium, or by the character,
+.QW \e032
+.PQ \eu001a ", control-Z" .
If this character is present in the file, the \fBtclsh\fR application
will read text up to but not including the character. An application
that requires this character in the file may safely encode it as
-``\\032'', ``\\x1a'', or ``\\u001a''; or may generate it by use of commands
-such as \fBformat\fR or \fBbinary\fR.
-.VE
+.QW \e032 ,
+.QW \ex1a ,
+or
+.QW \eu001a ;
+or may generate it by use of commands such as \fBformat\fR or \fBbinary\fR.
There is no automatic evaluation of \fB.tclshrc\fR when the name
of a script file is presented on the \fBtclsh\fR command
line, but the script file can always \fBsource\fR it if desired.
@@ -57,8 +64,8 @@ If you create a Tcl script in a file whose first line is
then you can invoke the script file directly from your shell if
you mark the file as executable.
This assumes that \fBtclsh\fR has been installed in the default
-location in /usr/local/bin; if it's installed somewhere else
-then you'll have to modify the above line to match.
+location in /usr/local/bin; if it is installed somewhere else
+then you will have to modify the above line to match.
Many UNIX systems do not allow the \fB#!\fR line to exceed about
30 characters in length, so be sure that the \fBtclsh\fR
executable can be accessed with a short file name.
@@ -71,7 +78,7 @@ following three lines:
exec tclsh "$0" ${1+"$@"}\fR
.CE
This approach has three advantages over the approach in the previous
-paragraph. First, the location of the \fBtclsh\fR binary doesn't have
+paragraph. First, the location of the \fBtclsh\fR binary does not have
to be hard-wired into the script: it can be anywhere in your shell
search path. Second, it gets around the 30-character file name limit
in the previous approach.
@@ -89,13 +96,11 @@ When \fBtclsh\fR starts up, it treats all three lines as comments,
since the backslash at the end of the second line causes the third
line to be treated as part of the comment on the second line.
.PP
-.VS
-You should note that it is also common practise to install tclsh with
+You should note that it is also common practice to install tclsh with
its version number as part of the name. This has the advantage of
allowing multiple versions of Tcl to exist on the same system at once,
but also the disadvantage of making it harder to write scripts that
start up uniformly across different versions of Tcl.
-.VE
.SH "VARIABLES"
.PP
@@ -121,14 +126,16 @@ device), 0 otherwise.
.SH PROMPTS
.PP
When \fBtclsh\fR is invoked interactively it normally prompts for each
-command with ``\fB% \fR''. You can change the prompt by setting the
+command with
+.QW "\fB% \fR" .
+You can change the prompt by setting the
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
will evaluate the script in \fBtcl_prompt1\fR.
The variable \fBtcl_prompt2\fR is used in a similar way when
-a newline is typed but the current command isn't yet complete;
-if \fBtcl_prompt2\fR isn't set then no prompt is output for
+a newline is typed but the current command is not yet complete;
+if \fBtcl_prompt2\fR is not set then no prompt is output for
incomplete commands.
.SH "STANDARD CHANNELS"
@@ -136,7 +143,7 @@ incomplete commands.
See \fBTcl_StandardChannels\fR for more explanations.
.SH "SEE ALSO"
-fconfigure(n), tclvars(n)
+encoding(n), fconfigure(n), tclvars(n)
.SH KEYWORDS
argument, interpreter, prompt, script file, shell
diff --git a/doc/tcltest.n b/doc/tcltest.n
index 497afe7..9ac8f66 100644
--- a/doc/tcltest.n
+++ b/doc/tcltest.n
@@ -9,14 +9,14 @@
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.so man.macros
-.TH "tcltest" n 2.2 tcltest "Tcl Bundled Packages"
+.TH "tcltest" n 2.3 tcltest "Tcl Bundled Packages"
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
tcltest \- Test harness support code and utilities
.SH SYNOPSIS
.nf
-\fBpackage require tcltest ?2.2.5?\fR
+\fBpackage require tcltest ?2.3?\fR
.sp
\fBtcltest::test \fIname description ?option value ...?\fR
\fBtcltest::test \fIname description ?constraints? body result\fR
@@ -77,12 +77,12 @@ in and exported from the \fB::tcltest\fR namespace, as indicated in
the \fBSYNOPSIS\fR above. In the following sections, all commands
will be described by their simple names, in the interest of brevity.
.PP
-The central command of \fBtcltest\fR is [\fBtest\fR] that defines
-and runs a test. Testing with [\fBtest\fR] involves evaluation
+The central command of \fBtcltest\fR is \fBtest\fR that defines
+and runs a test. Testing with \fBtest\fR involves evaluation
of a Tcl script and comparing the result to an expected result, as
configured and controlled by a number of options. Several other
commands provided by \fBtcltest\fR govern the configuration of
-[\fBtest\fR] and the collection of many [\fBtest\fR] commands into
+\fBtest\fR and the collection of many \fBtest\fR commands into
test suites.
.PP
See \fBCREATING TEST SUITES WITH TCLTEST\fR below for an extended example
@@ -93,29 +93,30 @@ for your Tcl-enabled code.
\fBtest\fR \fIname description ?option value ...?\fR
Defines and possibly runs a test with the name \fIname\fR and
description \fIdescription\fR. The name and description of a test
-are used in messages reported by [\fBtest\fR] during the
+are used in messages reported by \fBtest\fR during the
test, as configured by the options of \fBtcltest\fR. The
-remaining \fIoption value\fR arguments to [\fBtest\fR]
+remaining \fIoption value\fR arguments to \fBtest\fR
define the test, including the scripts to run, the conditions
under which to run them, the expected result, and the means
by which the expected and actual results should be compared.
See \fBTESTS\fR below for a complete description of the valid
-options and how they define a test. The [\fBtest\fR] command
-returns an empty string.
+options and how they define a test. The \fBtest\fR command
+returns an empty string.
.TP
\fBtest\fR \fIname description ?constraints? body result\fR
-This form of [\fBtest\fR] is provided to support test suites written
+This form of \fBtest\fR is provided to support test suites written
for version 1 of the \fBtcltest\fR package, and also a simpler
interface for a common usage. It is the same as
-[\fBtest\fR \fIname description\fB -constraints \fIconstraints\fB -body
-\fIbody\fB -result \fIresult\fR]. All other options to [\fBtest\fR]
+.QW "\fBtest\fR \fIname description\fB \-constraints \fIconstraints\fB \-body \fIbody\fB \-result \fIresult\fR" .
+All other options to \fBtest\fR
take their default values. When \fIconstraints\fR is omitted, this
-form of [\fBtest\fR] can be distinguished from the first because
-all \fIoption\fRs begin with ``-''.
+form of \fBtest\fR can be distinguished from the first because
+all \fIoption\fRs begin with
+.QW \- .
.TP
\fBloadTestedCommands\fR
Evaluates in the caller's context the script specified by
-[\fBconfigure -load\fR] or [\fBconfigure -loadfile\fR].
+\fBconfigure \-load\fR or \fBconfigure \-loadfile\fR.
Returns the result of that script evaluation, including any error
raised by the script. Use this command and the related
configuration options to provide the commands to be tested to
@@ -124,31 +125,31 @@ the interpreter running the test suite.
\fBmakeFile\fR \fIcontents name ?directory?\fR
Creates a file named \fIname\fR relative to
directory \fIdirectory\fR and write \fIcontents\fR
-to that file using the encoding [\fBencoding system\fR].
+to that file using the encoding \fBencoding system\fR.
If \fIcontents\fR does not end with a newline, a newline
will be appended so that the file named \fIname\fR
does end with a newline. Because the system encoding is used,
this command is only suitable for making text files.
The file will be removed by the next evaluation
-of [\fBcleanupTests\fR], unless it is removed by
-[\fBremoveFile\fR] first. The default value of
-\fIdirectory\fR is the directory [\fBconfigure -tmpdir\fR].
+of \fBcleanupTests\fR, unless it is removed by
+\fBremoveFile\fR first. The default value of
+\fIdirectory\fR is the directory \fBconfigure \-tmpdir\fR.
Returns the full path of the file created. Use this command
to create any text file required by a test with contents as needed.
.TP
\fBremoveFile\fR \fIname ?directory?\fR
Forces the file referenced by \fIname\fR to be removed. This file name
should be relative to \fIdirectory\fR. The default value of
-\fIdirectory\fR is the directory [\fBconfigure -tmpdir\fR].
+\fIdirectory\fR is the directory \fBconfigure \-tmpdir\fR.
Returns an empty string. Use this command to delete files
-created by [\fBmakeFile\fR].
+created by \fBmakeFile\fR.
.TP
\fBmakeDirectory\fR \fIname ?directory?\fR
Creates a directory named \fIname\fR relative to directory \fIdirectory\fR.
-The directory will be removed by the next evaluation of [\fBcleanupTests\fR],
-unless it is removed by [\fBremoveDirectory\fR] first.
+The directory will be removed by the next evaluation of \fBcleanupTests\fR,
+unless it is removed by \fBremoveDirectory\fR first.
The default value of \fIdirectory\fR is the directory
-[\fBconfigure -tmpdir\fR].
+\fBconfigure \-tmpdir\fR.
Returns the full path of the directory created. Use this command
to create any directories that are required to exist by a test.
.TP
@@ -156,16 +157,16 @@ to create any directories that are required to exist by a test.
Forces the directory referenced by \fIname\fR to be removed. This
directory should be relative to \fIdirectory\fR.
The default value of \fIdirectory\fR is the directory
-[\fBconfigure -tmpdir\fR].
+\fBconfigure \-tmpdir\fR.
Returns an empty string. Use this command to delete any directories
-created by [\fBmakeDirectory\fR].
+created by \fBmakeDirectory\fR.
.TP
\fBviewFile\fR \fIfile ?directory?\fR
Returns the contents of \fIfile\fR, except for any
-final newline, just as [\fBread -nonewline\fR] would return.
-This file name should be relative to \fIdirectory\fR.
+final newline, just as \fBread \-nonewline\fR would return.
+This file name should be relative to \fIdirectory\fR.
The default value of \fIdirectory\fR is the directory
-[\fBconfigure -tmpdir\fR]. Use this command
+\fBconfigure \-tmpdir\fR. Use this command
as a convenient way to turn the contents of a file generated
by a test into the result of that test for matching against
an expected result. The contents of the file are read using
@@ -176,25 +177,27 @@ files.
Intended to clean up and summarize after several tests have been
run. Typically called once per test file, at the end of the file
after all tests have been completed. For best effectiveness, be
-sure that the [\fBcleanupTests\fR] is evaluated even if an error
-occurs earlier in the test file evaluation.
-.sp
+sure that the \fBcleanupTests\fR is evaluated even if an error
+occurs earlier in the test file evaluation.
+.RS
+.PP
Prints statistics about the tests run and removes files that were
-created by [\fBmakeDirectory\fR] and [\fBmakeFile\fR] since the
-last [\fBcleanupTests\fR]. Names of files and directories
-in the directory [\fBconfigure -tmpdir\fR] created since
-the last [\fBcleanupTests\fR], but not created by
-[\fBmakeFile\fR] or [\fBmakeDirectory\fR] are printed
-to [\fBoutputChannel\fR]. This command also restores the original
-shell environment, as described by the ::env
+created by \fBmakeDirectory\fR and \fBmakeFile\fR since the
+last \fBcleanupTests\fR. Names of files and directories
+in the directory \fBconfigure \-tmpdir\fR created since
+the last \fBcleanupTests\fR, but not created by
+\fBmakeFile\fR or \fBmakeDirectory\fR are printed
+to \fBoutputChannel\fR. This command also restores the original
+shell environment, as described by the \fB::env\fR
array. Returns an empty string.
+.RE
.TP
\fBrunAllTests\fR
This is a master command meant to run an entire suite of tests,
spanning multiple files and/or directories, as governed by
the configurable options of \fBtcltest\fR. See \fBRUNNING ALL TESTS\fR
below for a complete description of the many variations possible
-with [\fBrunAllTests\fR].
+with \fBrunAllTests\fR.
.SH "CONFIGURATION COMMANDS"
.TP
\fBconfigure\fR
@@ -212,19 +215,21 @@ corresponding value \fIvalue\fR, in order. Raises an error if
an \fIoption\fR is not a supported configurable option, or if
\fIvalue\fR is not a valid value for the corresponding \fIoption\fR,
or if a \fIvalue\fR is not provided. When an error is raised, the
-operation of [\fBconfigure\fR] is halted, and subsequent \fIoption value\fR
+operation of \fBconfigure\fR is halted, and subsequent \fIoption value\fR
arguments are not processed.
-.sp
+.RS
+.PP
If the environment variable \fB::env(TCLTEST_OPTIONS)\fR exists when
-the \fBtcltest\fR package is loaded (by [\fBpackage require tcltest\fR])
-then its value is taken as a list of arguments to pass to [\fBconfigure\fR].
+the \fBtcltest\fR package is loaded (by \fBpackage require tcltest\fR)
+then its value is taken as a list of arguments to pass to \fBconfigure\fR.
This allows the default values of the configuration options to be
set by the environment.
+.RE
.TP
\fBcustomMatch \fImode script\fR
-Registers \fImode\fR as a new legal value of the \fB-match\fR option
-to [\fBtest\fR]. When the \fB-match \fImode\fR option is
-passed to [\fBtest\fR], the script \fIscript\fR will be evaluated
+Registers \fImode\fR as a new legal value of the \fB\-match\fR option
+to \fBtest\fR. When the \fB\-match \fImode\fR option is
+passed to \fBtest\fR, the script \fIscript\fR will be evaluated
to compare the actual result of evaluating the body of the test
to the expected result.
To perform the match, the \fIscript\fR is completed with two additional
@@ -232,82 +237,82 @@ words, the expected result, and the actual result, and the completed script
is evaluated in the global namespace.
The completed script is expected to return a boolean value indicating
whether or not the results match. The built-in matching modes of
-[\fBtest\fR] are \fBexact\fR, \fBglob\fR, and \fBregexp\fR.
+\fBtest\fR are \fBexact\fR, \fBglob\fR, and \fBregexp\fR.
.TP
\fBtestConstraint \fIconstraint ?boolean?\fR
Sets or returns the boolean value associated with the named \fIconstraint\fR.
See \fBTEST CONSTRAINTS\fR below for more information.
.TP
\fBinterpreter\fR \fI?executableName?\fR
-Sets or returns the name of the executable to be [\fBexec\fR]ed by
-[\fBrunAllTests\fR] to run each test file when
-[\fBconfigure -singleproc\fR] is false.
-The default value for [\fBinterpreter\fR] is the name of the
-currently running program as returned by [\fBinfo nameofexecutable\fR].
+Sets or returns the name of the executable to be \fBexec\fRed by
+\fBrunAllTests\fR to run each test file when
+\fBconfigure \-singleproc\fR is false.
+The default value for \fBinterpreter\fR is the name of the
+currently running program as returned by \fBinfo nameofexecutable\fR.
.TP
\fBoutputChannel\fR \fI?channelID?\fR
Sets or returns the output channel ID. This defaults to stdout.
Any test that prints test related output should send
-that output to [\fBoutputChannel\fR] rather than letting
+that output to \fBoutputChannel\fR rather than letting
that output default to stdout.
.TP
\fBerrorChannel\fR \fI?channelID?\fR
Sets or returns the error channel ID. This defaults to stderr.
Any test that prints error messages should send
-that output to [\fBerrorChannel\fR] rather than printing
+that output to \fBerrorChannel\fR rather than printing
directly to stderr.
.SH "SHORTCUT COMMANDS"
.TP
\fBdebug \fI?level?\fR
-Same as [\fBconfigure -debug \fI?level?\fR].
+Same as \fBconfigure \-debug \fI?level?\fR.
.TP
\fBerrorFile \fI?filename?\fR
-Same as [\fBconfigure -errfile \fI?filename?\fR].
+Same as \fBconfigure \-errfile \fI?filename?\fR.
.TP
\fBlimitConstraints \fI?boolean?\fR
-Same as [\fBconfigure -limitconstraints \fI?boolean?\fR].
+Same as \fBconfigure \-limitconstraints \fI?boolean?\fR.
.TP
\fBloadFile \fI?filename?\fR
-Same as [\fBconfigure -loadfile \fI?filename?\fR].
+Same as \fBconfigure \-loadfile \fI?filename?\fR.
.TP
\fBloadScript \fI?script?\fR
-Same as [\fBconfigure -load \fI?script?\fR].
+Same as \fBconfigure \-load \fI?script?\fR.
.TP
\fBmatch \fI?patternList?\fR
-Same as [\fBconfigure -match \fI?patternList?\fR].
+Same as \fBconfigure \-match \fI?patternList?\fR.
.TP
\fBmatchDirectories \fI?patternList?\fR
-Same as [\fBconfigure -relateddir \fI?patternList?\fR].
+Same as \fBconfigure \-relateddir \fI?patternList?\fR.
.TP
\fBmatchFiles \fI?patternList?\fR
-Same as [\fBconfigure -file \fI?patternList?\fR].
+Same as \fBconfigure \-file \fI?patternList?\fR.
.TP
\fBoutputFile \fI?filename?\fR
-Same as [\fBconfigure -outfile \fI?filename?\fR].
+Same as \fBconfigure \-outfile \fI?filename?\fR.
.TP
\fBpreserveCore \fI?level?\fR
-Same as [\fBconfigure -preservecore \fI?level?\fR].
+Same as \fBconfigure \-preservecore \fI?level?\fR.
.TP
\fBsingleProcess \fI?boolean?\fR
-Same as [\fBconfigure -singleproc \fI?boolean?\fR].
+Same as \fBconfigure \-singleproc \fI?boolean?\fR.
.TP
\fBskip \fI?patternList?\fR
-Same as [\fBconfigure -skip \fI?patternList?\fR].
+Same as \fBconfigure \-skip \fI?patternList?\fR.
.TP
\fBskipDirectories \fI?patternList?\fR
-Same as [\fBconfigure -asidefromdir \fI?patternList?\fR].
+Same as \fBconfigure \-asidefromdir \fI?patternList?\fR.
.TP
\fBskipFiles \fI?patternList?\fR
-Same as [\fBconfigure -notfile \fI?patternList?\fR].
+Same as \fBconfigure \-notfile \fI?patternList?\fR.
.TP
\fBtemporaryDirectory \fI?directory?\fR
-Same as [\fBconfigure -tmpdir \fI?directory?\fR].
+Same as \fBconfigure \-tmpdir \fI?directory?\fR.
.TP
\fBtestsDirectory \fI?directory?\fR
-Same as [\fBconfigure -testdir \fI?directory?\fR].
+Same as \fBconfigure \-testdir \fI?directory?\fR.
.TP
\fBverbose \fI?level?\fR
-Same as [\fBconfigure -verbose \fI?level?\fR].
+Same as \fBconfigure \-verbose \fI?level?\fR.
.SH "OTHER COMMANDS"
.PP
The remaining commands provided by \fBtcltest\fR have better
@@ -316,43 +321,49 @@ are retained to support existing test suites, but should be avoided
in new code.
.TP
\fBtest\fR \fIname description optionList\fR
-This form of [\fBtest\fR] was provided to enable passing many
-options spanning several lines to [\fBtest\fR] as a single
+This form of \fBtest\fR was provided to enable passing many
+options spanning several lines to \fBtest\fR as a single
argument quoted by braces, rather than needing to backslash quote
-the newlines between arguments to [\fBtest\fR]. The \fIoptionList\fR
+the newlines between arguments to \fBtest\fR. The \fIoptionList\fR
argument is expected to be a list with an even number of elements
representing \fIoption\fR and \fIvalue\fR arguments to pass
-to [\fBtest\fR]. However, these values are not passed directly, as
-in the alternate forms of [\fBswitch\fR]. Instead, this form makes
+to \fBtest\fR. However, these values are not passed directly, as
+in the alternate forms of \fBswitch\fR. Instead, this form makes
an unfortunate attempt to overthrow Tcl's substitution rules by
performing substitutions on some of the list elements as an attempt to
-implement a ``do what I mean'' interpretation of a brace-enclosed
-``block''. The result is nearly impossible to document clearly, and
+implement a
+.QW "do what I mean"
+interpretation of a brace-enclosed
+.QW block .
+The result is nearly impossible to document clearly, and
for that reason this form is not recommended. See the examples in
\fBCREATING TEST SUITES WITH TCLTEST\fR below to see that this
form is really not necessary to avoid backslash-quoted newlines.
If you insist on using this form, examine
the source code of \fBtcltest\fR if you want to know the substitution
details, or just enclose the third through last argument
-to [\fBtest\fR] in braces and hope for the best.
+to \fBtest\fR in braces and hope for the best.
.TP
\fBworkingDirectory\fR \fI?directoryName?\fR
Sets or returns the current working directory when the test suite is
running. The default value for workingDirectory is the directory in
-which the test suite was launched. The Tcl commands [\fBcd\fR] and
-[\fBpwd\fR] are sufficient replacements.
+which the test suite was launched. The Tcl commands \fBcd\fR and
+\fBpwd\fR are sufficient replacements.
.TP
\fBnormalizeMsg\fR \fImsg\fR
-Returns the result of removing the ``extra'' newlines from \fImsg\fR,
-where ``extra'' is rather imprecise. Tcl offers plenty of string
+Returns the result of removing the
+.QW extra
+newlines from \fImsg\fR, where
+.QW extra
+is rather imprecise. Tcl offers plenty of string
processing commands to modify strings as you wish, and
-[\fBcustomMatch\fR] allows flexible matching of actual and expected
+\fBcustomMatch\fR allows flexible matching of actual and expected
results.
.TP
\fBnormalizePath\fR \fIpathVar\fR
Resolves symlinks in a path, thus creating a path without internal
redirection. It is assumed that \fIpathVar\fR is absolute.
-\fIpathVar\fR is modified in place. The Tcl command [\fBfile normalize\fR]
+\fIpathVar\fR is modified in place. The Tcl command \fBfile normalize\fR
is a sufficient replacement.
.TP
\fBbytestring\fR \fIstring\fR
@@ -362,52 +373,54 @@ value supplied in \fIstring\fR. This allows the tester to create
denormalized or improperly formed strings to pass to C procedures that
are supposed to accept strings with embedded NULL types and confirm
that a string result has a certain pattern of bytes. This is
-exactly equivalent to the Tcl command [\fBencoding convertfrom identity\fR].
+exactly equivalent to the Tcl command \fBencoding convertfrom identity\fR.
.SH TESTS
.PP
-The [\fBtest\fR] command is the heart of the \fBtcltest\fR package.
+The \fBtest\fR command is the heart of the \fBtcltest\fR package.
Its essential function is to evaluate a Tcl script and compare
-the result with an expected result. The options of [\fBtest\fR]
+the result with an expected result. The options of \fBtest\fR
define the test script, the environment in which to evaluate it,
the expected result, and how the compare the actual result to
the expected result. Some configuration options of \fBtcltest\fR
-also influence how [\fBtest\fR] operates.
+also influence how \fBtest\fR operates.
+.PP
+The valid options for \fBtest\fR are summarized:
.PP
-The valid options for [\fBtest\fR] are summarized:
.CS
-.ta 0.8i
\fBtest\fR \fIname\fR \fIdescription\fR
- ?-constraints \fIkeywordList|expression\fR?
- ?-setup \fIsetupScript\fR?
- ?-body \fItestScript\fR?
- ?-cleanup \fIcleanupScript\fR?
- ?-result \fIexpectedAnswer\fR?
- ?-output \fIexpectedOutput\fR?
- ?-errorOutput \fIexpectedError\fR?
- ?-returnCodes \fIcodeList\fR?
- ?-match \fImode\fR?
+ ?-constraints \fIkeywordList|expression\fR?
+ ?-setup \fIsetupScript\fR?
+ ?-body \fItestScript\fR?
+ ?-cleanup \fIcleanupScript\fR?
+ ?-result \fIexpectedAnswer\fR?
+ ?-output \fIexpectedOutput\fR?
+ ?-errorOutput \fIexpectedError\fR?
+ ?-returnCodes \fIcodeList\fR?
+ ?-match \fImode\fR?
.CE
+.PP
The \fIname\fR may be any string. It is conventional to choose
a \fIname\fR according to the pattern:
+.PP
.CS
\fItarget\fR-\fImajorNum\fR.\fIminorNum\fR
.CE
+.PP
For white-box (regression) tests, the target should be the name of the
C function or Tcl procedure being tested. For black-box tests, the
target should be the name of the feature being tested. Some conventions
call for the names of black-box tests to have the suffix \fB_bb\fR.
Related tests should share a major number. As a test suite evolves,
it is best to have the same test name continue to correspond to the
-same test, so that it remains meaningful to say things like ``Test
-foo-1.3 passed in all releases up to 3.4, but began failing in
-release 3.5.''
+same test, so that it remains meaningful to say things like
+.QW "Test foo-1.3 passed in all releases up to 3.4, but began failing in release 3.5."
.PP
-During evaluation of [\fBtest\fR], the \fIname\fR will be compared
+During evaluation of \fBtest\fR, the \fIname\fR will be compared
to the lists of string matching patterns returned by
-[\fBconfigure -match\fR], and [\fBconfigure -skip\fR]. The test
+\fBconfigure \-match\fR, and \fBconfigure \-skip\fR. The test
will be run only if \fIname\fR matches any of the patterns from
-[\fBconfigure -match\fR] and matches none of the patterns
-from [\fBconfigure -skip\fR].
+\fBconfigure \-match\fR and matches none of the patterns
+from \fBconfigure \-skip\fR.
.PP
The \fIdescription\fR should be a short textual description of the
test. The \fIdescription\fR is included in output produced by the
@@ -419,124 +432,125 @@ a bug, include the bug ID in the description.
.PP
Valid attributes and associated values are:
.TP
-\fB-constraints \fIkeywordList|expression\fR
-The optional \fB-constraints\fR attribute can be list of one or more
-keywords or an expression. If the \fB-constraints\fR value is a list of
+\fB\-constraints \fIkeywordList|expression\fR
+The optional \fB\-constraints\fR attribute can be list of one or more
+keywords or an expression. If the \fB\-constraints\fR value is a list of
keywords, each of these keywords should be the name of a constraint
-defined by a call to [\fBtestConstraint\fR]. If any of the listed
+defined by a call to \fBtestConstraint\fR. If any of the listed
constraints is false or does not exist, the test is skipped. If the
-\fB-constraints\fR value is an expression, that expression
+\fB\-constraints\fR value is an expression, that expression
is evaluated. If the expression evaluates to true, then the test is run.
-Note that the expression form of \fB-constraints\fR may interfere with the
-operation of [\fBconfigure -constraints\fR] and
-[\fBconfigure -limitconstraints\fR], and is not recommended.
+Note that the expression form of \fB\-constraints\fR may interfere with the
+operation of \fBconfigure \-constraints\fR and
+\fBconfigure \-limitconstraints\fR, and is not recommended.
Appropriate constraints should be added to any tests that should
not always be run. That is, conditional evaluation of a test
-should be accomplished by the \fB-constraints\fR option, not by
-conditional evaluation of [\fBtest\fR]. In that way, the same
+should be accomplished by the \fB\-constraints\fR option, not by
+conditional evaluation of \fBtest\fR. In that way, the same
number of tests are always reported by the test suite, though
the number skipped may change based on the testing environment.
The default value is an empty list.
See \fBTEST CONSTRAINTS\fR below for a list of built-in constraints
and information on how to add your own constraints.
.TP
-\fB-setup \fIscript\fR
-The optional \fB-setup\fR attribute indicates a \fIscript\fR that will be run
-before the script indicated by the \fB-body\fR attribute. If evaluation
+\fB\-setup \fIscript\fR
+The optional \fB\-setup\fR attribute indicates a \fIscript\fR that will be run
+before the script indicated by the \fB\-body\fR attribute. If evaluation
of \fIscript\fR raises an error, the test will fail. The default value
is an empty script.
.TP
-\fB-body \fIscript\fR
-The \fB-body\fR attribute indicates the \fIscript\fR to run to carry out the
+\fB\-body \fIscript\fR
+The \fB\-body\fR attribute indicates the \fIscript\fR to run to carry out the
test. It must return a result that can be checked for correctness.
If evaluation of \fIscript\fR raises an error, the test will fail.
The default value is an empty script.
.TP
-\fB-cleanup \fIscript\fR
-The optional \fB-cleanup\fR attribute indicates a \fIscript\fR that will be
-run after the script indicated by the \fB-body\fR attribute.
+\fB\-cleanup \fIscript\fR
+The optional \fB\-cleanup\fR attribute indicates a \fIscript\fR that will be
+run after the script indicated by the \fB\-body\fR attribute.
If evaluation of \fIscript\fR raises an error, the test will fail.
The default value is an empty script.
.TP
-\fB-match \fImode\fR
-The \fB-match\fR attribute determines how expected answers supplied by
-\fB-result\fR, \fB-output\fR, and \fB-errorOutput\fR are compared. Valid
+\fB\-match \fImode\fR
+The \fB\-match\fR attribute determines how expected answers supplied by
+\fB\-result\fR, \fB\-output\fR, and \fB\-errorOutput\fR are compared. Valid
values for \fImode\fR are \fBregexp\fR, \fBglob\fR, \fBexact\fR, and
-any value registered by a prior call to [\fBcustomMatch\fR]. The default
+any value registered by a prior call to \fBcustomMatch\fR. The default
value is \fBexact\fR.
.TP
-\fB-result \fIexpectedValue\fR
-The \fB-result\fR attribute supplies the \fIexpectedValue\fR against which
+\fB\-result \fIexpectedValue\fR
+The \fB\-result\fR attribute supplies the \fIexpectedValue\fR against which
the return value from script will be compared. The default value is
an empty string.
.TP
-\fB-output \fIexpectedValue\fR
-The \fB-output\fR attribute supplies the \fIexpectedValue\fR against which
-any output sent to \fBstdout\fR or [\fBoutputChannel\fR] during evaluation
+\fB\-output \fIexpectedValue\fR
+The \fB\-output\fR attribute supplies the \fIexpectedValue\fR against which
+any output sent to \fBstdout\fR or \fBoutputChannel\fR during evaluation
of the script(s) will be compared. Note that only output printed using
-[\fB::puts\fR] is used for comparison. If \fB-output\fR is not specified,
-output sent to \fBstdout\fR and [\fBoutputChannel\fR] is not processed for
+\fB::puts\fR is used for comparison. If \fB\-output\fR is not specified,
+output sent to \fBstdout\fR and \fBoutputChannel\fR is not processed for
comparison.
.TP
-\fB-errorOutput \fIexpectedValue\fR
-The \fB-errorOutput\fR attribute supplies the \fIexpectedValue\fR against
-which any output sent to \fBstderr\fR or [\fBerrorChannel\fR] during
+\fB\-errorOutput \fIexpectedValue\fR
+The \fB\-errorOutput\fR attribute supplies the \fIexpectedValue\fR against
+which any output sent to \fBstderr\fR or \fBerrorChannel\fR during
evaluation of the script(s) will be compared. Note that only output
-printed using [\fB::puts\fR] is used for comparison. If \fB-errorOutput\fR
-is not specified, output sent to \fBstderr\fR and [\fBerrorChannel\fR] is
+printed using \fB::puts\fR is used for comparison. If \fB\-errorOutput\fR
+is not specified, output sent to \fBstderr\fR and \fBerrorChannel\fR is
not processed for comparison.
.TP
-\fB-returnCodes \fIexpectedCodeList\fR
-The optional \fB-returnCodes\fR attribute supplies \fIexpectedCodeList\fR,
+\fB\-returnCodes \fIexpectedCodeList\fR
+The optional \fB\-returnCodes\fR attribute supplies \fIexpectedCodeList\fR,
a list of return codes that may be accepted from evaluation of the
-\fB-body\fR script. If evaluation of the \fB-body\fR script returns
+\fB\-body\fR script. If evaluation of the \fB\-body\fR script returns
a code not in the \fIexpectedCodeList\fR, the test fails. All
-return codes known to [\fBreturn\fR], in both numeric and symbolic
+return codes known to \fBreturn\fR, in both numeric and symbolic
form, including extended return codes, are acceptable elements in
-the \fIexpectedCodeList\fR. Default value is \fB{ok return}\fR.
+the \fIexpectedCodeList\fR. Default value is
+.QW \fBok return\fR.
.PP
-To pass, a test must successfully evaluate its \fB-setup\fR, \fB-body\fR,
-and \fB-cleanup\fR scripts. The return code of the \fB-body\fR script and
+To pass, a test must successfully evaluate its \fB\-setup\fR, \fB\-body\fR,
+and \fB\-cleanup\fR scripts. The return code of the \fB\-body\fR script and
its result must match expected values, and if specified, output and error
-data from the test must match expected \fB-output\fR and \fB-errorOutput\fR
+data from the test must match expected \fB\-output\fR and \fB\-errorOutput\fR
values. If any of these conditions are not met, then the test fails.
Note that all scripts are evaluated in the context of the caller
-of [\fBtest\fR].
+of \fBtest\fR.
.PP
-As long as [\fBtest\fR] is called with valid syntax and legal
+As long as \fBtest\fR is called with valid syntax and legal
values for all attributes, it will not raise an error. Test
-failures are instead reported as output written to [\fBoutputChannel\fR].
+failures are instead reported as output written to \fBoutputChannel\fR.
In default operation, a successful test produces no output. The output
-messages produced by [\fBtest\fR] are controlled by the
-[\fBconfigure -verbose\fR] option as described in \fBCONFIGURABLE OPTIONS\fR
+messages produced by \fBtest\fR are controlled by the
+\fBconfigure \-verbose\fR option as described in \fBCONFIGURABLE OPTIONS\fR
below. Any output produced by the test scripts themselves should be
-produced using [\fB::puts\fR] to [\fBoutputChannel\fR] or
-[\fBerrorChannel\fR], so that users of the test suite may
-easily capture output with the [\fBconfigure -outfile\fR] and
-[\fBconfigure -errfile\fR] options, and so that the \fB-output\fR
-and \fB-errorOutput\fR attributes work properly.
+produced using \fB::puts\fR to \fBoutputChannel\fR or
+\fBerrorChannel\fR, so that users of the test suite may
+easily capture output with the \fBconfigure \-outfile\fR and
+\fBconfigure \-errfile\fR options, and so that the \fB\-output\fR
+and \fB\-errorOutput\fR attributes work properly.
.SH "TEST CONSTRAINTS"
.PP
Constraints are used to determine whether or not a test should be skipped.
Each constraint has a name, which may be any string, and a boolean
-value. Each [\fBtest\fR] has a \fB-constraints\fR value which is a
+value. Each \fBtest\fR has a \fB\-constraints\fR value which is a
list of constraint names. There are two modes of constraint control.
Most frequently, the default mode is used, indicated by a setting
-of [\fBconfigure -limitconstraints\fR] to false. The test will run
+of \fBconfigure \-limitconstraints\fR to false. The test will run
only if all constraints in the list are true-valued. Thus,
-the \fB-constraints\fR option of [\fBtest\fR] is a convenient, symbolic
+the \fB\-constraints\fR option of \fBtest\fR is a convenient, symbolic
way to define any conditions required for the test to be possible or
-meaningful. For example, a [\fBtest\fR] with \fB-constraints unix\fR
+meaningful. For example, a \fBtest\fR with \fB\-constraints unix\fR
will only be run if the constraint \fBunix\fR is true, which indicates
the test suite is being run on a Unix platform.
.PP
-Each [\fBtest\fR] should include whatever \fB-constraints\fR are
+Each \fBtest\fR should include whatever \fB\-constraints\fR are
required to constrain it to run only where appropriate. Several
constraints are pre-defined in the \fBtcltest\fR package, listed
below. The registration of user-defined constraints is performed
-by the [\fBtestConstraint\fR] command. User-defined constraints
+by the \fBtestConstraint\fR command. User-defined constraints
may appear within a test file, or within the script specified
-by the [\fBconfigure -load\fR] or [\fBconfigure -loadfile\fR]
+by the \fBconfigure \-load\fR or \fBconfigure \-loadfile\fR
options.
.PP
The following is a list of constraints pre-defined by the
@@ -581,15 +595,15 @@ test can not be run on a Mac. This flag is used
to temporarily disable a test.
.TP
\fIunixCrash\fR
-test crashes if it's run on Unix. This flag is used to temporarily
+test crashes if it is run on Unix. This flag is used to temporarily
disable a test.
.TP
\fIwinCrash\fR
-test crashes if it's run on Windows. This flag is used to temporarily
+test crashes if it is run on Windows. This flag is used to temporarily
disable a test.
.TP
\fImacCrash\fR
-test crashes if it's run on a Mac. This flag is used to temporarily
+test crashes if it is run on a Mac. This flag is used to temporarily
disable a test.
.TP
\fIemptyTest\fR
@@ -643,46 +657,50 @@ test can only run if Unix user is not root
.TP
\fIeformat\fR
test can only run if app has a working version of sprintf with respect
-to the "e" format of floating-point numbers.
+to the
+.QW e
+format of floating-point numbers.
.TP
\fIstdio\fR
-test can only be run if [\fBinterpreter\fR] can be [\fBopen\fR]ed
+test can only be run if \fBinterpreter\fR can be \fBopen\fRed
as a pipe.
.PP
The alternative mode of constraint control is enabled by setting
-[\fBconfigure -limitconstraints\fR] to true. With that configuration
+\fBconfigure \-limitconstraints\fR to true. With that configuration
setting, all existing constraints other than those in the constraint
-list returned by [\fBconfigure -constraints\fR] are set to false.
-When the value of [\fBconfigure -constraints\fR]
+list returned by \fBconfigure \-constraints\fR are set to false.
+When the value of \fBconfigure \-constraints\fR
is set, all those constraints are set to true. The effect is that
-when both options [\fBconfigure -constraints\fR] and
-[\fBconfigure -limitconstraints\fR] are in use, only those tests including
-only constraints from the [\fBconfigure -constraints\fR] list
+when both options \fBconfigure \-constraints\fR and
+\fBconfigure \-limitconstraints\fR are in use, only those tests including
+only constraints from the \fBconfigure \-constraints\fR list
are run; all others are skipped. For example, one might set
up a configuration with
+.PP
.CS
\fBconfigure\fR -constraints knownBug \e
-limitconstraints true \e
-verbose pass
.CE
+.PP
to run exactly those tests that exercise known bugs, and discover
-whether any of them pass, indicating the bug had been fixed.
+whether any of them pass, indicating the bug had been fixed.
.SH "RUNNING ALL TESTS"
.PP
-The single command [\fBrunAllTests\fR] is evaluated to run an entire
+The single command \fBrunAllTests\fR is evaluated to run an entire
test suite, spanning many files and directories. The configuration
options of \fBtcltest\fR control the precise operations. The
-[\fBrunAllTests\fR] command begins by printing a summary of its
-configuration to [\fBoutputChannel\fR].
+\fBrunAllTests\fR command begins by printing a summary of its
+configuration to \fBoutputChannel\fR.
.PP
Test files to be evaluated are sought in the directory
-[\fBconfigure -testdir\fR]. The list of files in that directory
-that match any of the patterns in [\fBconfigure -file\fR] and
-match none of the patterns in [\fBconfigure -notfile\fR] is generated
+\fBconfigure \-testdir\fR. The list of files in that directory
+that match any of the patterns in \fBconfigure \-file\fR and
+match none of the patterns in \fBconfigure \-notfile\fR is generated
and sorted. Then each file will be evaluated in turn. If
-[\fBconfigure -singleproc\fR] is true, then each file will
-be [\fBsource\fR]d in the caller's context. If it is false,
-then a copy of [\fBinterpreter\fR] will be [\fBexec\fR]d to
+\fBconfigure \-singleproc\fR is true, then each file will
+be \fBsource\fRd in the caller's context. If it is false,
+then a copy of \fBinterpreter\fR will be \fBexec\fR'd to
evaluate each file. The multi-process operation is useful
when testing can cause errors so severe that a process
terminates. Although such an error may terminate a child
@@ -690,17 +708,17 @@ process evaluating one file, the master process can continue
with the rest of the test suite. In multi-process operation,
the configuration of \fBtcltest\fR in the master process is
passed to the child processes as command line arguments,
-with the exception of [\fBconfigure -outfile\fR]. The
-[\fBrunAllTests\fR] command in the
+with the exception of \fBconfigure \-outfile\fR. The
+\fBrunAllTests\fR command in the
master process collects all output from the child processes
and collates their results into one master report. Any
reports of individual test failures, or messages requested
-by a [\fBconfigure -verbose\fR] setting are passed directly
-on to [\fBoutputChannel\fR] by the master process.
+by a \fBconfigure \-verbose\fR setting are passed directly
+on to \fBoutputChannel\fR by the master process.
.PP
After evaluating all selected test files, a summary of the
-results is printed to [\fBoutputChannel\fR]. The summary
-includes the total number of [\fBtest\fR]s evaluated, broken
+results is printed to \fBoutputChannel\fR. The summary
+includes the total number of \fBtest\fRs evaluated, broken
down into those skipped, those passed, and those failed.
The summary also notes the number of files evaluated, and the names
of any files with failing tests or errors. A list of
@@ -708,45 +726,45 @@ the constraints that caused tests to be skipped, and the
number of tests skipped for each is also printed. Also,
messages are printed if it appears that evaluation of
a test file has caused any temporary files to be left
-behind in [\fBconfigure -tmpdir\fR].
+behind in \fBconfigure \-tmpdir\fR.
.PP
Having completed and summarized all selected test files,
-[\fBrunAllTests\fR] then recursively acts on subdirectories
-of [\fBconfigure -testdir\fR]. All subdirectories that
-match any of the patterns in [\fBconfigure -relateddir\fR]
+\fBrunAllTests\fR then recursively acts on subdirectories
+of \fBconfigure \-testdir\fR. All subdirectories that
+match any of the patterns in \fBconfigure \-relateddir\fR
and do not match any of the patterns in
-[\fBconfigure -asidefromdir\fR] are examined. If
+\fBconfigure \-asidefromdir\fR are examined. If
a file named \fBall.tcl\fR is found in such a directory,
-it will be [\fBsource\fR]d in the caller's context.
+it will be \fBsource\fRd in the caller's context.
Whether or not an examined directory contains an
\fBall.tcl\fR file, its subdirectories are also scanned
-against the [\fBconfigure -relateddir\fR] and
-[\fBconfigure -asidefromdir\fR] patterns. In this way,
+against the \fBconfigure \-relateddir\fR and
+\fBconfigure \-asidefromdir\fR patterns. In this way,
many directories in a directory tree can have all their
-test files evaluated by a single [\fBrunAllTests\fR]
+test files evaluated by a single \fBrunAllTests\fR
command.
.SH "CONFIGURABLE OPTIONS"
-The [\fBconfigure\fR] command is used to set and query the configurable
+The \fBconfigure\fR command is used to set and query the configurable
options of \fBtcltest\fR. The valid options are:
.TP
-\fB-singleproc \fIboolean\fR
-Controls whether or not [\fBrunAllTests\fR] spawns a child process for
+\fB\-singleproc \fIboolean\fR
+Controls whether or not \fBrunAllTests\fR spawns a child process for
each test file. No spawning when \fIboolean\fR is true. Default
value is false.
.TP
-\fB-debug \fIlevel\fR
+\fB\-debug \fIlevel\fR
Sets the debug level to \fIlevel\fR, an integer value indicating how
much debugging information should be printed to stdout. Note that
debug messages always go to stdout, independent of the value of
-[\fBconfigure -outfile\fR]. Default value is 0. Levels are defined as:
+\fBconfigure \-outfile\fR. Default value is 0. Levels are defined as:
.RS
.IP 0
Do not display any debug information.
.IP 1
Display information regarding whether a test is skipped because it
-doesn't match any of the tests that were specified using by
-[\fBconfigure -match\fR] (userSpecifiedNonMatch) or matches any of
-the tests specified by [\fBconfigure -skip\fR] (userSpecifiedSkip). Also
+does not match any of the tests that were specified using by
+\fBconfigure \-match\fR (userSpecifiedNonMatch) or matches any of
+the tests specified by \fBconfigure \-skip\fR (userSpecifiedSkip). Also
print warnings about possible lack of cleanup or balance in test files.
Also print warnings about any re-use of test names.
.IP 2
@@ -758,10 +776,10 @@ Display information regarding what individual procs in the test
harness are doing.
.RE
.TP
-\fB-verbose \fIlevel\fR
+\fB\-verbose \fIlevel\fR
Sets the type of output verbosity desired to \fIlevel\fR,
a list of zero or more of the elements \fBbody\fR, \fBpass\fR,
-\fBskip\fR, \fBstart\fR, and \fBerror\fR. Default value
+\fBskip\fR, \fBstart\fR, \fBerror\fR and \fBline\fR. Default value
is \fB{body error}\fR.
Levels are defined as:
.RS
@@ -776,108 +794,121 @@ Print output whenever a test starts
.IP "error (e)"
Print errorInfo and errorCode, if they exist, when a test return code
does not match its expected return code
+.IP "line (l)"
+Print source file line information of failed tests
.RE
The single letter abbreviations noted above are also recognized
-so that [\fBconfigure -verbose pt\fR] is the same as
-[\fBconfigure -verbose {pass start}\fR].
+so that
+.QW "\fBconfigure \-verbose pt\fR"
+is the same as
+.QW "\fBconfigure \-verbose {pass start}\fR" .
.TP
-\fB-preservecore \fIlevel\fR
+\fB\-preservecore \fIlevel\fR
Sets the core preservation level to \fIlevel\fR. This level
determines how stringent checks for core files are. Default
value is 0. Levels are defined as:
.RS
.IP 0
-No checking - do not check for core files at the end of each test
-command, but do check for them in [\fBrunAllTests\fR] after all
+No checking \(em do not check for core files at the end of each test
+command, but do check for them in \fBrunAllTests\fR after all
test files have been evaluated.
.IP 1
-Also check for core files at the end of each [\fBtest\fR] command.
+Also check for core files at the end of each \fBtest\fR command.
.IP 2
Check for core files at all times described above, and save a
-copy of each core file produced in [\fBconfigure -tmpdir\fR].
+copy of each core file produced in \fBconfigure \-tmpdir\fR.
.RE
.TP
-\fB-limitconstraints \fIboolean\fR
-Sets the mode by which [\fBtest\fR] honors constraints as described
+\fB\-limitconstraints \fIboolean\fR
+Sets the mode by which \fBtest\fR honors constraints as described
in \fBTESTS\fR above. Default value is false.
.TP
-\fB-constraints \fIlist\fR
+\fB\-constraints \fIlist\fR
Sets all the constraints in \fIlist\fR to true. Also used in
-combination with [\fBconfigure -limitconstraints true\fR] to control an
+combination with \fBconfigure \-limitconstraints true\fR to control an
alternative constraint mode as described in \fBTESTS\fR above.
Default value is an empty list.
.TP
-\fB-tmpdir \fIdirectory\fR
-Sets the temporary directory to be used by [\fBmakeFile\fR],
-[\fBmakeDirectory\fR], [\fBviewFile\fR], [\fBremoveFile\fR],
-and [\fBremoveDirectory\fR] as the default directory where
+\fB\-tmpdir \fIdirectory\fR
+Sets the temporary directory to be used by \fBmakeFile\fR,
+\fBmakeDirectory\fR, \fBviewFile\fR, \fBremoveFile\fR,
+and \fBremoveDirectory\fR as the default directory where
temporary files and directories created by test files should
-be created. Default value is [\fBworkingDirectory\fR].
+be created. Default value is \fBworkingDirectory\fR.
.TP
-\fB-testdir \fIdirectory\fR
-Sets the directory searched by [\fBrunAllTests\fR] for test files
-and subdirectories. Default value is [\fBworkingDirectory\fR].
+\fB\-testdir \fIdirectory\fR
+Sets the directory searched by \fBrunAllTests\fR for test files
+and subdirectories. Default value is \fBworkingDirectory\fR.
.TP
-\fB-file \fIpatternList\fR
-Sets the list of patterns used by [\fBrunAllTests\fR] to determine
-what test files to evaluate. Default value is \fB*.test\fR.
+\fB\-file \fIpatternList\fR
+Sets the list of patterns used by \fBrunAllTests\fR to determine
+what test files to evaluate. Default value is
+.QW \fB*.test\fR .
.TP
-\fB-notfile \fIpatternList\fR
-Sets the list of patterns used by [\fBrunAllTests\fR] to determine
-what test files to skip. Default value is \fBl.*.test\fR, so
-that any SCCS lock files are skipped.
+\fB\-notfile \fIpatternList\fR
+Sets the list of patterns used by \fBrunAllTests\fR to determine
+what test files to skip. Default value is
+.QW \fBl.*.test\fR ,
+so that any SCCS lock files are skipped.
.TP
-\fB-relateddir \fIpatternList\fR
-Sets the list of patterns used by [\fBrunAllTests\fR] to determine
+\fB\-relateddir \fIpatternList\fR
+Sets the list of patterns used by \fBrunAllTests\fR to determine
what subdirectories to search for an \fBall.tcl\fR file. Default
-value is \fB*\fR.
+value is
+.QW \fB*\fR .
.TP
-\fB-asidefromdir \fIpatternList\fR
-Sets the list of patterns used by [\fBrunAllTests\fR] to determine
+\fB\-asidefromdir \fIpatternList\fR
+Sets the list of patterns used by \fBrunAllTests\fR to determine
what subdirectories to skip when searching for an \fBall.tcl\fR file.
Default value is an empty list.
.TP
-\fB-match \fIpatternList\fR
-Set the list of patterns used by [\fBtest\fR] to determine whether
-a test should be run. Default value is \fB*\fR.
+\fB\-match \fIpatternList\fR
+Set the list of patterns used by \fBtest\fR to determine whether
+a test should be run. Default value is
+.QW \fB*\fR .
.TP
-\fB-skip \fIpatternList\fR
-Set the list of patterns used by [\fBtest\fR] to determine whether
+\fB\-skip \fIpatternList\fR
+Set the list of patterns used by \fBtest\fR to determine whether
a test should be skipped. Default value is an empty list.
.TP
-\fB-load \fIscript\fR
-Sets a script to be evaluated by [\fBloadTestedCommands\fR].
+\fB\-load \fIscript\fR
+Sets a script to be evaluated by \fBloadTestedCommands\fR.
Default value is an empty script.
.TP
-\fB-loadfile \fIfilename\fR
+\fB\-loadfile \fIfilename\fR
Sets the filename from which to read a script to be evaluated
-by [\fBloadTestedCommands\fR]. This is an alternative to
-\fB-load\fR. They cannot be used together.
+by \fBloadTestedCommands\fR. This is an alternative to
+\fB\-load\fR. They cannot be used together.
.TP
-\fB-outfile \fIfilename\fR
+\fB\-outfile \fIfilename\fR
Sets the file to which all output produced by tcltest should be
-written. A file named \fIfilename\fR will be [\fBopen\fR]ed for writing,
-and the resulting channel will be set as the value of [\fBoutputChannel\fR].
+written. A file named \fIfilename\fR will be \fBopen\fRed for writing,
+and the resulting channel will be set as the value of \fBoutputChannel\fR.
.TP
-\fB-errfile \fIfilename\fR
+\fB\-errfile \fIfilename\fR
Sets the file to which all error output produced by tcltest
-should be written. A file named \fIfilename\fR will be [\fBopen\fR]ed
+should be written. A file named \fIfilename\fR will be \fBopen\fRed
for writing, and the resulting channel will be set as the value
-of [\fBerrorChannel\fR].
+of \fBerrorChannel\fR.
.SH "CREATING TEST SUITES WITH TCLTEST"
.PP
-The fundamental element of a test suite is the individual [\fBtest\fR]
+The fundamental element of a test suite is the individual \fBtest\fR
command. We begin with several examples.
.IP [1]
Test of a script that returns normally.
+.RS
+.PP
.CS
\fBtest\fR example-1.0 {normal return} {
format %s value
} value
.CE
+.RE
.IP [2]
Test of a script that requires context setup and cleanup. Note the
bracing and indenting style that avoids any need for line continuation.
+.RS
+.PP
.CS
\fBtest\fR example-1.1 {test file existence} -setup {
set file [makeFile {} test]
@@ -887,15 +918,21 @@ bracing and indenting style that avoids any need for line continuation.
removeFile test
} -result 1
.CE
+.RE
.IP [3]
Test of a script that raises an error.
+.RS
+.PP
.CS
\fBtest\fR example-1.2 {error return} -body {
error message
} -returnCodes error -result message
.CE
+.RE
.IP [4]
Test with a constraint.
+.RS
+.PP
.CS
\fBtest\fR example-1.3 {user owns created files} -constraints {
unix
@@ -907,47 +944,57 @@ Test with a constraint.
removeFile test
} -result $::tcl_platform(user)
.CE
+.RE
.PP
-At the next higher layer of organization, several [\fBtest\fR] commands
+At the next higher layer of organization, several \fBtest\fR commands
are gathered together into a single test file. Test files should have
names with the \fB.test\fR extension, because that is the default pattern
-used by [\fBrunAllTests\fR] to find test files. It is a good rule of
+used by \fBrunAllTests\fR to find test files. It is a good rule of
thumb to have one test file for each source code file of your project.
It is good practice to edit the test file and the source code file
together, keeping tests synchronized with code changes.
.PP
-Most of the code in the test file should be the [\fBtest\fR] commands.
+Most of the code in the test file should be the \fBtest\fR commands.
Use constraints to skip tests, rather than conditional evaluation
-of [\fBtest\fR]. That is, do this:
+of \fBtest\fR.
.IP [5]
+Recommended system for writing conditional tests, using constraints to
+guard:
+.RS
+.PP
.CS
\fBtestConstraint\fR X [expr $myRequirement]
\fBtest\fR goodConditionalTest {} X {
# body
} result
.CE
-and do not do this:
+.RE
.IP [6]
+Discouraged system for writing conditional tests, using \fBif\fR to
+guard:
+.RS
+.PP
.CS
if $myRequirement {
test badConditionalTest {} {
- #body
+ #body
} result
}
.CE
+.RE
.PP
-Use the \fB-setup\fR and \fB-cleanup\fR options to establish and release
+Use the \fB\-setup\fR and \fB\-cleanup\fR options to establish and release
all context requirements of the test body. Do not make tests depend on
prior tests in the file. Those prior tests might be skipped. If several
consecutive tests require the same context, the appropriate setup
and cleanup scripts may be stored in variable for passing to each tests
-\fB-setup\fR and \fB-cleanup\fR options. This is a better solution than
-performing setup outside of [\fBtest\fR] commands, because the setup will
+\fB\-setup\fR and \fB\-cleanup\fR options. This is a better solution than
+performing setup outside of \fBtest\fR commands, because the setup will
only be done if necessary, and any errors during setup will be reported,
and not cause the test file to abort.
.PP
A test file should be able to be combined with other test files and not
-interfere with them, even when [\fBconfigure -singleproc 1\fR] causes
+interfere with them, even when \fBconfigure \-singleproc 1\fR causes
all files to be evaluated in a common interpreter. A simple way to
achieve this is to have your tests define all their commands and variables
in a namespace that is deleted when the test file evaluation is complete.
@@ -955,14 +1002,16 @@ A good namespace to use is a child namespace \fBtest\fR of the namespace
of the module you are testing.
.PP
A test file should also be able to be evaluated directly as a script,
-not depending on being called by a master [\fBrunAllTests\fR]. This
+not depending on being called by a master \fBrunAllTests\fR. This
means that each test file should process command line arguments to give
the tester all the configuration control that \fBtcltest\fR provides.
.PP
-After all [\fBtest\fR]s in a test file, the command [\fBcleanupTests\fR]
+After all \fBtest\fRs in a test file, the command \fBcleanupTests\fR
should be called.
.IP [7]
Here is a sketch of a sample test file illustrating those points:
+.RS
+.PP
.CS
package require tcltest 2.2
eval \fB::tcltest::configure\fR $argv
@@ -973,36 +1022,40 @@ namespace eval ::example::test {
variable SETUP {#common setup code}
variable CLEANUP {#common cleanup code}
\fBtest\fR example-1 {} -setup $SETUP -body {
- # First test
+ # First test
} -cleanup $CLEANUP -result {...}
\fBtest\fR example-2 {} -constraints X -setup $SETUP -body {
- # Second test; constrained
+ # Second test; constrained
} -cleanup $CLEANUP -result {...}
\fBtest\fR example-3 {} {
- # Third test; no context required
+ # Third test; no context required
} {...}
\fBcleanupTests\fR
}
namespace delete ::example::test
.CE
+.RE
.PP
The next level of organization is a full test suite, made up of several
test files. One script is used to control the entire suite. The
-basic function of this script is to call [\fBrunAllTests\fR] after
+basic function of this script is to call \fBrunAllTests\fR after
doing any necessary setup. This script is usually named \fBall.tcl\fR
-because that's the default name used by [\fBrunAllTests\fR] when combining
+because that is the default name used by \fBrunAllTests\fR when combining
multiple test suites into one testing run.
.IP [8]
Here is a sketch of a sample test suite master script:
+.RS
+.PP
.CS
package require Tcl 8.4
package require tcltest 2.2
package require example
-\fB::tcltest::configure\fR -testdir \
+\fB::tcltest::configure\fR -testdir \e
[file dirname [file normalize [info script]]]
eval \fB::tcltest::configure\fR $argv
\fB::tcltest::runAllTests\fR
.CE
+.RE
.SH COMPATIBILITY
.PP
A number of commands and variables in the \fB::tcltest\fR namespace
@@ -1012,21 +1065,24 @@ here. They are no longer part of the supported public interface of
to continue to support existing test suites written to the older
interface specifications, many of those deprecated commands and
variables still work as before. For example, in many circumstances,
-[\fBconfigure\fR] will be automatically called shortly after
-[\fBpackage require tcltest 2.1\fR] succeeds with arguments
+\fBconfigure\fR will be automatically called shortly after
+\fBpackage require tcltest 2.1\fR succeeds with arguments
from the variable \fB::argv\fR. This is to support test suites
that depend on the old behavior that \fBtcltest\fR was automatically
configured from command line arguments. New test files should not
depend on this, but should explicitly include
+.PP
.CS
eval \fB::tcltest::configure\fR $::argv
.CE
+.PP
to establish a configuration from command line arguments.
.SH "KNOWN ISSUES"
-There are two known issues related to nested evaluations of [\fBtest\fR].
+There are two known issues related to nested evaluations of \fBtest\fR.
The first issue relates to the stack level in which test scripts are
executed. Tests nested within other tests may be executed at the same
stack level as the outermost test. For example, in the following code:
+.PP
.CS
\fBtest\fR level-1.1 {level 1} {
-body {
@@ -1035,27 +1091,38 @@ stack level as the outermost test. For example, in the following code:
}
}
.CE
+.PP
any script executed in level-2.1 may be executed at the same stack
level as the script defined for level-1.1.
.PP
-In addition, while two [\fBtest\fR]s have been run, results will only
-be reported by [\fBcleanupTests\fR] for tests at the same level as
+In addition, while two \fBtest\fRs have been run, results will only
+be reported by \fBcleanupTests\fR for tests at the same level as
test level-1.1. However, test results for all tests run prior to
level-1.1 will be available when test level-2.1 runs. What this
means is that if you try to access the test results for test level-2.1,
-it will may say that 'm' tests have run, 'n' tests have
-been skipped, 'o' tests have passed and 'p' tests have failed,
-where 'm', 'n', 'o', and 'p' refer to tests that were run at the
-same test level as test level-1.1.
+it will may say that
+.QW m
+tests have run,
+.QW n
+tests have been skipped,
+.QW o
+tests have passed and
+.QW p
+tests have failed, where
+.QW m ,
+.QW n ,
+.QW o ,
+and
+.QW p
+refer to tests that were run at the same test level as test level-1.1.
.PP
Implementation of output and error comparison in the test command
depends on usage of ::puts in your application code. Output is
intercepted by redefining the ::puts command while the defined test
script is being run. Errors thrown by C procedures or printed
directly from C applications will not be caught by the test command.
-Therefore, usage of the \fB-output\fR and \fB-errorOutput\fR
-options to [\fBtest\fR] is useful only for pure Tcl applications
-that use [\fB::puts\fR] to produce output.
-
+Therefore, usage of the \fB\-output\fR and \fB\-errorOutput\fR
+options to \fBtest\fR is useful only for pure Tcl applications
+that use \fB::puts\fR to produce output.
.SH KEYWORDS
test, test harness, test suite
diff --git a/doc/tclvars.n b/doc/tclvars.n
index d097a92..885de34 100644
--- a/doc/tclvars.n
+++ b/doc/tclvars.n
@@ -12,7 +12,6 @@
.SH NAME
tclvars \- Variables used by Tcl
.BE
-
.SH DESCRIPTION
.PP
The following global variables are created and managed automatically
@@ -25,7 +24,7 @@ whose elements are the environment variables for the process.
Reading an element will return the value of the corresponding
environment variable.
Setting an element of the array will modify the corresponding
-environment variable or create a new one if it doesn't already
+environment variable or create a new one if it does not already
exist.
Unsetting an element of \fBenv\fR will remove the corresponding
environment variable.
@@ -35,90 +34,74 @@ If the entire \fBenv\fR array is unset then Tcl will stop
monitoring \fBenv\fR accesses and will not update environment
variables.
.RS
-.VS 8.0
+.PP
Under Windows, the environment variables PATH and COMSPEC in any
capitalization are converted automatically to upper case. For instance, the
-PATH variable could be exported by the operating system as ``path'',
-``Path'', ``PaTh'', etc., causing otherwise simple Tcl code to have to
+PATH variable could be exported by the operating system as
+.QW path ,
+.QW Path ,
+.QW PaTh ,
+etc., causing otherwise simple Tcl code to have to
support many special cases. All other environment variables inherited by
Tcl are left unmodified. Setting an env array variable to blank is the
same as unsetting it as this is the behavior of the underlying Windows OS.
It should be noted that relying on an existing and empty environment variable
-won't work on windows and is discouraged for cross-platform usage.
-.VE
-.RE
-.RS
-On the Macintosh, the environment variable is constructed by Tcl as no
-global environment variable exists. The environment variables that
-are created for Tcl include:
-.TP
-\fBLOGIN\fR
-This holds the Chooser name of the Macintosh.
-.TP
-\fBUSER\fR
-This also holds the Chooser name of the Macintosh.
-.TP
-\fBSYS_FOLDER\fR
-The path to the system directory.
-.TP
-\fBAPPLE_M_FOLDER\fR
-The path to the Apple Menu directory.
-.TP
-\fBCP_FOLDER\fR
-The path to the control panels directory.
-.TP
-\fBDESK_FOLDER\fR
-The path to the desk top directory.
-.TP
-\fBEXT_FOLDER\fR
-The path to the system extensions directory.
-.TP
-\fBPREF_FOLDER\fR
-The path to the preferences directory.
-.TP
-\fBPRINT_MON_FOLDER\fR
-The path to the print monitor directory.
-.TP
-\fBSHARED_TRASH_FOLDER\fR
-The path to the network trash directory.
-.TP
-\fBTRASH_FOLDER\fR
-The path to the trash directory.
-.TP
-\fBSTART_UP_FOLDER\fR
-The path to the start up directory.
-.TP
-\fBHOME\fR
-The path to the application's default directory.
+will not work on Windows and is discouraged for cross-platform usage.
.PP
-You can also create your own environment variables for the Macintosh.
-A file named \fITcl Environment Variables\fR may be placed in the
-preferences folder in the Mac system folder. Each line of this file
-should be of the form \fIVAR_NAME=var_data\fR.
+The following elements of \fBenv\fR are special to Tcl:
+.TP
+\fBenv(HOME)\fR
+.
+This environment variable, if set, gives the location of the directory
+considered to be the current user's home directory, and to which a
+call of \fBcd\fR without arguments or with just
+.QW ~
+as an argument will change into. Most platforms set this correctly by
+default; it does not normally need to be set by user code.
+.TP
+\fBenv(TCL_LIBRARY)\fR
+.
+If set, then it specifies the location of the directory containing
+library scripts (the value of this variable will be
+assigned to the \fBtcl_library\fR variable and therefore returned by
+the command \fBinfo library\fR). If this variable is not set then
+a default value is used.
+.RS
.PP
-The last alternative is to place environment variables in a 'STR#'
-resource named \fITcl Environment Variables\fR of the application. This
-is considered a little more ``Mac like'' than a Unix style Environment
-Variable file. Each entry in the 'STR#' resource has the same format
-as above. The source code file \fItclMacEnv.c\fR contains the
-implementation of the env mechanisms. This file contains many
-#define's that allow customization of the env mechanisms to fit your
-applications needs.
+Note that this environment variable should \fInot\fR normally be set.
+.RE
+.TP
+\fBenv(TCLLIBPATH)\fR
+.
+If set, then it must contain a valid Tcl list giving directories to
+search during auto-load operations. Directories must be specified in
+Tcl format, using
+.QW /
+as the path separator, regardless of platform.
+This variable is only used when initializing the \fBauto_path\fR variable.
+.TP
+\fBenv(TCL_INTERP_DEBUG_FRAME)\fR
+.
+If existing, it has the same effect as running \fBinterp debug {} -frame 1\fR
+as the very first command of each new Tcl interpreter.
.RE
.TP
\fBerrorCode\fR
-After an error has occurred, this variable will be set to hold
-a list value representing additional information about the error
+This variable holds the value of the \fB\-errorcode\fR return option
+set by the most recent error that occurred in this interpreter.
+This list value represents additional information about the error
in a form that is easy to process with programs.
The first element of the list identifies a general class of
errors, and determines the format of the rest of the list.
-The following formats for \fBerrorCode\fR are used by the
-Tcl core; individual applications may define additional formats.
+The following formats for \fB\-errorcode\fR return options
+are used by the Tcl core; individual applications may define
+additional formats.
.RS
.TP
\fBARITH\fI code msg\fR
+.
This format is used when an arithmetic error occurs (e.g. an attempt
-to divide by zero in the \fBexpr\fR command).
+to divide zero by zero in the \fBexpr\fR command).
\fICode\fR identifies the precise error and \fImsg\fR provides a
human-readable description of the error. \fICode\fR will be either
DIVZERO (for an attempt to divide by zero),
@@ -126,62 +109,77 @@ DOMAIN (if an argument is outside the domain of a function, such as acos(\-3)),
IOVERFLOW (for integer overflow),
OVERFLOW (for a floating-point overflow),
or UNKNOWN (if the cause of the error cannot be determined).
+.RS
+.PP
+Detection of these errors depends in part on the underlying hardware
+and system libraries.
+.RE
.TP
\fBCHILDKILLED\fI pid sigName msg\fR
This format is used when a child process has been killed because of
-a signal. The second element of \fBerrorCode\fR will be the
-process's identifier (in decimal).
-The third element will be the symbolic name of the signal that caused
+a signal. The \fIpid\fR element will be the process's identifier (in decimal).
+The \fIsigName\fR element will be the symbolic name of the signal that caused
the process to terminate; it will be one of the names from the
include file signal.h, such as \fBSIGPIPE\fR.
-The fourth element will be a short human-readable message
-describing the signal, such as ``write on pipe with no readers''
+The \fImsg\fR element will be a short human-readable message
+describing the signal, such as
+.QW "write on pipe with no readers"
for \fBSIGPIPE\fR.
.TP
\fBCHILDSTATUS\fI pid code\fR
This format is used when a child process has exited with a non-zero
-exit status. The second element of \fBerrorCode\fR will be the
-process's identifier (in decimal) and the third element will be the exit
+exit status. The \fIpid\fR element will be the
+process's identifier (in decimal) and the \fIcode\fR element will be the exit
code returned by the process (also in decimal).
.TP
\fBCHILDSUSP\fI pid sigName msg\fR
This format is used when a child process has been suspended because
of a signal.
-The second element of \fBerrorCode\fR will be the process's identifier,
-in decimal.
-The third element will be the symbolic name of the signal that caused
+The \fIpid\fR element will be the process's identifier, in decimal.
+The \fIsigName\fR element will be the symbolic name of the signal that caused
the process to suspend; this will be one of the names from the
include file signal.h, such as \fBSIGTTIN\fR.
-The fourth element will be a short human-readable message
-describing the signal, such as ``background tty read''
+The \fImsg\fR element will be a short human-readable message
+describing the signal, such as
+.QW "background tty read"
for \fBSIGTTIN\fR.
.TP
\fBNONE\fR
This format is used for errors where no additional information is
available for an error besides the message returned with the
-error. In these cases \fBerrorCode\fR will consist of a list
-containing a single element whose contents are \fBNONE\fR.
+error. In these cases the \fB\-errorcode\fR return option
+will consist of a list containing a single element whose
+contents are \fBNONE\fR.
.TP
\fBPOSIX \fIerrName msg\fR
-If the first element of \fBerrorCode\fR is \fBPOSIX\fR, then
+If the first element is \fBPOSIX\fR, then
the error occurred during a POSIX kernel call.
-The second element of the list will contain the symbolic name
+The \fIerrName\fR element will contain the symbolic name
of the error that occurred, such as \fBENOENT\fR; this will
be one of the values defined in the include file errno.h.
-The third element of the list will be a human-readable
+The \fImsg\fR element will be a human-readable
message corresponding to \fIerrName\fR, such as
-``no such file or directory'' for the \fBENOENT\fR case.
+.QW "no such file or directory"
+for the \fBENOENT\fR case.
.PP
-To set \fBerrorCode\fR, applications should use library
-procedures such as \fBTcl_SetErrorCode\fR and \fBTcl_PosixError\fR,
-or they may invoke the \fBerror\fR command.
-If one of these methods hasn't been used, then the Tcl
-interpreter will reset the variable to \fBNONE\fR after
+To set the \fB\-errorcode\fR return option, applications should use library
+procedures such as \fBTcl_SetObjErrorCode\fR, \fBTcl_SetReturnOptions\fR,
+and \fBTcl_PosixError\fR, or they may invoke the \fB\-errorcode\fR
+option of the \fBreturn\fR command.
+If none of these methods for setting the error code has been used,
+the Tcl interpreter will reset the variable to \fBNONE\fR after
the next error.
.RE
+.\" .TP
+.\" \fBTCL\fR ...
+.\" .
+.\" Indicates some sort of problem generated in relation to Tcl itself,
+.\" e.g. a failure to look up a channel or variable.
.TP
\fBerrorInfo\fR
-After an error has occurred, this string will contain one or more lines
+This variable holds the value of the \fB\-errorinfo\fR return option
+set by the most recent error that occurred in this interpreter.
+This string value will contain one or more lines
identifying the Tcl commands and procedures that were being executed
when the most recent error occurred.
Its contents take the form of a stack trace showing the various
@@ -203,19 +201,19 @@ is created by searching several different directories until one is
found that contains an appropriate Tcl startup script.
If the \fBTCL_LIBRARY\fR environment variable exists, then
the directory it names is checked first.
-If \fBTCL_LIBRARY\fR isn't set or doesn't refer to an appropriate
+If \fBTCL_LIBRARY\fR is not set or doesn't refer to an appropriate
directory, then Tcl checks several other directories based on a
compiled-in default location, the location of the binary containing
the application, and the current working directory.
.TP
\fBtcl_patchLevel\fR
+.
When an interpreter is created Tcl initializes this variable to
hold a string giving the current patch level for Tcl, such as
-\fB7.3p2\fR for Tcl 7.3 with the first two official patches, or
-\fB7.4b4\fR for the fourth beta release of Tcl 7.4.
+\fB8.4.16\fR for Tcl 8.4 with the first sixteen official patches, or
+\fB8.5b3\fR for the third beta release of Tcl 8.5.
The value of this variable is returned by the \fBinfo patchlevel\fR
command.
-.VS 8.0 br
.TP
\fBtcl_pkgPath\fR
This variable holds a list of directories indicating where packages are
@@ -228,29 +226,26 @@ subdirectory of one of the entries in \fB$tcl_pkgPath\fR. The directories
in \fB$tcl_pkgPath\fR are included by default in the \fBauto_path\fR
variable, so they and their immediate subdirectories are automatically
searched for packages during \fBpackage require\fR commands. Note:
-\fBtcl_pkgPath\fR it not intended to be modified by the application. Its
+\fBtcl_pkgPath\fR is not intended to be modified by the application. Its
value is added to \fBauto_path\fR at startup; changes to \fBtcl_pkgPath\fR
are not reflected in \fBauto_path\fR. If you want Tcl to search additional
directories for packages you should add the names of those directories to
\fBauto_path\fR, not \fBtcl_pkgPath\fR.
-.VE
.TP
\fBtcl_platform\fR
This is an associative array whose elements contain information about
the platform on which the application is running, such as the name of
the operating system, its current release number, and the machine's
instruction set. The elements listed below will always
-be defined, but they may have empty strings as values if Tcl couldn't
+be defined, but they may have empty strings as values if Tcl could not
retrieve any relevant information. In addition, extensions
and applications may add additional values to the array. The
predefined elements are:
.RS
-.VS
.TP
\fBbyteOrder\fR
The native byte order of this machine: either \fBlittleEndian\fR or
\fBbigEndian\fR.
-.VE
.TP
\fBdebug\fR
If this variable exists, then the interpreter was compiled with and linked
@@ -266,7 +261,7 @@ is the value returned by \fBuname -m\fR.
.TP
\fBos\fR
The name of the operating system running on this machine,
-such as \fBWindows 95\fR, \fBWindows NT\fR, \fBMacOS\fR, or \fBSunOS\fR.
+such as \fBWindows 95\fR, \fBWindows NT\fR, or \fBSunOS\fR.
On UNIX machines, this is the value returned by \fBuname -s\fR.
On Windows 95 and Windows 98, the value returned will be \fBWindows
95\fR to provide better backwards compatibility to Windows 95; to
@@ -279,7 +274,7 @@ Windows 95, the version will be 4.0; on Windows 98, the version will
be 4.10.
.TP
\fBplatform\fR
-Either \fBwindows\fR, \fBmacintosh\fR, or \fBunix\fR. This identifies the
+Either \fBwindows\fR, or \fBunix\fR. This identifies the
general operating environment of the machine.
.TP
\fBthreaded\fR
@@ -290,33 +285,71 @@ was compiled with threads enabled.
This identifies the
current user based on the login information available on the platform.
This comes from the USER or LOGNAME environment variable on Unix,
-and the value from GetUserName on Windows and Macintosh.
+and the value from GetUserName on Windows.
.TP
\fBwordSize\fR
-.VS 8.4
This gives the size of the native-machine word in bytes (strictly, it
is same as the result of evaluating \fIsizeof(long)\fR in C.)
-.VE 8.4
+.TP
+\fBpointerSize\fR
+This gives the size of the native-machine pointer in bytes (strictly, it
+is same as the result of evaluating \fIsizeof(void*)\fR in C.)
.RE
.TP
\fBtcl_precision\fR
-.VS
+.
This variable controls the number of digits to generate
when converting floating-point values to strings. It defaults
-to 12.
-17 digits is ``perfect'' for IEEE floating-point in that it allows
+to 0. \fIApplications should not change this value;\fR it is
+provided for compatibility with legacy code.
+.PP
+.RS
+The default value of 0 is special, meaning that Tcl should
+convert numbers using as few digits as possible while still
+distinguishing any floating point number from its nearest
+neighbours. It differs from using an arbitrarily high value
+for \fItcl_precision\fR in that an inexact number like \fI1.4\fR
+will convert as \fI1.4\fR rather than \fI1.3999999999999999\fR
+even though the latter is nearer to the exact value of the
+binary number.
+.RE
+.PP
+.RS
+If \fBtcl_precision\fR is not zero, then when Tcl converts a floating
+point number, it creates a decimal representation of at most
+\fBtcl_precision\fR significant digits; the result may be shorter if
+the shorter result represents the original number exactly. If no
+result of at most \fBtcl_precision\fR digits is an exact representation
+of the original number, the one that is closest to the original
+number is chosen.
+If the original number lies precisely between two equally accurate
+decimal representations, then the one with an even value for the least
+significant digit is chosen; for instance, if \fBtcl_precision\fR is 3, then
+0.3125 will convert to 0.312, not 0.313, while 0.6875 will convert to
+0.688, not 0.687. Any string of trailing zeroes that remains is trimmed.
+.RE
+.PP
+.RS
+a \fBtcl_precision\fR value of 17 digits is
+.QW perfect
+for IEEE floating-point in that it allows
double-precision values to be converted to strings and back to
-binary with no loss of information. However, using 17 digits prevents
-any rounding, which produces longer, less intuitive results. For example,
-\fBexpr 1.4\fR returns 1.3999999999999999 with \fBtcl_precision\fR
-set to 17, vs. 1.4 if \fBtcl_precision\fR is 12.
+binary with no loss of information. For this reason, you will often
+see it as a value in legacy code that must run on Tcl versions before
+8.5. It is no longer recommended; as noted above, a zero value is the
+preferred method.
+.RE
+.PP
.RS
-All interpreters in a process share a single \fBtcl_precision\fR value:
+All interpreters in a thread share a single \fBtcl_precision\fR value:
changing it in one interpreter will affect all other interpreters as
-well. However, safe interpreters are not allowed to modify the
+well. Safe interpreters are not allowed to modify the
variable.
.RE
-.VE
+.PP
+.RS
+Valid values for \fBtcl_precision\fR range from 0 to 17.
+.RE
.TP
\fBtcl_rcFileName\fR
This variable is used during initialization to indicate the name of a
@@ -326,15 +359,6 @@ of this file and \fBsource\fR it if it exists. For example, for \fBwish\fR
the variable is set to \fB~/.wishrc\fR for Unix and \fB~/wishrc.tcl\fR
for Windows.
.TP
-\fBtcl_rcRsrcName\fR
-This variable is only used on Macintosh systems. The variable is used
-during initialization to indicate the name of a user-specific
-\fBTEXT\fR resource located in the application or extension resource
-forks. If it is set by application-specific initialization, then the
-Tcl startup code will check for the existence of this resource and
-\fBsource\fR it if it exists. For example, the Macintosh \fBwish\fR
-application has the variable is set to \fBtclshrc\fR.
-.TP
\fBtcl_traceCompile\fR
The value of this variable can be set to control
how much tracing information
@@ -346,11 +370,11 @@ Setting it to 2 generates a detailed listing in stdout of the
bytecode instructions emitted during every compilation.
This variable is useful in
tracking down suspected problems with the Tcl compiler.
-It is also occasionally useful when converting
-existing code to use Tcl8.0.
.PP
+.RS
This variable and functionality only exist if
\fBTCL_COMPILE_DEBUG\fR was defined during Tcl's compilation.
+.RE
.TP
\fBtcl_traceExec\fR
The value of this variable can be set to control
@@ -371,26 +395,30 @@ of bytecode instructions are not shown.
Setting this variable is useful in
tracking down suspected problems with the bytecode compiler
and interpreter.
-It is also occasionally useful when converting
-code to use Tcl8.0.
.PP
+.RS
This variable and functionality only exist if
\fBTCL_COMPILE_DEBUG\fR was defined during Tcl's compilation.
+.RE
.TP
\fBtcl_wordchars\fR
The value of this variable is a regular expression that can be set to
-control what are considered ``word'' characters, for instances like
+control what are considered
+.QW word
+characters, for instances like
selecting a word by double-clicking in text in Tk. It is platform
-dependent. On Windows, it defaults to \fB\\S\fR, meaning anything
-but a Unicode space character. Otherwise it defaults to \fB\\w\fR,
+dependent. On Windows, it defaults to \fB\eS\fR, meaning anything
+but a Unicode space character. Otherwise it defaults to \fB\ew\fR,
which is any Unicode word character (number, letter, or underscore).
.TP
\fBtcl_nonwordchars\fR
The value of this variable is a regular expression that can be set to
-control what are considered ``non-word'' characters, for instances like
+control what are considered
+.QW non-word
+characters, for instances like
selecting a word by double-clicking in text in Tk. It is platform
-dependent. On Windows, it defaults to \fB\\s\fR, meaning any Unicode space
-character. Otherwise it defaults to \fB\\W\fR, which is anything but a
+dependent. On Windows, it defaults to \fB\es\fR, meaning any Unicode space
+character. Otherwise it defaults to \fB\eW\fR, which is anything but a
Unicode word character (number, letter, or underscore).
.TP
\fBtcl_version\fR
@@ -422,15 +450,13 @@ Contains 1 if \fBtclsh\fR or \fBwish\fR is running interactively (no
script was specified and standard input is a terminal-like device), 0
otherwise.
.PP
-The \fBwish\fR executably additionally specifies the following global
+The \fBwish\fR executable additionally specifies the following global
variable:
.TP 6
\fBgeometry\fR
If set, contains the user-supplied geometry specification to use for
the main Tk window.
-
.SH "SEE ALSO"
eval(n), tclsh(1), wish(1)
-
.SH KEYWORDS
arithmetic, bytecode, compiler, error, environment, POSIX, precision, subprocess, variables
diff --git a/doc/tell.n b/doc/tell.n
index 559f709..282cae5 100644
--- a/doc/tell.n
+++ b/doc/tell.n
@@ -17,21 +17,17 @@ tell \- Return current access position for an open channel
.SH DESCRIPTION
.PP
-.VS 8.1
Returns an integer string giving the current access position in
\fIchannelId\fR. This value returned is a byte offset that can be passed to
\fBseek\fR in order to set the channel to a particular position. Note
that this value is in terms of bytes, not characters like \fBread\fR.
-.VE 8.1
The value returned is -1 for channels that do not support
seeking.
.PP
-.VS
\fIChannelId\fR must be an identifier for an open channel such as a
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.
-.VE
.SH EXAMPLE
Read a line from a file channel only if it starts with \fBfoobar\fR:
.CS
diff --git a/doc/time.n b/doc/time.n
index 38ae49a..bdd0786 100644
--- a/doc/time.n
+++ b/doc/time.n
@@ -18,7 +18,7 @@ time \- Time the execution of a script
.SH DESCRIPTION
.PP
This command will call the Tcl interpreter \fIcount\fR
-times to evaluate \fIscript\fR (or once if \fIcount\fR isn't
+times to evaluate \fIscript\fR (or once if \fIcount\fR is not
specified). It will then return a string of the form
.CS
\fB503 microseconds per iteration\fR
diff --git a/doc/tm.n b/doc/tm.n
new file mode 100644
index 0000000..aef06dd
--- /dev/null
+++ b/doc/tm.n
@@ -0,0 +1,293 @@
+'\"
+'\" Copyright (c) 2004-2010 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+'\"
+'\" 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"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+tm \- Facilities for locating and loading of Tcl Modules
+.SH SYNOPSIS
+.nf
+\fB::tcl::tm::path add \fR?\fIpath\fR...?
+\fB::tcl::tm::path remove \fR?\fIpath\fR...?
+\fB::tcl::tm::path list\fR
+\fB::tcl::tm::roots \fR?\fIpath\fR...?
+.fi
+.BE
+.SH DESCRIPTION
+This document describes the facilities for locating and loading Tcl
+Modules (see \fBMODULE DEFINITION\fR for the definition of a Tcl Module).
+The following commands are supported:
+.TP
+\fB::tcl::tm::path add \fR?\fIpath\fR...?
+.
+The paths are added at the head to the list of module paths, in order
+of appearance. This means that the last argument ends up as the new
+head of the list.
+.RS
+.PP
+The command enforces the restriction that no path may be an ancestor
+directory of any other path on the list. If any of the new paths
+violates this restriction an error will be raised, before any of the
+paths have been added. In other words, if only one path argument
+violates the restriction then none will be added.
+.PP
+If a path is already present as is, no error will be raised and no
+action will be taken.
+.PP
+Paths are searched later in the order of their appearance in the
+list. As they are added to the front of the list they are searched in
+reverse order of addition. In other words, the paths added last are
+looked at first.
+.RE
+.TP
+\fB::tcl::tm::path remove \fR?\fIpath\fR...?
+.
+Removes the paths from the list of module paths. The command silently
+ignores all paths which are not on the list.
+.TP
+\fB::tcl::tm::path list\fR
+.
+Returns a list containing all registered module paths, in the order
+that they are searched for modules.
+.TP
+\fB::tcl::tm::roots \fR?\fIpath\fR...?
+.
+Similar to \fBpath add\fR, and layered on top of it. This command
+takes a list of paths, extends each with
+.QW "\fBtcl\fIX\fB/site-tcl\fR" ,
+and
+.QW "\fBtcl\fIX\fB/\fIX\fB.\fIy\fR" ,
+for major version \fIX\fR of the
+Tcl interpreter and minor version \fIy\fR less than or equal to the
+minor version of the interpreter, and adds the resulting set of paths
+to the list of paths to search.
+.RS
+.PP
+This command is used internally by the system to set up the
+system-specific default paths.
+.PP
+The command has been exposed to allow a build system to define
+additional root paths beyond those described by this document.
+.RE
+.SH "MODULE DEFINITION"
+A Tcl Module is a Tcl Package contained in a single file, and no other
+files required by it. This file has to be \fBsource\fRable. In other
+words, a Tcl Module is always imported via:
+.CS
+source module_file
+.CE
+.PP
+The \fBload\fR command is not directly used. This restriction is not
+an actual limitation, as some may believe.
+Ever since 8.4 the Tcl \fBsource\fR command reads only until the first
+^Z character. This allows us to combine an arbitrary Tcl script with
+arbitrary binary data into one file, where the script processes the
+attached data in any it chooses to fully import and activate the
+package.
+.PP
+The name of a module file has to match the regular expression:
+.CS
+([_[:alpha:]][:_[:alnum:]]*)-([[:digit:]].*)\e.tm
+.CE
+.PP
+The first capturing parentheses provides the name of the package, the
+second clause its version. In addition to matching the pattern, the
+extracted version number must not raise an error when used in the
+command:
+.CS
+package vcompare $version 0
+.CE
+.PP
+.SH "FINDING MODULES"
+The directory tree for storing Tcl modules is separate from other
+parts of the filesystem and independent of \fBauto_path\fR.
+.PP
+Tcl Modules are searched for in all directories listed in the result
+of the command \fB::tcl::tm::path list\fR.
+This is called the \fIModule path\fR. Neither the \fBauto_path\fR nor
+the \fBtcl_pkgPath\fR variables are used.
+All directories on the module path have to obey one restriction:
+.RS
+.PP
+For any two directories, neither is an ancestor directory of the
+other.
+.RE
+.PP
+This is required to avoid ambiguities in package naming. If for
+example the two directories
+.QW "\fIfoo/\fR"
+and
+.QW "\fIfoo/cool\fR"
+were on
+the path a package named \fBcool::ice\fR could be found via the
+names \fBcool::ice\fR or \fBice\fR, the latter potentially
+obscuring a package named \fBice\fR, unqualified.
+.PP
+Before the search is started, the name of the requested package is
+translated into a partial path, using the following algorithm:
+.RS
+.PP
+All occurrences of
+.QW "\fB::\fR"
+in the package name are replaced by
+the appropriate directory separator character for the platform we are
+on. On Unix, for example, this is
+.QW "\fB/\fR" .
+.RE
+.PP
+Example:
+.RS
+.PP
+The requested package is \fBencoding::base64\fR. The generated
+partial path is
+.QW "\fIencoding/base64\fR" .
+.RE
+.PP
+After this translation the package is looked for in all module paths,
+by combining them one-by-one, first to last with the partial path to
+form a complete search pattern. Note that the search algorithm rejects
+all files where the filename does not match the regular expression
+given in the section \fBMODULE DEFINITION\fR. For the remaining
+files \fIprovide scripts\fR are generated and added to the package
+ifneeded database.
+.PP
+The algorithm falls back to the previous unknown handler when none of
+the found module files satisfy the request. If the request was
+satisfied the fall-back is ignored.
+.PP
+Note that packages in module form have \fIno\fR control over the
+\fIindex\fR and \fIprovide script\fRs entered into the package
+database for them.
+For a module file \fBMF\fR the \fIindex script\fR is always:
+.CS
+package ifneeded \fBPNAME PVERSION\fR [list source \fBMF\fR]
+.CE
+and the \fIprovide script\fR embedded in the above is:
+.CS
+source \fBMF\fR
+.CE
+.PP
+Both package name \fBPNAME\fR and package version \fBPVERSION\fR are
+extracted from the filename \fBMF\fR according to the definition
+below:
+.CS
+\fBMF\fR = /module_path/\fBPNAME\(fm\fR-\fBPVERSION\fR.tm
+.CE
+.PP
+Where \fBPNAME\(fm\fR is the partial path of the module as defined in
+section \fBFINDING MODULES\fR, and translated into \fBPNAME\fR by
+changing all directory separators to
+.QW "\fB::\fR" ,
+and \fBmodule_path\fR is the path (from the list of paths to search)
+that we found the module file under.
+.PP
+Note also that we are here creating a connection between package names
+and paths. Tcl is case-sensitive when it comes to comparing package
+names, but there are filesystems which are not, like NTFS. Luckily
+these filesystems do store the case of the name, despite not using the
+information when comparing.
+.PP
+Given the above we allow the names for packages in Tcl modules to have
+mixed-case, but also require that there are no collisions when
+comparing names in a case-insensitive manner. In other words, if a
+package \fBFoo\fR is deployed in the form of a Tcl Module,
+packages like \fBfoo\fR, \fBfOo\fR, etc. are not allowed
+anymore.
+.SH "DEFAULT PATHS"
+The default list of paths on the module path is computed by a
+\fBtclsh\fR as follows, where \fIX\fR is the major version of the Tcl
+interpreter and \fIy\fR is less than or equal to the minor version of
+the Tcl interpreter.
+.PP
+All the default paths are added to the module path, even those paths
+which do not exist. Non-existent paths are filtered out during actual
+searches. This enables a user to create one of the paths searched when
+needed and all running applications will automatically pick up any
+modules placed in them.
+.PP
+The paths are added in the order as they are listed below, and for
+lists of paths defined by an environment variable in the order they
+are found in the variable.
+.SS "SYSTEM SPECIFIC PATHS"
+.TP
+\fBfile normalize [info library]/../tcl\fIX\fB/\fIX\fB.\fIy\fR
+.
+In other words, the interpreter will look into a directory specified
+by its major version and whose minor versions are less than or equal
+to the minor version of the interpreter.
+.RS
+.PP
+For example for Tcl 8.4 the paths searched are:
+.CS
+\fB[info library]/../tcl8/8.4\fR
+\fB[info library]/../tcl8/8.3\fR
+\fB[info library]/../tcl8/8.2\fR
+\fB[info library]/../tcl8/8.1\fR
+\fB[info library]/../tcl8/8.0\fR
+.CE
+.PP
+This definition assumes that a package defined for Tcl \fIX\fB.\fIy\fR
+can also be used by all interpreters which have the same major number
+\fIX\fR and a minor number greater than \fIy\fR.
+.RE
+.TP
+\fBfile normalize EXEC/tcl\fIX\fB/\fIX\fB.\fIy\fR
+.
+Where \fBEXEC\fR is \fBfile normalize [info nameofexecutable]/../lib\fR
+or \fBfile normalize [::tcl::pkgconfig get libdir,runtime]\fR
+.RS
+.PP
+This sets of paths is handled equivalently to the set coming before,
+except that it is anchored in \fBEXEC_PREFIX\fR.
+For a build with \fBPREFIX\fR = \fBEXEC_PREFIX\fR the two sets are
+identical.
+.RE
+.SS "SITE SPECIFIC PATHS"
+.TP
+\fBfile normalize [info library]/../tcl\fIX\fB/site-tcl\fR
+.
+Note that this is always a single entry because \fIX\fR is always a
+specific value (the current major version of Tcl).
+.SS "USER SPECIFIC PATHS"
+.TP
+\fB$::env(TCL\fIX\fB_\fIy\fB_TM_PATH)\fR
+.
+A list of paths, separated by either \fB:\fR (Unix) or \fB;\fR
+(Windows). This is user and site specific as this environment variable
+can be set not only by the user's profile, but by system configuration
+scripts as well.
+.TP
+\fB$::env(TCL\fIX\fB.\fIy\fB_TM_PATH)\fR
+.
+Same meaning and content as the previous variable. However the use of
+dot '.' to separate major and minor version number makes this name
+less to non-portable and its use is discouraged. Support of this
+variable has been kept only for backward compatibility with the
+original specification, i.e. TIP 189.
+.PP
+These paths are seen and therefore shared by all Tcl shells in the
+\fB$::env(PATH)\fR of the user.
+.PP
+Note that \fIX\fR and \fIy\fR follow the general rules set out
+above. In other words, Tcl 8.4, for example, will look at these 5
+environment variables:
+.CS
+\fB$::env(TCL8.4_TM_PATH)\fR \fB$::env(TCL8_4_TM_PATH)\fR
+\fB$::env(TCL8.3_TM_PATH)\fR \fB$::env(TCL8_3_TM_PATH)\fR
+\fB$::env(TCL8.2_TM_PATH)\fR \fB$::env(TCL8_2_TM_PATH)\fR
+\fB$::env(TCL8.1_TM_PATH)\fR \fB$::env(TCL8_1_TM_PATH)\fR
+\fB$::env(TCL8.0_TM_PATH)\fR \fB$::env(TCL8_0_TM_PATH)\fR
+.CE
+.SH "SEE ALSO"
+package(n), Tcl Improvement Proposal #189
+.QW "\fITcl Modules\fR"
+(online at http://tip.tcl.tk/189.html), Tcl Improvement Proposal #190
+.QW "\fIImplementation Choices for Tcl Modules\fR"
+(online at http://tip.tcl.tk/190.html)
+.SH "KEYWORDS"
+modules, package
diff --git a/doc/trace.n b/doc/trace.n
index 552b269..9d40123 100644
--- a/doc/trace.n
+++ b/doc/trace.n
@@ -15,52 +15,57 @@ trace \- Monitor variable accesses, command usages and command executions
.SH SYNOPSIS
\fBtrace \fIoption\fR ?\fIarg arg ...\fR?
.BE
-
.SH DESCRIPTION
.PP
This command causes Tcl commands to be executed whenever certain operations are
-invoked. The legal \fIoption\fR's (which may be abbreviated) are:
+invoked. The legal \fIoption\fRs (which may be abbreviated) are:
.TP
\fBtrace add \fItype name ops ?args?\fR
Where \fItype\fR is \fBcommand\fR, \fBexecution\fR, or \fBvariable\fR.
.RS
.TP
-\fBtrace add command\fR \fIname ops command\fR
-Arrange for \fIcommand\fR to be executed whenever command \fIname\fR
-is modified in one of the ways given by the list \fIops\fR. \fIName\fR will be
-resolved using the usual namespace resolution rules used by
-procedures. If the command does not exist, an error will be thrown.
+\fBtrace add command\fR \fIname ops commandPrefix\fR
+.
+Arrange for \fIcommandPrefix\fR to be executed (with additional arguments)
+whenever command \fIname\fR is modified in one of the ways given by the list
+\fIops\fR. \fIName\fR will be resolved using the usual namespace resolution
+rules used by commands. If the command does not exist, an error will be
+thrown.
.RS
.PP
\fIOps\fR indicates which operations are of interest, and is a list of
one or more of the following items:
.TP
\fBrename\fR
-Invoke \fIcommand\fR whenever the command is renamed. Note that
-renaming to the empty string is considered deletion, and will not
-be traced with '\fBrename\fR'.
+.
+Invoke \fIcommandPrefix\fR whenever the traced command is renamed. Note that
+renaming to the empty string is considered deletion, and will not be traced
+with
+.QW \fBrename\fR .
.TP
\fBdelete\fR
-Invoke \fIcommand\fR when the command is deleted. Commands can be
-deleted explicitly by using the \fBrename\fR command to rename the
-command to an empty string. Commands are also deleted when the
-interpreter is deleted, but traces will not be invoked because there is no
-interpreter in which to execute them.
+.
+Invoke \fIcommandPrefix\fR when the traced command is deleted. Commands can be
+deleted explicitly by using the \fBrename\fR command to rename the command to
+an empty string. Commands are also deleted when the interpreter is deleted,
+but traces will not be invoked because there is no interpreter in which to
+execute them.
.PP
-When the trace triggers, depending on the operations being traced, a
-number of arguments are appended to \fIcommand\fR so that the actual
-command is as follows:
+When the trace triggers, depending on the operations being traced, a number of
+arguments are appended to \fIcommandPrefix\fR so that the actual command is as
+follows:
.CS
-\fIcommand oldName newName op\fR
+\fIcommandPrefix oldName newName op\fR
.CE
-\fIOldName\fR and \fInewName\fR give the traced command's current
-(old) name, and the name to which it is being renamed (the empty
-string if this is a 'delete' operation).
+\fIOldName\fR and \fInewName\fR give the traced command's current (old) name,
+and the name to which it is being renamed (the empty string if this is a
+.QW delete
+operation).
\fIOp\fR indicates what operation is being performed on the
command, and is one of \fBrename\fR or \fBdelete\fR as
defined above. The trace operation cannot be used to stop a command
from being deleted. Tcl will always remove the command once the trace
-is complete. Recursive renaming or deleting will not cause further traces
+is complete. Recursive renaming or deleting will not cause further traces
of the same type to be evaluated, so a delete trace which itself
deletes the command, or a rename trace which itself renames the
command will not cause further trace evaluations to occur.
@@ -68,90 +73,100 @@ Both \fIoldName\fR and \fInewName\fR are fully qualified with any namespace(s)
in which they appear.
.RE
.TP
-\fBtrace add execution\fR \fIname ops command\fR
-Arrange for \fIcommand\fR to be executed whenever command \fIname\fR
-is executed, with traces occurring at the points indicated by the list
-\fIops\fR. \fIName\fR will be
-resolved using the usual namespace resolution rules used by
-procedures. If the command does not exist, an error will be thrown.
+\fBtrace add execution\fR \fIname ops commandPrefix\fR
+.
+Arrange for \fIcommandPrefix\fR to be executed (with additional arguments)
+whenever command \fIname\fR is executed, with traces occurring at the points
+indicated by the list \fIops\fR. \fIName\fR will be resolved using the usual
+namespace resolution rules used by commands. If the command does not exist,
+an error will be thrown.
.RS
.PP
\fIOps\fR indicates which operations are of interest, and is a list of
one or more of the following items:
.TP
\fBenter\fR
-Invoke \fIcommand\fR whenever the command \fIname\fR is executed,
+Invoke \fIcommandPrefix\fR whenever the command \fIname\fR is executed,
just before the actual execution takes place.
.TP
\fBleave\fR
-Invoke \fIcommand\fR whenever the command \fIname\fR is executed,
+Invoke \fIcommandPrefix\fR whenever the command \fIname\fR is executed,
just after the actual execution takes place.
.TP
\fBenterstep\fR
-Invoke \fIcommand\fR for every Tcl command which is executed
-inside the procedure \fIname\fR, just before the actual execution
-takes place. For example if we have 'proc foo {} { puts "hello" }',
-then an \fIenterstep\fR trace would be
-invoked just before \fIputs "hello"\fR is executed.
-Setting an \fIenterstep\fR trace on a \fIcommand\fR
-will not result in an error and is simply ignored.
+.
+Invoke \fIcommandPrefix\fR for every Tcl command which is executed from the
+start of the execution of the procedure \fIname\fR until that
+procedure finishes. \fICommandPrefix\fR is invoked just before the actual
+execution of the Tcl command being reported takes place. For example
+if we have
+.QW "proc foo {} { puts \N'34'hello\N'34' }" ,
+then an \fIenterstep\fR trace would be invoked just before
+.QW "\fIputs \N'34'hello\N'34'\fR"
+is executed.
+Setting an \fIenterstep\fR trace on a command \fIname\fR that does not refer
+to a procedure will not result in an error and is simply ignored.
.TP
\fBleavestep\fR
-Invoke \fIcommand\fR for every Tcl command which is executed
-inside the procedure \fIname\fR, just after the actual execution
-takes place.
-Setting a \fIleavestep\fR trace on a \fIcommand\fR
-will not result in an error and is simply ignored.
+.
+Invoke \fIcommandPrefix\fR for every Tcl command which is executed from the
+start of the execution of the procedure \fIname\fR until that
+procedure finishes. \fICommandPrefix\fR is invoked just after the actual
+execution of the Tcl command being reported takes place.
+Setting a \fIleavestep\fR trace on a command \fIname\fR that does not refer to
+a procedure will not result in an error and is simply ignored.
.PP
-When the trace triggers, depending on the operations being traced, a
-number of arguments are appended to \fIcommand\fR so that the actual
+When the trace triggers, depending on the operations being traced, a
+number of arguments are appended to \fIcommandPrefix\fR so that the actual
command is as follows:
.PP
For \fBenter\fR and \fBenterstep\fR operations:
.CS
-\fIcommand command-string op\fR
+\fIcommandPrefix command-string op\fR
.CE
-\fICommand-string\fR gives the complete current command being
-executed (the traced command for a \fBenter\fR operation, an
+\fICommand-string\fR gives the complete current command being
+executed (the traced command for a \fBenter\fR operation, an
arbitrary command for a \fBenterstep\fR operation), including
all arguments in their fully expanded form.
\fIOp\fR indicates what operation is being performed on the
command execution, and is one of \fBenter\fR or \fBenterstep\fR as
defined above. The trace operation can be used to stop the
command from executing, by deleting the command in question. Of
-course when the command is subsequently executed, an 'invalid command'
+course when the command is subsequently executed, an
+.QW "invalid command"
error will occur.
.PP
For \fBleave\fR and \fBleavestep\fR operations:
.CS
\fIcommand command-string code result op\fR
.CE
-\fICommand-string\fR gives the complete current command being
-executed (the traced command for a \fBenter\fR operation, an
+\fICommand-string\fR gives the complete current command being
+executed (the traced command for a \fBenter\fR operation, an
arbitrary command for a \fBenterstep\fR operation), including
all arguments in their fully expanded form.
\fICode\fR gives the result code of that execution, and \fIresult\fR
the result string.
\fIOp\fR indicates what operation is being performed on the
command execution, and is one of \fBleave\fR or \fBleavestep\fR as
-defined above.
+defined above.
Note that the creation of many \fBenterstep\fR or
\fBleavestep\fR traces can lead to unintuitive results, since the
invoked commands from one trace can themselves lead to further
command invocations for other traces.
.PP
-\fICommand\fR executes in the same context as the code that invoked
-the traced operation: thus the \fIcommand\fR, if invoked from a procedure,
-will have access to the same local variables as code in the procedure.
-This context may be different than the context in which the trace was
-created. If \fIcommand\fR invokes a procedure (which it normally does)
-then the procedure will have to use upvar or uplevel commands if it wishes
-to access the local variables of the code which invoked the trace operation.
+\fICommandPrefix\fR executes in the same context as the code that invoked
+the traced operation: thus the \fIcommandPrefix\fR, if invoked from a
+procedure, will have access to the same local variables as code in the
+procedure. This context may be different than the context in which the trace
+was created. If \fIcommandPrefix\fR invokes a procedure (which it normally
+does) then the procedure will have to use \fBupvar\fR or \fBuplevel\fR
+commands if it wishes to access the local variables of the code which invoked
+the trace operation.
.PP
-While \fIcommand\fR is executing during an execution trace, traces
-on \fIname\fR are temporarily disabled. This allows the \fIcommand\fR
+While \fIcommandPrefix\fR is executing during an execution trace, traces
+on \fIname\fR are temporarily disabled. This allows the \fIcommandPrefix\fR
to execute \fIname\fR in its body without invoking any other traces again.
-If an error occurs while executing the \fIcommand\fR body, then the
+If an error occurs while executing the \fIcommandPrefix\fR, then the
command \fIname\fR as a whole will return that same error.
.PP
When multiple traces are set on \fIname\fR, then for \fIenter\fR
@@ -160,17 +175,17 @@ in the reverse order of how the traces were originally created;
and for \fIleave\fR and \fIleavestep\fR operations, the traced
commands are invoked in the original order of creation.
.PP
-The behavior of execution traces is currently undefined for a command
+The behavior of execution traces is currently undefined for a command
\fIname\fR imported into another namespace.
.RE
.TP
-\fBtrace add variable\fI name ops command\fR
-Arrange for \fIcommand\fR to be executed whenever variable \fIname\fR
+\fBtrace add variable\fI name ops commandPrefix\fR
+Arrange for \fIcommandPrefix\fR to be executed whenever variable \fIname\fR
is accessed in one of the ways given by the list \fIops\fR. \fIName\fR may
refer to a normal variable, an element of an array, or to an array
as a whole (i.e. \fIname\fR may be just the name of an array, with no
parenthesized index). If \fIname\fR refers to a whole array, then
-\fIcommand\fR is invoked whenever any element of the array is
+\fIcommandPrefix\fR is invoked whenever any element of the array is
manipulated. If the variable does not exist, it will be created but
will not be given a value, so it will be visible to \fBnamespace which\fR
queries, but not to \fBinfo exists\fR queries.
@@ -180,20 +195,20 @@ queries, but not to \fBinfo exists\fR queries.
one or more of the following items:
.TP
\fBarray\fR
-Invoke \fIcommand\fR whenever the variable is accessed or modified via
+Invoke \fIcommandPrefix\fR whenever the variable is accessed or modified via
the \fBarray\fR command, provided that \fIname\fR is not a scalar
variable at the time that the \fBarray\fR command is invoked. If
\fIname\fR is a scalar variable, the access via the \fBarray\fR
command will not trigger the trace.
.TP
\fBread\fR
-Invoke \fIcommand\fR whenever the variable is read.
+Invoke \fIcommandPrefix\fR whenever the variable is read.
.TP
\fBwrite\fR
-Invoke \fIcommand\fR whenever the variable is written.
+Invoke \fIcommandPrefix\fR whenever the variable is written.
.TP
\fBunset\fR
-Invoke \fIcommand\fR whenever the variable is unset. Variables
+Invoke \fIcommandPrefix\fR whenever the variable is unset. Variables
can be unset explicitly with the \fBunset\fR command, or
implicitly when procedures return (all of their local variables
are unset). Variables are also unset when interpreters are
@@ -201,9 +216,9 @@ deleted, but traces will not be invoked because there is no
interpreter in which to execute them.
.PP
When the trace triggers, three arguments are appended to
-\fIcommand\fR so that the actual command is as follows:
+\fIcommandPrefix\fR so that the actual command is as follows:
.CS
-\fIcommand name1 name2 op\fR
+\fIcommandPrefix name1 name2 op\fR
.CE
\fIName1\fR and \fIname2\fR give the name(s) for the variable
being accessed: if the variable is a scalar then \fIname1\fR
@@ -221,11 +236,11 @@ different name.
variable, and is one of \fBread\fR, \fBwrite\fR, or \fBunset\fR as
defined above.
.PP
-\fICommand\fR executes in the same context as the code that invoked
+\fICommandPrefix\fR executes in the same context as the code that invoked
the traced operation: if the variable was accessed as part of a Tcl
-procedure, then \fIcommand\fR will have access to the same local
+procedure, then \fIcommandPrefix\fR will have access to the same local
variables as code in the procedure. This context may be different
-than the context in which the trace was created. If \fIcommand\fR
+than the context in which the trace was created. If \fIcommandPrefix\fR
invokes a procedure (which it normally does) then the procedure will
have to use \fBupvar\fR or \fBuplevel\fR if it wishes to access the
traced variable. Note also that \fIname1\fR may not necessarily be
@@ -233,25 +248,25 @@ the same as the name used to set the trace on the variable;
differences can occur if the access is made through a variable defined
with the \fBupvar\fR command.
.PP
-For read and write traces, \fIcommand\fR can modify the variable to
-affect the result of the traced operation. If \fIcommand\fR modifies
+For read and write traces, \fIcommandPrefix\fR can modify the variable to
+affect the result of the traced operation. If \fIcommandPrefix\fR modifies
the value of a variable during a read or write trace, then the new
value will be returned as the result of the traced operation. The
-return value from \fIcommand\fR is ignored except that if it returns
+return value from \fIcommandPrefix\fR is ignored except that if it returns
an error of any sort then the traced operation also returns an error
with the same error message returned by the trace command (this
mechanism can be used to implement read-only variables, for example).
-For write traces, \fIcommand\fR is invoked after the variable's value
+For write traces, \fIcommandPrefix\fR is invoked after the variable's value
has been changed; it can write a new value into the variable to
override the original value specified in the write operation. To
-implement read-only variables, \fIcommand\fR will have to restore the
+implement read-only variables, \fIcommandPrefix\fR will have to restore the
old value of the variable.
.PP
-While \fIcommand\fR is executing during a read or write trace, traces
+While \fIcommandPrefix\fR is executing during a read or write trace, traces
on the variable are temporarily disabled. This means that reads and
-writes invoked by \fIcommand\fR will occur directly, without invoking
-\fIcommand\fR (or any other traces) again. However, if \fIcommand\fR
-unsets the variable then unset traces will be invoked.
+writes invoked by \fIcommandPrefix\fR will occur directly, without invoking
+\fIcommandPrefix\fR (or any other traces) again. However, if
+\fIcommandPrefix\fR unsets the variable then unset traces will be invoked.
.PP
When an unset trace is invoked, the variable has already been deleted:
it will appear to be undefined with no traces. If an unset occurs
@@ -279,28 +294,28 @@ This command returns an empty string.
.RE
.RE
.TP
-\fBtrace remove \fItype name opList command\fR
+\fBtrace remove \fItype name opList commandPrefix\fR
Where \fItype\fR is either \fBcommand\fR, \fBexecution\fR or \fBvariable\fR.
.RS
.TP
-\fBtrace remove command\fI name opList command\fR
+\fBtrace remove command\fI name opList commandPrefix\fR
If there is a trace set on command \fIname\fR with the operations and
-command given by \fIopList\fR and \fIcommand\fR, then the trace is
-removed, so that \fIcommand\fR will never again be invoked. Returns
-an empty string. If \fIname\fR doesn't exist, the command will throw
+command given by \fIopList\fR and \fIcommandPrefix\fR, then the trace is
+removed, so that \fIcommandPrefix\fR will never again be invoked. Returns
+an empty string. If \fIname\fR does not exist, the command will throw
an error.
.TP
-\fBtrace remove execution\fI name opList command\fR
+\fBtrace remove execution\fI name opList commandPrefix\fR
If there is a trace set on command \fIname\fR with the operations and
-command given by \fIopList\fR and \fIcommand\fR, then the trace is
-removed, so that \fIcommand\fR will never again be invoked. Returns
-an empty string. If \fIname\fR doesn't exist, the command will throw
+command given by \fIopList\fR and \fIcommandPrefix\fR, then the trace is
+removed, so that \fIcommandPrefix\fR will never again be invoked. Returns
+an empty string. If \fIname\fR does not exist, the command will throw
an error.
.TP
-\fBtrace remove variable\fI name opList command\fR
+\fBtrace remove variable\fI name opList commandPrefix\fR
If there is a trace set on variable \fIname\fR with the operations and
-command given by \fIopList\fR and \fIcommand\fR, then the trace is
-removed, so that \fIcommand\fR will never again be invoked. Returns
+command given by \fIopList\fR and \fIcommandPrefix\fR, then the trace is
+removed, so that \fIcommandPrefix\fR will never again be invoked. Returns
an empty string.
.RE
.TP
@@ -311,24 +326,24 @@ Where \fItype\fR is either \fBcommand\fR, \fBexecution\fR or \fBvariable\fR.
\fBtrace info command\fI name\fR
Returns a list containing one element for each trace currently set on
command \fIname\fR. Each element of the list is itself a list
-containing two elements, which are the \fIopList\fR and \fIcommand\fR
-associated with the trace. If \fIname\fR doesn't have any traces set,
+containing two elements, which are the \fIopList\fR and \fIcommandPrefix\fR
+associated with the trace. If \fIname\fR does not have any traces set,
then the result of the command will be an empty string. If \fIname\fR
-doesn't exist, the command will throw an error.
+does not exist, the command will throw an error.
.TP
\fBtrace info execution\fI name\fR
Returns a list containing one element for each trace currently set on
command \fIname\fR. Each element of the list is itself a list
-containing two elements, which are the \fIopList\fR and \fIcommand\fR
-associated with the trace. If \fIname\fR doesn't have any traces set,
+containing two elements, which are the \fIopList\fR and \fIcommandPrefix\fR
+associated with the trace. If \fIname\fR does not have any traces set,
then the result of the command will be an empty string. If \fIname\fR
-doesn't exist, the command will throw an error.
+does not exist, the command will throw an error.
.TP
\fBtrace info variable\fI name\fR
Returns a list containing one element for each trace currently set on
variable \fIname\fR. Each element of the list is itself a list
-containing two elements, which are the \fIopList\fR and \fIcommand\fR
-associated with the trace. If \fIname\fR doesn't exist or doesn't
+containing two elements, which are the \fIopList\fR and \fIcommandPrefix\fR
+associated with the trace. If \fIname\fR does not exist or does not
have any traces set, then the result of the command will be an empty
string.
.RE
@@ -341,8 +356,8 @@ This is equivalent to \fBtrace add variable \fIname ops command\fR.
.TP
\fBtrace vdelete \fIname ops command\fR
This is equivalent to \fBtrace remove variable \fIname ops command\fR
-.TP
-\fBtrace vinfo \fIname\fR
+.TP
+\fBtrace vinfo \fIname\fR
This is equivalent to \fBtrace info variable \fIname\fR
.RE
.PP
@@ -375,9 +390,22 @@ proc doMult args {
\fBtrace add\fR variable foo write doMult
\fBtrace add\fR variable bar write doMult
.CE
-
+.PP
+Print a trace of what commands are executed during the processing of a Tcl
+procedure:
+.CS
+proc x {} { y }
+proc y {} { z }
+proc z {} { puts hello }
+proc report args {puts [info level 0]}
+\fBtrace add\fR execution x enterstep report
+x
+ \(-> \fIreport y enterstep\fR
+ \fIreport z enterstep\fR
+ \fIreport {puts hello} enterstep\fR
+ \fIhello\fR
+.CE
.SH "SEE ALSO"
set(n), unset(n)
-
.SH KEYWORDS
read, command, rename, variable, write, trace, unset
diff --git a/doc/unknown.n b/doc/unknown.n
index a5cbe6f..c258daa 100644
--- a/doc/unknown.n
+++ b/doc/unknown.n
@@ -14,22 +14,24 @@ unknown \- Handle attempts to use non-existent commands
.SH SYNOPSIS
\fBunknown \fIcmdName \fR?\fIarg arg ...\fR?
.BE
-
.SH DESCRIPTION
.PP
This command is invoked by the Tcl interpreter whenever a script
-tries to invoke a command that doesn't exist. The default implementation
+tries to invoke a command that does not exist. The default implementation
of \fBunknown\fR is a library procedure defined when Tcl initializes an
interpreter. You can override the default \fBunknown\fR to change its
-functionality. Note that there is no default implementation of
-\fBunknown\fR in a safe interpreter.
+functionality, or you can register a new handler for individual namespaces
+using the \fBnamespace unknown\fR command. Note that there is no default
+implementation of \fBunknown\fR in a safe interpreter.
.PP
If the Tcl interpreter encounters a command name for which there
-is not a defined command, then Tcl checks for the existence of
-a command named \fBunknown\fR.
-If there is no such command, then the interpreter returns an
-error.
-If the \fBunknown\fR command exists, then it is invoked with
+is not a defined command (in either the current namespace, or the
+global namespace), then Tcl checks for the existence of
+an unknown handler for the current namespace. By default, this
+handler is a command named \fB::unknown\fR. If there is no such
+command, then the interpreter returns an error.
+If the \fBunknown\fR command exists (or a new handler has been
+registered for the current namespace), then it is invoked with
arguments consisting of the fully-substituted name and arguments
for the original non-existent command.
The \fBunknown\fR command typically does things like searching
@@ -49,7 +51,7 @@ If the auto-load fails then \fBunknown\fR calls \fBauto_execok\fR
to see if there is an executable file by the name \fIcmd\fR.
If so, it invokes the Tcl \fBexec\fR command
with \fIcmd\fR and all the \fIargs\fR as arguments.
-If \fIcmd\fR can't be auto-executed, \fBunknown\fR checks to
+If \fIcmd\fR cannot be auto-executed, \fBunknown\fR checks to
see if the command was invoked at top-level and outside of any
script. If so, then \fBunknown\fR takes two additional steps.
First, it sees if \fIcmd\fR has one of the following three forms:
@@ -80,12 +82,10 @@ rename \fBunknown\fR _original_unknown
# Provide our own implementation
proc \fBunknown\fR args {
puts stderr "WARNING: unknown command: $args"
- uplevel 1 [list _original_unknown {expand}$args]
+ uplevel 1 [list _original_unknown {*}$args]
}
.CE
-
.SH "SEE ALSO"
-info(n), proc(n), interp(n), library(n)
-
+info(n), proc(n), interp(n), library(n), namespace(n)
.SH KEYWORDS
error, non-existent command
diff --git a/doc/unload.n b/doc/unload.n
new file mode 100644
index 0000000..f060cd6
--- /dev/null
+++ b/doc/unload.n
@@ -0,0 +1,162 @@
+'\"
+'\" Copyright (c) 2003 George Petasis <petasis@iit.demokritos.gr>.
+'\"
+'\" 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"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+unload \- Unload machine code
+.SH SYNOPSIS
+\fBunload \fR?\fIswitches\fR? \fIfileName\fR
+.br
+\fBunload \fR?\fIswitches\fR? \fIfileName packageName\fR
+.br
+\fBunload \fR?\fIswitches\fR? \fIfileName packageName interp\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command tries to unload shared libraries previously loaded
+with \fBload\fR from the application's address space. \fIfileName\fR
+is the name of the file containing the library file to be unload; it
+must be the same as the filename provided to \fBload\fR for
+loading the library.
+The \fIpackageName\fR argument is the name of the package (as
+determined by or passed to \fBload\fR), and is used to
+compute the name of the unload procedure; if not supplied, it is
+computed from \fIfileName\fR in the same manner as \fBload\fR.
+The \fIinterp\fR argument is the path name of the interpreter from
+which to unload the package (see the \fBinterp\fR manual entry for
+details); if \fIinterp\fR is omitted, it defaults to the
+interpreter in which the \fBunload\fR command was invoked.
+.PP
+If the initial arguments to \fBunload\fR start with \fB\-\fR then
+they are treated as switches. The following switches are
+currently supported:
+.TP
+\fB\-nocomplain\fR
+.
+Suppresses all error messages. If this switch is given, \fBunload\fR will
+never report an error.
+.TP
+\fB\-keeplibrary\fR
+.
+This switch will prevent \fBunload\fR from issuing the operating system call
+that will unload the library from the process.
+.TP
+\fB\-\|\-\fR
+.
+Marks the end of switches. The argument following this one will
+be treated as a \fIfileName\fR even if it starts with a \fB\-\fR.
+.SS "UNLOAD OPERATION"
+.PP
+When a file containing a shared library is loaded through the
+\fBload\fR command, Tcl associates two reference counts to the library
+file. The first counter shows how many times the library has been
+loaded into normal (trusted) interpreters while the second describes how many
+times the library has been loaded into safe interpreters. As a file containing
+a shared library can be loaded only once by Tcl (with the first \fBload\fR
+call on the file), these counters track how many interpreters use the library.
+Each subsequent call to \fBload\fR after the first simply increments the
+proper reference count.
+.PP
+\fBunload\fR works in the opposite direction. As a first step, \fBunload\fR
+will check whether the library is unloadable: an unloadable library exports
+a special unload procedure. The name of the unload procedure is determined by
+\fIpackageName\fR and whether or not the target interpreter
+is a safe one. For normal interpreters the name of the initialization
+procedure will have the form \fIpkg\fB_Unload\fR, where \fIpkg\fR
+is the same as \fIpackageName\fR except that the first letter is
+converted to upper case and all other letters
+are converted to lower case. For example, if \fIpackageName\fR is
+\fBfoo\fR or \fBFOo\fR, the initialization procedure's name will
+be \fBFoo_Unload\fR.
+If the target interpreter is a safe interpreter, then the name
+of the initialization procedure will be \fIpkg\fB_SafeUnload\fR
+instead of \fIpkg\fB_Unload\fR.
+.PP
+If \fBunload\fR determines that a library is not unloadable (or unload
+functionality has been disabled during compilation), an error will be returned.
+If the library is unloadable, then \fBunload\fR will call the unload
+procedure. If the unload procedure returns \fBTCL_OK\fR, \fBunload\fR will proceed
+and decrease the proper reference count (depending on the target interpreter
+type). When both reference counts have reached 0, the library will be
+detached from the process.
+.SS "UNLOAD HOOK PROTOTYPE"
+.PP
+The unload procedure must match the following prototype:
+.CS
+typedef int Tcl_PackageUnloadProc(Tcl_Interp *\fIinterp\fR, int \fIflags\fR);
+.CE
+.PP
+The \fIinterp\fR argument identifies the interpreter from which the
+library is to be unloaded. The unload procedure must return
+\fBTCL_OK\fR or \fBTCL_ERROR\fR to indicate whether or not it completed
+successfully; in the event of an error it should set the interpreter's result
+to point to an error message. In this case, the result of the
+\fBunload\fR command will be the result returned by the unload procedure.
+.PP
+The \fIflags\fR argument can be either \fBTCL_UNLOAD_DETACH_FROM_INTERPRETER\fR
+or \fBTCL_UNLOAD_DETACH_FROM_PROCESS\fR. In case the library will remain
+attached to the process after the unload procedure returns (i.e. because
+the library is used by other interpreters),
+\fBTCL_UNLOAD_DETACH_FROM_INTERPRETER\fR will be defined. However, if the
+library is used only by the target interpreter and the library will be
+detached from the application as soon as the unload procedure returns,
+the \fIflags\fR argument will be set to \fBTCL_UNLOAD_DETACH_FROM_PROCESS\fR.
+.SS NOTES
+.PP
+The \fBunload\fR command cannot unload libraries that are statically
+linked with the application.
+If \fIfileName\fR is an empty string, then the \fIpackageName\fR argument must
+be specified.
+.PP
+If \fIpackageName\fR is omitted or specified as an empty string,
+Tcl tries to guess the name of the package.
+This may be done differently on different platforms.
+The default guess, which is used on most UNIX platforms, is to
+take the last element of \fIfileName\fR, strip off the first
+three characters if they are \fBlib\fR, and use any following
+alphabetic and underline characters as the module name.
+For example, the command \fBunload libxyz4.2.so\fR uses the module
+name \fBxyz\fR and the command \fBunload bin/last.so {}\fR uses the
+module name \fBlast\fR.
+.SH "PORTABILITY ISSUES"
+.TP
+\fBUnix\fR\0\0\0\0\0
+.
+Not all unix operating systems support library unloading. Under such
+an operating system \fBunload\fR returns an error (unless \fB\-nocomplain\fR
+has been specified).
+.SH BUGS
+.PP
+If the same file is \fBload\fRed by different \fIfileName\fRs, it will
+be loaded into the process's address space multiple times. The
+behavior of this varies from system to system (some systems may
+detect the redundant loads, others may not). In case a library has been
+silently detached by the operating system (and as a result Tcl thinks the
+library is still loaded), it may be dangerous to use
+\fBunload\fR on such a library (as the library will be completely detached
+from the application while some interpreters will continue to use it).
+.SH EXAMPLE
+If an unloadable module in the file \fBfoobar.dll\fR had been loaded
+using the \fBload\fR command like this (on Windows):
+.CS
+load c:/some/dir/foobar.dll
+.CE
+then it would be unloaded like this:
+.CS
+\fBunload\fR c:/some/dir/foobar.dll
+.CE
+.PP
+This allows a C code module to be installed temporarily into a
+long-running Tcl program and then removed again (either because it is
+no longer needed or because it is being updated with a new version)
+without having to shut down the overall Tcl process.
+.SH "SEE ALSO"
+info sharedlibextension, load(n), safe(n)
+.SH KEYWORDS
+binary code, unloading, safe interpreter, shared library
diff --git a/doc/unset.n b/doc/unset.n
index 2bde1e2..29d7e7c 100644
--- a/doc/unset.n
+++ b/doc/unset.n
@@ -15,7 +15,6 @@ unset \- Delete variables
.SH SYNOPSIS
\fBunset \fR?\fI\-nocomplain\fR? ?\fI\-\-\fR? ?\fIname name name ...\fR?
.BE
-
.SH DESCRIPTION
.PP
This command removes one or more variables.
@@ -26,16 +25,14 @@ element is removed without affecting the rest of the array.
If a \fIname\fR consists of an array name with no parenthesized
index, then the entire array is deleted.
The \fBunset\fR command returns an empty string as result.
-.VS 8.4
If \fI\-nocomplain\fR is specified as the first argument, any possible
errors are suppressed. The option may not be abbreviated, in order to
disambiguate it from possible variable names. The option \fI\-\-\fR
indicates the end of the options, and should be used if you wish to
remove a variable with the same name as any of the options.
-.VE 8.4
If an error occurs, any variables after the named one causing the error
are not
-deleted. An error can occur when the named variable doesn't exist, or the
+deleted. An error can occur when the named variable does not exist, or the
name refers to an array element but the variable is a scalar, or the name
refers to a variable in a non-existent namespace.
.SH EXAMPLE
@@ -59,9 +56,7 @@ parray squares
puts "The prime squares are:"
parray squares
.CE
-
.SH "SEE ALSO"
set(n), trace(n), upvar(n)
-
.SH KEYWORDS
remove, variable
diff --git a/doc/update.n b/doc/update.n
index 41a50f8..555766c 100644
--- a/doc/update.n
+++ b/doc/update.n
@@ -17,7 +17,8 @@ update \- Process pending events and idle callbacks
.SH DESCRIPTION
.PP
-This command is used to bring the application ``up to date''
+This command is used to bring the application
+.QW "up to date"
by entering the event loop repeatedly until all pending events
(including idle callbacks) have been processed.
.PP
@@ -59,7 +60,7 @@ while {!$done} {
.CE
.SH "SEE ALSO"
-after(n), bgerror(n)
+after(n), interp(n)
.SH KEYWORDS
event, flush, handler, idle, update
diff --git a/doc/uplevel.n b/doc/uplevel.n
index d34716c..c8ef0ff 100644
--- a/doc/uplevel.n
+++ b/doc/uplevel.n
@@ -14,7 +14,6 @@ uplevel \- Execute a script in a different stack frame
.SH SYNOPSIS
\fBuplevel \fR?\fIlevel\fR?\fI arg \fR?\fIarg ...\fR?
.BE
-
.SH DESCRIPTION
.PP
All of the \fIarg\fR arguments are concatenated as if they had
@@ -53,16 +52,16 @@ the command
.CE
then the \fBset\fR command will modify the same variable \fBx\fR in \fBb\fR's
context: the procedure \fBc\fR does not appear to be on the call stack
-when \fBd\fR is executing. The command ``\fBinfo level\fR'' may
+when \fBd\fR is executing. The \fBinfo level\fR command may
be used to obtain the level of the current procedure.
.PP
\fBUplevel\fR makes it possible to implement new control
constructs as Tcl procedures (for example, \fBuplevel\fR could
be used to implement the \fBwhile\fR construct as a Tcl procedure).
.PP
-\fBnamespace eval\fR is another way (besides procedure calls)
-that the Tcl naming context can change.
-It adds a call frame to the stack to represent the namespace context.
+The \fBnamespace eval\fR and \fBapply\fR commands offer other ways
+(besides procedure calls) that the Tcl naming context can change.
+They add a call frame to the stack to represent the namespace context.
This means each \fBnamespace eval\fR command
counts as another call level for \fBuplevel\fR and \fBupvar\fR commands.
For example, \fBinfo level 1\fR will return a list
@@ -90,9 +89,7 @@ proc do {body while condition} {
}
}
.CE
-
.SH "SEE ALSO"
-namespace(n), upvar(n)
-
+apply(n), namespace(n), upvar(n)
.SH KEYWORDS
context, level, namespace, stack frame, variables
diff --git a/doc/upvar.n b/doc/upvar.n
index 03f4cd9..a255485 100644
--- a/doc/upvar.n
+++ b/doc/upvar.n
@@ -22,7 +22,7 @@ procedure to refer to variables in an enclosing procedure call or
to global variables.
\fILevel\fR may have any of the forms permitted for the \fBuplevel\fR
command, and may be omitted if the first letter of the first \fIotherVar\fR
-isn't \fB#\fR or a digit (it defaults to \fB1\fR).
+is not \fB#\fR or a digit (it defaults to \fB1\fR).
For each \fIotherVar\fR argument, \fBupvar\fR makes the variable
by that name in the procedure frame given by \fIlevel\fR (or at
global level, if \fIlevel\fR is \fB#0\fR) accessible
@@ -33,8 +33,8 @@ call; it will be created the first time \fImyVar\fR is referenced, just like
an ordinary variable. There must not exist a variable by the
name \fImyVar\fR at the time \fBupvar\fR is invoked.
\fIMyVar\fR is always treated as the name of a variable, not an
-array element. Even if the name looks like an array element,
-such as \fBa(b)\fR, a regular variable is created.
+array element. An error is returned if the name looks like an array element,
+such as \fBa(b)\fR.
\fIOtherVar\fR may refer to a scalar variable, an array,
or an array element.
\fBUpvar\fR returns an empty string.
@@ -44,14 +44,14 @@ procedure calling and also makes it easier to build new control constructs
as Tcl procedures.
For example, consider the following procedure:
.CS
-proc add2 name {
+proc \fIadd2\fR name {
\fBupvar\fR $name x
- set x [expr $x+2]
+ set x [expr {$x + 2}]
}
.CE
-\fBadd2\fR is invoked with an argument giving the name of a variable,
-and it adds two to the value of that variable.
-Although \fBadd2\fR could have been implemented using \fBuplevel\fR
+If \fIadd2\fR is invoked with an argument giving the name of a variable,
+it adds two to the value of that variable.
+Although \fIadd2\fR could have been implemented using \fBuplevel\fR
instead of \fBupvar\fR, \fBupvar\fR makes it simpler for \fBadd2\fR
to access the variable in the caller's procedure frame.
.PP
@@ -66,7 +66,6 @@ the outermost procedure call or the outermost \fBnamespace eval\fR command.
Also, \fBuplevel #0\fR evaluates a script
at top-level in the outermost namespace (the global namespace).
.PP
-.VS
If an upvar variable is unset (e.g. \fBx\fR in \fBadd2\fR above), the
\fBunset\fR operation affects the variable it is linked to, not the
upvar variable. There is no way to unset an upvar variable except
@@ -80,19 +79,21 @@ unexpected manner. If a variable trace is defined on \fIotherVar\fR, that
trace will be triggered by actions involving \fImyVar\fR. However,
the trace procedure will be passed the name of \fImyVar\fR, rather
than the name of \fIotherVar\fR. Thus, the output of the following code
-will be \fBlocalVar\fR rather than \fBoriginalVar\fR:
+will be
+.QW "\fIlocalVar\fR"
+rather than
+.QW "\fIoriginalVar\fR" :
.CS
-proc \fBtraceproc\fR { name index op } {
+proc \fItraceproc\fR { name index op } {
puts $name
}
-proc \fBsetByUpvar\fR { name value } {
+proc \fIsetByUpvar\fR { name value } {
\fBupvar\fR $name localVar
set localVar $value
}
set originalVar 1
-trace variable originalVar w \fBtraceproc\fR
-\fBsetByUpvar\fR originalVar 2
-}
+trace variable originalVar w \fItraceproc\fR
+\fIsetByUpvar\fR originalVar 2
.CE
.PP
If \fIotherVar\fR refers to an element of an array, then variable
@@ -100,7 +101,6 @@ traces set for the entire array will not be invoked when \fImyVar\fR
is accessed (but traces on the particular element will still be
invoked). In particular, if the array is \fBenv\fR, then changes
made to \fImyVar\fR will not be passed to subprocesses correctly.
-.VE
.SH EXAMPLE
A \fBdecr\fR command that works like \fBincr\fR except it subtracts
the value from the variable instead of adding it:
diff --git a/doc/vwait.n b/doc/vwait.n
index d1cdcbc..e7289e1 100644
--- a/doc/vwait.n
+++ b/doc/vwait.n
@@ -21,7 +21,7 @@ the application if no events are ready. It continues processing
events until some event handler sets the value of variable
\fIvarName\fR. Once \fIvarName\fR has been set, the \fBvwait\fR
command will return as soon as the event handler that modified
-\fIvarName\fR completes. \fIvarName\fR must globally scoped
+\fIvarName\fR completes. \fIvarName\fR must be globally scoped
(either with a call to \fBglobal\fR for the \fIvarName\fR, or with
the full namespace path specification).
.PP
diff --git a/generic/README b/generic/README
index ec6139a..d1c078e 100644
--- a/generic/README
+++ b/generic/README
@@ -1,3 +1,3 @@
This directory contains Tcl source files that work on all the platforms
-where Tcl runs (e.g. UNIX, PCs, and Macintoshes). Platform-specific
-sources are in the directories ../unix, ../win, ../macosx, and ../mac.
+where Tcl runs (e.g. UNIX, PCs, and MacOSX). Platform-specific
+sources are in the directories ../unix, ../win, and ../macosx.
diff --git a/generic/regc_color.c b/generic/regc_color.c
index f6716be..ba1f668 100644
--- a/generic/regc_color.c
+++ b/generic/regc_color.c
@@ -2,24 +2,24 @@
* colorings of characters
* This file is #included by regcomp.c.
*
- * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
- *
+ * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
+ *
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
- * Corporation, none of whom are responsible for the results. The author
- * thanks all of them.
- *
+ * Corporation, none of whom are responsible for the results. The author
+ * thanks all of them.
+ *
* Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
- *
- * I'd appreciate being given credit for this package in the documentation
- * of software which uses it, but that is not a requirement.
- *
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
@@ -28,662 +28,712 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- *
- *
- * Note that there are some incestuous relationships between this code and
- * NFA arc maintenance, which perhaps ought to be cleaned up sometime.
+ * Note that there are some incestuous relationships between this code and NFA
+ * arc maintenance, which perhaps ought to be cleaned up sometime.
*/
-
-
#define CISERR() VISERR(cm->v)
#define CERR(e) VERR(cm->v, (e))
-
-
-
+
/*
- initcm - set up new colormap
^ static VOID initcm(struct vars *, struct colormap *);
*/
-static VOID
-initcm(v, cm)
-struct vars *v;
-struct colormap *cm;
+static void
+initcm(
+ struct vars *v,
+ struct colormap *cm)
{
- int i;
- int j;
- union tree *t;
- union tree *nextt;
- struct colordesc *cd;
-
- cm->magic = CMMAGIC;
- cm->v = v;
-
- cm->ncds = NINLINECDS;
- cm->cd = cm->cdspace;
- cm->max = 0;
- cm->free = 0;
-
- cd = cm->cd; /* cm->cd[WHITE] */
- cd->sub = NOSUB;
- cd->arcs = NULL;
- cd->flags = 0;
- cd->nchrs = CHR_MAX - CHR_MIN + 1;
-
- /* upper levels of tree */
- for (t = &cm->tree[0], j = NBYTS-1; j > 0; t = nextt, j--) {
- nextt = t + 1;
- for (i = BYTTAB-1; i >= 0; i--)
- t->tptr[i] = nextt;
+ int i;
+ int j;
+ union tree *t;
+ union tree *nextt;
+ struct colordesc *cd;
+
+ cm->magic = CMMAGIC;
+ cm->v = v;
+
+ cm->ncds = NINLINECDS;
+ cm->cd = cm->cdspace;
+ cm->max = 0;
+ cm->free = 0;
+
+ cd = cm->cd; /* cm->cd[WHITE] */
+ cd->sub = NOSUB;
+ cd->arcs = NULL;
+ cd->flags = 0;
+ cd->nchrs = CHR_MAX - CHR_MIN + 1;
+
+ /*
+ * Upper levels of tree.
+ */
+
+ for (t=&cm->tree[0], j=NBYTS-1 ; j>0 ; t=nextt, j--) {
+ nextt = t + 1;
+ for (i=BYTTAB-1 ; i>=0 ; i--) {
+ t->tptr[i] = nextt;
}
- /* bottom level is solid white */
- t = &cm->tree[NBYTS-1];
- for (i = BYTTAB-1; i >= 0; i--)
- t->tcolor[i] = WHITE;
- cd->block = t;
-}
+ }
+ /*
+ * Bottom level is solid white.
+ */
+
+ t = &cm->tree[NBYTS-1];
+ for (i=BYTTAB-1 ; i>=0 ; i--) {
+ t->tcolor[i] = WHITE;
+ }
+ cd->block = t;
+}
+
/*
- freecm - free dynamically-allocated things in a colormap
^ static VOID freecm(struct colormap *);
*/
-static VOID
-freecm(cm)
-struct colormap *cm;
+static void
+freecm(
+ struct colormap *cm)
{
- size_t i;
- union tree *cb;
-
- cm->magic = 0;
- if (NBYTS > 1)
- cmtreefree(cm, cm->tree, 0);
- for (i = 1; i <= cm->max; i++) /* skip WHITE */
- if (!UNUSEDCOLOR(&cm->cd[i])) {
- cb = cm->cd[i].block;
- if (cb != NULL)
- FREE(cb);
- }
- if (cm->cd != cm->cdspace)
- FREE(cm->cd);
+ size_t i;
+ union tree *cb;
+
+ cm->magic = 0;
+ if (NBYTS > 1) {
+ cmtreefree(cm, cm->tree, 0);
+ }
+ for (i=1 ; i<=cm->max ; i++) { /* skip WHITE */
+ if (!UNUSEDCOLOR(&cm->cd[i])) {
+ cb = cm->cd[i].block;
+ if (cb != NULL) {
+ FREE(cb);
+ }
+ }
+ }
+ if (cm->cd != cm->cdspace) {
+ FREE(cm->cd);
+ }
}
-
+
/*
- cmtreefree - free a non-terminal part of a colormap tree
^ static VOID cmtreefree(struct colormap *, union tree *, int);
*/
-static VOID
-cmtreefree(cm, tree, level)
-struct colormap *cm;
-union tree *tree;
-int level; /* level number (top == 0) of this block */
+static void
+cmtreefree(
+ struct colormap *cm,
+ union tree *tree,
+ int level) /* level number (top == 0) of this block */
{
- int i;
- union tree *t;
- union tree *fillt = &cm->tree[level+1];
- union tree *cb;
-
- assert(level < NBYTS-1); /* this level has pointers */
- for (i = BYTTAB-1; i >= 0; i--) {
- t = tree->tptr[i];
- assert(t != NULL);
- if (t != fillt) {
- if (level < NBYTS-2) { /* more pointer blocks below */
- cmtreefree(cm, t, level+1);
- FREE(t);
- } else { /* color block below */
- cb = cm->cd[t->tcolor[0]].block;
- if (t != cb) /* not a solid block */
- FREE(t);
- }
+ int i;
+ union tree *t;
+ union tree *fillt = &cm->tree[level+1];
+ union tree *cb;
+
+ assert(level < NBYTS-1); /* this level has pointers */
+ for (i=BYTTAB-1 ; i>=0 ; i--) {
+ t = tree->tptr[i];
+ assert(t != NULL);
+ if (t != fillt) {
+ if (level < NBYTS-2) { /* more pointer blocks below */
+ cmtreefree(cm, t, level+1);
+ FREE(t);
+ } else { /* color block below */
+ cb = cm->cd[t->tcolor[0]].block;
+ if (t != cb) { /* not a solid block */
+ FREE(t);
}
+ }
}
+ }
}
-
+
/*
- setcolor - set the color of a character in a colormap
^ static color setcolor(struct colormap *, pchr, pcolor);
*/
static color /* previous color */
-setcolor(cm, c, co)
-struct colormap *cm;
-pchr c;
-pcolor co;
+setcolor(
+ struct colormap *cm,
+ pchr c,
+ pcolor co)
{
- uchr uc = c;
- int shift;
- int level;
- int b;
- int bottom;
- union tree *t;
- union tree *newt;
- union tree *fillt;
- union tree *lastt;
- union tree *cb;
- color prev;
-
- assert(cm->magic == CMMAGIC);
- if (CISERR() || co == COLORLESS)
+ uchr uc = c;
+ int shift;
+ int level;
+ int b;
+ int bottom;
+ union tree *t;
+ union tree *newt;
+ union tree *fillt;
+ union tree *lastt;
+ union tree *cb;
+ color prev;
+
+ assert(cm->magic == CMMAGIC);
+ if (CISERR() || co == COLORLESS) {
+ return COLORLESS;
+ }
+
+ t = cm->tree;
+ for (level=0, shift=BYTBITS*(NBYTS-1) ; shift>0; level++, shift-=BYTBITS){
+ b = (uc >> shift) & BYTMASK;
+ lastt = t;
+ t = lastt->tptr[b];
+ assert(t != NULL);
+ fillt = &cm->tree[level+1];
+ bottom = (shift <= BYTBITS) ? 1 : 0;
+ cb = (bottom) ? cm->cd[t->tcolor[0]].block : fillt;
+ if (t == fillt || t == cb) { /* must allocate a new block */
+ newt = (union tree *) MALLOC((bottom) ?
+ sizeof(struct colors) : sizeof(struct ptrs));
+ if (newt == NULL) {
+ CERR(REG_ESPACE);
return COLORLESS;
-
- t = cm->tree;
- for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0;
- level++, shift -= BYTBITS) {
- b = (uc >> shift) & BYTMASK;
- lastt = t;
- t = lastt->tptr[b];
- assert(t != NULL);
- fillt = &cm->tree[level+1];
- bottom = (shift <= BYTBITS) ? 1 : 0;
- cb = (bottom) ? cm->cd[t->tcolor[0]].block : fillt;
- if (t == fillt || t == cb) { /* must allocate a new block */
- newt = (union tree *)MALLOC((bottom) ?
- sizeof(struct colors) : sizeof(struct ptrs));
- if (newt == NULL) {
- CERR(REG_ESPACE);
- return COLORLESS;
- }
- if (bottom)
- memcpy(VS(newt->tcolor), VS(t->tcolor),
- BYTTAB*sizeof(color));
- else
- memcpy(VS(newt->tptr), VS(t->tptr),
- BYTTAB*sizeof(union tree *));
- t = newt;
- lastt->tptr[b] = t;
- }
+ }
+ if (bottom) {
+ memcpy(newt->tcolor, t->tcolor, BYTTAB*sizeof(color));
+ } else {
+ memcpy(newt->tptr, t->tptr, BYTTAB*sizeof(union tree *));
+ }
+ t = newt;
+ lastt->tptr[b] = t;
}
+ }
- b = uc & BYTMASK;
- prev = t->tcolor[b];
- t->tcolor[b] = (color)co;
- return prev;
+ b = uc & BYTMASK;
+ prev = t->tcolor[b];
+ t->tcolor[b] = (color) co;
+ return prev;
}
-
+
/*
- maxcolor - report largest color number in use
^ static color maxcolor(struct colormap *);
*/
static color
-maxcolor(cm)
-struct colormap *cm;
+maxcolor(
+ struct colormap *cm)
{
- if (CISERR())
- return COLORLESS;
+ if (CISERR()) {
+ return COLORLESS;
+ }
- return (color)cm->max;
+ return (color) cm->max;
}
-
+
/*
- newcolor - find a new color (must be subject of setcolor at once)
- * Beware: may relocate the colordescs.
+ * Beware: may relocate the colordescs.
^ static color newcolor(struct colormap *);
*/
static color /* COLORLESS for error */
-newcolor(cm)
-struct colormap *cm;
+newcolor(
+ struct colormap *cm)
{
- struct colordesc *cd;
- struct colordesc *new;
- size_t n;
-
- if (CISERR())
- return COLORLESS;
-
- if (cm->free != 0) {
- assert(cm->free > 0);
- assert((size_t)cm->free < cm->ncds);
- cd = &cm->cd[cm->free];
- assert(UNUSEDCOLOR(cd));
- assert(cd->arcs == NULL);
- cm->free = cd->sub;
- } else if (cm->max < cm->ncds - 1) {
- cm->max++;
- cd = &cm->cd[cm->max];
+ struct colordesc *cd;
+ size_t n;
+
+ if (CISERR()) {
+ return COLORLESS;
+ }
+
+ if (cm->free != 0) {
+ assert(cm->free > 0);
+ assert((size_t) cm->free < cm->ncds);
+ cd = &cm->cd[cm->free];
+ assert(UNUSEDCOLOR(cd));
+ assert(cd->arcs == NULL);
+ cm->free = cd->sub;
+ } else if (cm->max < cm->ncds - 1) {
+ cm->max++;
+ cd = &cm->cd[cm->max];
+ } else {
+ struct colordesc *newCd;
+
+ /*
+ * Oops, must allocate more.
+ */
+
+ n = cm->ncds * 2;
+ if (cm->cd == cm->cdspace) {
+ newCd = (struct colordesc *) MALLOC(n * sizeof(struct colordesc));
+ if (newCd != NULL) {
+ memcpy(newCd, cm->cdspace,
+ cm->ncds * sizeof(struct colordesc));
+ }
} else {
- /* oops, must allocate more */
- n = cm->ncds * 2;
- if (cm->cd == cm->cdspace) {
- new = (struct colordesc *)MALLOC(n *
- sizeof(struct colordesc));
- if (new != NULL)
- memcpy(VS(new), VS(cm->cdspace), cm->ncds *
- sizeof(struct colordesc));
- } else
- new = (struct colordesc *)REALLOC(cm->cd,
- n * sizeof(struct colordesc));
- if (new == NULL) {
- CERR(REG_ESPACE);
- return COLORLESS;
- }
- cm->cd = new;
- cm->ncds = n;
- assert(cm->max < cm->ncds - 1);
- cm->max++;
- cd = &cm->cd[cm->max];
+ newCd = (struct colordesc *)
+ REALLOC(cm->cd, n * sizeof(struct colordesc));
}
-
- cd->nchrs = 0;
- cd->sub = NOSUB;
- cd->arcs = NULL;
- cd->flags = 0;
- cd->block = NULL;
-
- return (color)(cd - cm->cd);
+ if (newCd == NULL) {
+ CERR(REG_ESPACE);
+ return COLORLESS;
+ }
+ cm->cd = newCd;
+ cm->ncds = n;
+ assert(cm->max < cm->ncds - 1);
+ cm->max++;
+ cd = &cm->cd[cm->max];
+ }
+
+ cd->nchrs = 0;
+ cd->sub = NOSUB;
+ cd->arcs = NULL;
+ cd->flags = 0;
+ cd->block = NULL;
+
+ return (color) (cd - cm->cd);
}
-
+
/*
- freecolor - free a color (must have no arcs or subcolor)
^ static VOID freecolor(struct colormap *, pcolor);
*/
-static VOID
-freecolor(cm, co)
-struct colormap *cm;
-pcolor co;
+static void
+freecolor(
+ struct colormap *cm,
+ pcolor co)
{
- struct colordesc *cd = &cm->cd[co];
- color pco, nco; /* for freelist scan */
-
- assert(co >= 0);
- if (co == WHITE)
- return;
-
- assert(cd->arcs == NULL);
- assert(cd->sub == NOSUB);
- assert(cd->nchrs == 0);
- cd->flags = FREECOL;
- if (cd->block != NULL) {
- FREE(cd->block);
- cd->block = NULL; /* just paranoia */
+ struct colordesc *cd = &cm->cd[co];
+ color pco, nco; /* for freelist scan */
+
+ assert(co >= 0);
+ if (co == WHITE) {
+ return;
+ }
+
+ assert(cd->arcs == NULL);
+ assert(cd->sub == NOSUB);
+ assert(cd->nchrs == 0);
+ cd->flags = FREECOL;
+ if (cd->block != NULL) {
+ FREE(cd->block);
+ cd->block = NULL; /* just paranoia */
+ }
+
+ if ((size_t) co == cm->max) {
+ while (cm->max > WHITE && UNUSEDCOLOR(&cm->cd[cm->max])) {
+ cm->max--;
}
-
- if ((size_t)co == cm->max) {
- while (cm->max > WHITE && UNUSEDCOLOR(&cm->cd[cm->max]))
- cm->max--;
- assert(cm->free >= 0);
- while ((size_t)cm->free > cm->max)
- cm->free = cm->cd[cm->free].sub;
- if (cm->free > 0) {
- assert(cm->free < cm->max);
- pco = cm->free;
- nco = cm->cd[pco].sub;
- while (nco > 0)
- if ((size_t)nco > cm->max) {
- /* take this one out of freelist */
- nco = cm->cd[nco].sub;
- cm->cd[pco].sub = nco;
- } else {
- assert(nco < cm->max);
- pco = nco;
- nco = cm->cd[pco].sub;
- }
+ assert(cm->free >= 0);
+ while ((size_t) cm->free > cm->max) {
+ cm->free = cm->cd[cm->free].sub;
+ }
+ if (cm->free > 0) {
+ assert(cm->free < cm->max);
+ pco = cm->free;
+ nco = cm->cd[pco].sub;
+ while (nco > 0) {
+ if ((size_t) nco > cm->max) {
+ /*
+ * Take this one out of freelist.
+ */
+
+ nco = cm->cd[nco].sub;
+ cm->cd[pco].sub = nco;
+ } else {
+ assert(nco < cm->max);
+ pco = nco;
+ nco = cm->cd[pco].sub;
}
- } else {
- cd->sub = cm->free;
- cm->free = (color)(cd - cm->cd);
+ }
}
+ } else {
+ cd->sub = cm->free;
+ cm->free = (color) (cd - cm->cd);
+ }
}
-
+
/*
- pseudocolor - allocate a false color, to be managed by other means
^ static color pseudocolor(struct colormap *);
*/
static color
-pseudocolor(cm)
-struct colormap *cm;
+pseudocolor(
+ struct colormap *cm)
{
- color co;
-
- co = newcolor(cm);
- if (CISERR())
- return COLORLESS;
- cm->cd[co].nchrs = 1;
- cm->cd[co].flags = PSEUDO;
- return co;
+ color co;
+
+ co = newcolor(cm);
+ if (CISERR()) {
+ return COLORLESS;
+ }
+ cm->cd[co].nchrs = 1;
+ cm->cd[co].flags = PSEUDO;
+ return co;
}
-
+
/*
- subcolor - allocate a new subcolor (if necessary) to this chr
^ static color subcolor(struct colormap *, pchr c);
*/
static color
-subcolor(cm, c)
-struct colormap *cm;
-pchr c;
+subcolor(
+ struct colormap *cm,
+ pchr c)
{
- color co; /* current color of c */
- color sco; /* new subcolor */
-
- co = GETCOLOR(cm, c);
- sco = newsub(cm, co);
- if (CISERR())
- return COLORLESS;
- assert(sco != COLORLESS);
-
- if (co == sco) /* already in an open subcolor */
- return co; /* rest is redundant */
- cm->cd[co].nchrs--;
- cm->cd[sco].nchrs++;
- setcolor(cm, c, sco);
- return sco;
+ color co; /* current color of c */
+ color sco; /* new subcolor */
+
+ co = GETCOLOR(cm, c);
+ sco = newsub(cm, co);
+ if (CISERR()) {
+ return COLORLESS;
+ }
+ assert(sco != COLORLESS);
+
+ if (co == sco) { /* already in an open subcolor */
+ return co; /* rest is redundant */
+ }
+ cm->cd[co].nchrs--;
+ cm->cd[sco].nchrs++;
+ setcolor(cm, c, sco);
+ return sco;
}
-
+
/*
- newsub - allocate a new subcolor (if necessary) for a color
^ static color newsub(struct colormap *, pcolor);
*/
static color
-newsub(cm, co)
-struct colormap *cm;
-pcolor co;
+newsub(
+ struct colormap *cm,
+ pcolor co)
{
- color sco; /* new subcolor */
-
- sco = cm->cd[co].sub;
- if (sco == NOSUB) { /* color has no open subcolor */
- if (cm->cd[co].nchrs == 1) /* optimization */
- return co;
- sco = newcolor(cm); /* must create subcolor */
- if (sco == COLORLESS) {
- assert(CISERR());
- return COLORLESS;
- }
- cm->cd[co].sub = sco;
- cm->cd[sco].sub = sco; /* open subcolor points to self */
+ color sco; /* new subcolor */
+
+ sco = cm->cd[co].sub;
+ if (sco == NOSUB) { /* color has no open subcolor */
+ if (cm->cd[co].nchrs == 1) { /* optimization */
+ return co;
+ }
+ sco = newcolor(cm); /* must create subcolor */
+ if (sco == COLORLESS) {
+ assert(CISERR());
+ return COLORLESS;
}
- assert(sco != NOSUB);
+ cm->cd[co].sub = sco;
+ cm->cd[sco].sub = sco; /* open subcolor points to self */
+ }
+ assert(sco != NOSUB);
- return sco;
+ return sco;
}
-
+
/*
- subrange - allocate new subcolors to this range of chrs, fill in arcs
^ static VOID subrange(struct vars *, pchr, pchr, struct state *,
^ struct state *);
*/
-static VOID
-subrange(v, from, to, lp, rp)
-struct vars *v;
-pchr from;
-pchr to;
-struct state *lp;
-struct state *rp;
+static void
+subrange(
+ struct vars *v,
+ pchr from,
+ pchr to,
+ struct state *lp,
+ struct state *rp)
{
- uchr uf;
- int i;
-
- assert(from <= to);
-
- /* first, align "from" on a tree-block boundary */
- uf = (uchr)from;
- i = (int)( ((uf + BYTTAB-1) & (uchr)~BYTMASK) - uf );
- for (; from <= to && i > 0; i--, from++)
- newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp);
- if (from > to) /* didn't reach a boundary */
- return;
-
- /* deal with whole blocks */
- for (; to - from >= BYTTAB; from += BYTTAB)
- subblock(v, from, lp, rp);
-
- /* clean up any remaining partial table */
- for (; from <= to; from++)
- newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp);
+ uchr uf;
+ int i;
+
+ assert(from <= to);
+
+ /*
+ * First, align "from" on a tree-block boundary
+ */
+
+ uf = (uchr) from;
+ i = (int) (((uf + BYTTAB - 1) & (uchr) ~BYTMASK) - uf);
+ for (; from<=to && i>0; i--, from++) {
+ newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp);
+ }
+ if (from > to) { /* didn't reach a boundary */
+ return;
+ }
+
+ /*
+ * Deal with whole blocks.
+ */
+
+ for (; to-from>=BYTTAB ; from+=BYTTAB) {
+ subblock(v, from, lp, rp);
+ }
+
+ /*
+ * Clean up any remaining partial table.
+ */
+
+ for (; from<=to ; from++) {
+ newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp);
+ }
}
-
+
/*
- subblock - allocate new subcolors for one tree block of chrs, fill in arcs
^ static VOID subblock(struct vars *, pchr, struct state *, struct state *);
*/
-static VOID
-subblock(v, start, lp, rp)
-struct vars *v;
-pchr start; /* first of BYTTAB chrs */
-struct state *lp;
-struct state *rp;
+static void
+subblock(
+ struct vars *v,
+ pchr start, /* first of BYTTAB chrs */
+ struct state *lp,
+ struct state *rp)
{
- uchr uc = start;
- struct colormap *cm = v->cm;
- int shift;
- int level;
- int i;
- int b;
- union tree *t;
- union tree *cb;
- union tree *fillt;
- union tree *lastt;
- int previ;
- int ndone;
- color co;
- color sco;
-
- assert((uc % BYTTAB) == 0);
-
- /* find its color block, making new pointer blocks as needed */
- t = cm->tree;
- fillt = NULL;
- for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0;
- level++, shift -= BYTBITS) {
- b = (uc >> shift) & BYTMASK;
- lastt = t;
- t = lastt->tptr[b];
- assert(t != NULL);
- fillt = &cm->tree[level+1];
- if (t == fillt && shift > BYTBITS) { /* need new ptr block */
- t = (union tree *)MALLOC(sizeof(struct ptrs));
- if (t == NULL) {
- CERR(REG_ESPACE);
- return;
- }
- memcpy(VS(t->tptr), VS(fillt->tptr),
- BYTTAB*sizeof(union tree *));
- lastt->tptr[b] = t;
- }
+ uchr uc = start;
+ struct colormap *cm = v->cm;
+ int shift;
+ int level;
+ int i;
+ int b;
+ union tree *t;
+ union tree *cb;
+ union tree *fillt;
+ union tree *lastt;
+ int previ;
+ int ndone;
+ color co;
+ color sco;
+
+ assert((uc % BYTTAB) == 0);
+
+ /*
+ * Find its color block, making new pointer blocks as needed.
+ */
+
+ t = cm->tree;
+ fillt = NULL;
+ for (level=0, shift=BYTBITS*(NBYTS-1); shift>0; level++, shift-=BYTBITS) {
+ b = (uc >> shift) & BYTMASK;
+ lastt = t;
+ t = lastt->tptr[b];
+ assert(t != NULL);
+ fillt = &cm->tree[level+1];
+ if (t == fillt && shift > BYTBITS) { /* need new ptr block */
+ t = (union tree *) MALLOC(sizeof(struct ptrs));
+ if (t == NULL) {
+ CERR(REG_ESPACE);
+ return;
+ }
+ memcpy(t->tptr, fillt->tptr, BYTTAB*sizeof(union tree *));
+ lastt->tptr[b] = t;
}
+ }
+
+ /*
+ * Special cases: fill block or solid block.
+ */
+ co = t->tcolor[0];
+ cb = cm->cd[co].block;
+ if (t == fillt || t == cb) {
+ /*
+ * Either way, we want a subcolor solid block.
+ */
- /* special cases: fill block or solid block */
- co = t->tcolor[0];
- cb = cm->cd[co].block;
- if (t == fillt || t == cb) {
- /* either way, we want a subcolor solid block */
- sco = newsub(cm, co);
- t = cm->cd[sco].block;
- if (t == NULL) { /* must set it up */
- t = (union tree *)MALLOC(sizeof(struct colors));
- if (t == NULL) {
- CERR(REG_ESPACE);
- return;
- }
- for (i = 0; i < BYTTAB; i++)
- t->tcolor[i] = sco;
- cm->cd[sco].block = t;
- }
- /* find loop must have run at least once */
- lastt->tptr[b] = t;
- newarc(v->nfa, PLAIN, sco, lp, rp);
- cm->cd[co].nchrs -= BYTTAB;
- cm->cd[sco].nchrs += BYTTAB;
+ sco = newsub(cm, co);
+ t = cm->cd[sco].block;
+ if (t == NULL) { /* must set it up */
+ t = (union tree *) MALLOC(sizeof(struct colors));
+ if (t == NULL) {
+ CERR(REG_ESPACE);
return;
+ }
+ for (i=0 ; i<BYTTAB ; i++) {
+ t->tcolor[i] = sco;
+ }
+ cm->cd[sco].block = t;
}
- /* general case, a mixed block to be altered */
- i = 0;
- while (i < BYTTAB) {
- co = t->tcolor[i];
- sco = newsub(cm, co);
- newarc(v->nfa, PLAIN, sco, lp, rp);
- previ = i;
- do {
- t->tcolor[i++] = sco;
- } while (i < BYTTAB && t->tcolor[i] == co);
- ndone = i - previ;
- cm->cd[co].nchrs -= ndone;
- cm->cd[sco].nchrs += ndone;
- }
-}
+ /*
+ * Find loop must have run at least once.
+ */
+
+ lastt->tptr[b] = t;
+ newarc(v->nfa, PLAIN, sco, lp, rp);
+ cm->cd[co].nchrs -= BYTTAB;
+ cm->cd[sco].nchrs += BYTTAB;
+ return;
+ }
+
+ /*
+ * General case, a mixed block to be altered.
+ */
+ i = 0;
+ while (i < BYTTAB) {
+ co = t->tcolor[i];
+ sco = newsub(cm, co);
+ newarc(v->nfa, PLAIN, sco, lp, rp);
+ previ = i;
+ do {
+ t->tcolor[i++] = sco;
+ } while (i < BYTTAB && t->tcolor[i] == co);
+ ndone = i - previ;
+ cm->cd[co].nchrs -= ndone;
+ cm->cd[sco].nchrs += ndone;
+ }
+}
+
/*
- okcolors - promote subcolors to full colors
^ static VOID okcolors(struct nfa *, struct colormap *);
*/
-static VOID
-okcolors(nfa, cm)
-struct nfa *nfa;
-struct colormap *cm;
+static void
+okcolors(
+ struct nfa *nfa,
+ struct colormap *cm)
{
- struct colordesc *cd;
- struct colordesc *end = CDEND(cm);
- struct colordesc *scd;
- struct arc *a;
- color co;
- color sco;
-
- for (cd = cm->cd, co = 0; cd < end; cd++, co++) {
- sco = cd->sub;
- if (UNUSEDCOLOR(cd) || sco == NOSUB) {
- /* has no subcolor, no further action */
- } else if (sco == co) {
- /* is subcolor, let parent deal with it */
- } else if (cd->nchrs == 0) {
- /* parent empty, its arcs change color to subcolor */
- cd->sub = NOSUB;
- scd = &cm->cd[sco];
- assert(scd->nchrs > 0);
- assert(scd->sub == sco);
- scd->sub = NOSUB;
- while ((a = cd->arcs) != NULL) {
- assert(a->co == co);
- uncolorchain(cm, a);
- a->co = sco;
- colorchain(cm, a);
- }
- freecolor(cm, co);
- } else {
- /* parent's arcs must gain parallel subcolor arcs */
- cd->sub = NOSUB;
- scd = &cm->cd[sco];
- assert(scd->nchrs > 0);
- assert(scd->sub == sco);
- scd->sub = NOSUB;
- for (a = cd->arcs; a != NULL; a = a->colorchain) {
- assert(a->co == co);
- newarc(nfa, a->type, sco, a->from, a->to);
- }
- }
+ struct colordesc *cd;
+ struct colordesc *end = CDEND(cm);
+ struct colordesc *scd;
+ struct arc *a;
+ color co;
+ color sco;
+
+ for (cd=cm->cd, co=0 ; cd<end ; cd++, co++) {
+ sco = cd->sub;
+ if (UNUSEDCOLOR(cd) || sco == NOSUB) {
+ /*
+ * Has no subcolor, no further action.
+ */
+ } else if (sco == co) {
+ /*
+ * Is subcolor, let parent deal with it.
+ */
+ } else if (cd->nchrs == 0) {
+ /*
+ * Parent empty, its arcs change color to subcolor.
+ */
+
+ cd->sub = NOSUB;
+ scd = &cm->cd[sco];
+ assert(scd->nchrs > 0);
+ assert(scd->sub == sco);
+ scd->sub = NOSUB;
+ while ((a = cd->arcs) != NULL) {
+ assert(a->co == co);
+ uncolorchain(cm, a);
+ a->co = sco;
+ colorchain(cm, a);
+ }
+ freecolor(cm, co);
+ } else {
+ /*
+ * Parent's arcs must gain parallel subcolor arcs.
+ */
+
+ cd->sub = NOSUB;
+ scd = &cm->cd[sco];
+ assert(scd->nchrs > 0);
+ assert(scd->sub == sco);
+ scd->sub = NOSUB;
+ for (a=cd->arcs ; a!=NULL ; a=a->colorchain) {
+ assert(a->co == co);
+ newarc(nfa, a->type, sco, a->from, a->to);
+ }
}
+ }
}
-
+
/*
- colorchain - add this arc to the color chain of its color
^ static VOID colorchain(struct colormap *, struct arc *);
*/
-static VOID
-colorchain(cm, a)
-struct colormap *cm;
-struct arc *a;
+static void
+colorchain(
+ struct colormap *cm,
+ struct arc *a)
{
- struct colordesc *cd = &cm->cd[a->co];
-
- if (cd->arcs)
- cd->arcs->colorchain_rev = a;
- a->colorchain = cd->arcs;
- a->colorchain_rev = NULL;
- cd->arcs = a;
+ struct colordesc *cd = &cm->cd[a->co];
+
+ if (cd->arcs != NULL) {
+ cd->arcs->colorchainRev = a;
+ }
+ a->colorchain = cd->arcs;
+ a->colorchainRev = NULL;
+ cd->arcs = a;
}
-
+
/*
- uncolorchain - delete this arc from the color chain of its color
^ static VOID uncolorchain(struct colormap *, struct arc *);
*/
-static VOID
-uncolorchain(cm, a)
-struct colormap *cm;
-struct arc *a;
-{
- struct colordesc *cd = &cm->cd[a->co];
- struct arc *aa = a->colorchain_rev;
-
- if (aa == NULL) {
- assert(cd->arcs == a);
- cd->arcs = a->colorchain;
- } else {
- assert(aa->colorchain == a);
- aa->colorchain = a->colorchain;
- }
- if (a->colorchain)
- a->colorchain->colorchain_rev = aa;
- a->colorchain = NULL; /* paranoia */
- a->colorchain_rev = NULL;
-}
-
-/*
- - singleton - is this character in its own color?
- ^ static int singleton(struct colormap *, pchr c);
- */
-static int /* predicate */
-singleton(cm, c)
-struct colormap *cm;
-pchr c;
+static void
+uncolorchain(
+ struct colormap *cm,
+ struct arc *a)
{
- color co; /* color of c */
-
- co = GETCOLOR(cm, c);
- if (cm->cd[co].nchrs == 1 && cm->cd[co].sub == NOSUB)
- return 1;
- return 0;
+ struct colordesc *cd = &cm->cd[a->co];
+ struct arc *aa = a->colorchainRev;
+
+ if (aa == NULL) {
+ assert(cd->arcs == a);
+ cd->arcs = a->colorchain;
+ } else {
+ assert(aa->colorchain == a);
+ aa->colorchain = a->colorchain;
+ }
+ if (a->colorchain != NULL) {
+ a->colorchain->colorchainRev = aa;
+ }
+ a->colorchain = NULL; /* paranoia */
+ a->colorchainRev = NULL;
}
-
+
/*
- rainbow - add arcs of all full colors (but one) between specified states
^ static VOID rainbow(struct nfa *, struct colormap *, int, pcolor,
^ struct state *, struct state *);
*/
-static VOID
-rainbow(nfa, cm, type, but, from, to)
-struct nfa *nfa;
-struct colormap *cm;
-int type;
-pcolor but; /* COLORLESS if no exceptions */
-struct state *from;
-struct state *to;
+static void
+rainbow(
+ struct nfa *nfa,
+ struct colormap *cm,
+ int type,
+ pcolor but, /* COLORLESS if no exceptions */
+ struct state *from,
+ struct state *to)
{
- struct colordesc *cd;
- struct colordesc *end = CDEND(cm);
- color co;
-
- for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++)
- if (!UNUSEDCOLOR(cd) && cd->sub != co && co != but &&
- !(cd->flags&PSEUDO))
- newarc(nfa, type, co, from, to);
+ struct colordesc *cd;
+ struct colordesc *end = CDEND(cm);
+ color co;
+
+ for (cd=cm->cd, co=0 ; cd<end && !CISERR(); cd++, co++) {
+ if (!UNUSEDCOLOR(cd) && (cd->sub != co) && (co != but)
+ && !(cd->flags&PSEUDO)) {
+ newarc(nfa, type, co, from, to);
+ }
+ }
}
-
+
/*
- colorcomplement - add arcs of complementary colors
* The calling sequence ought to be reconciled with cloneouts().
^ static VOID colorcomplement(struct nfa *, struct colormap *, int,
^ struct state *, struct state *, struct state *);
*/
-static VOID
-colorcomplement(nfa, cm, type, of, from, to)
-struct nfa *nfa;
-struct colormap *cm;
-int type;
-struct state *of; /* complements of this guy's PLAIN outarcs */
-struct state *from;
-struct state *to;
+static void
+colorcomplement(
+ struct nfa *nfa,
+ struct colormap *cm,
+ int type,
+ struct state *of, /* complements of this guy's PLAIN outarcs */
+ struct state *from,
+ struct state *to)
{
- struct colordesc *cd;
- struct colordesc *end = CDEND(cm);
- color co;
-
- assert(of != from);
- for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++)
- if (!UNUSEDCOLOR(cd) && !(cd->flags&PSEUDO))
- if (findarc(of, PLAIN, co) == NULL)
- newarc(nfa, type, co, from, to);
+ struct colordesc *cd;
+ struct colordesc *end = CDEND(cm);
+ color co;
+
+ assert(of != from);
+ for (cd=cm->cd, co=0 ; cd<end && !CISERR() ; cd++, co++) {
+ if (!UNUSEDCOLOR(cd) && !(cd->flags&PSEUDO)) {
+ if (findarc(of, PLAIN, co) == NULL) {
+ newarc(nfa, type, co, from, to);
+ }
+ }
+ }
}
-
-
-
+
#ifdef REG_DEBUG
/*
^ #ifdef REG_DEBUG
@@ -693,87 +743,106 @@ struct state *to;
- dumpcolors - debugging output
^ static VOID dumpcolors(struct colormap *, FILE *);
*/
-static VOID
-dumpcolors(cm, f)
-struct colormap *cm;
-FILE *f;
+static void
+dumpcolors(
+ struct colormap *cm,
+ FILE *f)
{
- struct colordesc *cd;
- struct colordesc *end;
- color co;
- chr c;
- char *has;
-
- fprintf(f, "max %ld\n", (long)cm->max);
- if (NBYTS > 1)
- fillcheck(cm, cm->tree, 0, f);
- end = CDEND(cm);
- for (cd = cm->cd + 1, co = 1; cd < end; cd++, co++) /* skip 0 */
- if (!UNUSEDCOLOR(cd)) {
- assert(cd->nchrs > 0);
- has = (cd->block != NULL) ? "#" : "";
- if (cd->flags&PSEUDO)
- fprintf(f, "#%2ld%s(ps): ", (long)co, has);
- else
- fprintf(f, "#%2ld%s(%2d): ", (long)co,
- has, cd->nchrs);
- /* it's hard to do this more efficiently */
- for (c = CHR_MIN; c < CHR_MAX; c++)
- if (GETCOLOR(cm, c) == co)
- dumpchr(c, f);
- assert(c == CHR_MAX);
- if (GETCOLOR(cm, c) == co)
- dumpchr(c, f);
- fprintf(f, "\n");
+ struct colordesc *cd;
+ struct colordesc *end;
+ color co;
+ chr c;
+ char *has;
+
+ fprintf(f, "max %ld\n", (long) cm->max);
+ if (NBYTS > 1) {
+ fillcheck(cm, cm->tree, 0, f);
+ }
+ end = CDEND(cm);
+ for (cd=cm->cd+1, co=1 ; cd<end ; cd++, co++) { /* skip 0 */
+ if (!UNUSEDCOLOR(cd)) {
+ assert(cd->nchrs > 0);
+ has = (cd->block != NULL) ? "#" : "";
+ if (cd->flags&PSEUDO) {
+ fprintf(f, "#%2ld%s(ps): ", (long) co, has);
+ } else {
+ fprintf(f, "#%2ld%s(%2d): ", (long) co, has, cd->nchrs);
+ }
+
+ /*
+ * It's hard to do this more efficiently.
+ */
+
+ for (c=CHR_MIN ; c<CHR_MAX ; c++) {
+ if (GETCOLOR(cm, c) == co) {
+ dumpchr(c, f);
}
+ }
+ assert(c == CHR_MAX);
+ if (GETCOLOR(cm, c) == co) {
+ dumpchr(c, f);
+ }
+ fprintf(f, "\n");
+ }
+ }
}
-
+
/*
- fillcheck - check proper filling of a tree
^ static VOID fillcheck(struct colormap *, union tree *, int, FILE *);
*/
-static VOID
-fillcheck(cm, tree, level, f)
-struct colormap *cm;
-union tree *tree;
-int level; /* level number (top == 0) of this block */
-FILE *f;
+static void
+fillcheck(
+ struct colormap *cm,
+ union tree *tree,
+ int level, /* level number (top == 0) of this block */
+ FILE *f)
{
- int i;
- union tree *t;
- union tree *fillt = &cm->tree[level+1];
-
- assert(level < NBYTS-1); /* this level has pointers */
- for (i = BYTTAB-1; i >= 0; i--) {
- t = tree->tptr[i];
- if (t == NULL)
- fprintf(f, "NULL found in filled tree!\n");
- else if (t == fillt)
- {}
- else if (level < NBYTS-2) /* more pointer blocks below */
- fillcheck(cm, t, level+1, f);
+ int i;
+ union tree *t;
+ union tree *fillt = &cm->tree[level+1];
+
+ assert(level < NBYTS-1); /* this level has pointers */
+ for (i=BYTTAB-1 ; i>=0 ; i--) {
+ t = tree->tptr[i];
+ if (t == NULL) {
+ fprintf(f, "NULL found in filled tree!\n");
+ } else if (t == fillt) {
+ /* empty body */
+ } else if (level < NBYTS-2) { /* more pointer blocks below */
+ fillcheck(cm, t, level+1, f);
}
+ }
}
-
+
/*
- dumpchr - print a chr
* Kind of char-centric but works well enough for debug use.
^ static VOID dumpchr(pchr, FILE *);
*/
-static VOID
-dumpchr(c, f)
-pchr c;
-FILE *f;
+static void
+dumpchr(
+ pchr c,
+ FILE *f)
{
- if (c == '\\')
- fprintf(f, "\\\\");
- else if (c > ' ' && c <= '~')
- putc((char)c, f);
- else
- fprintf(f, "\\u%04lx", (long)c);
+ if (c == '\\') {
+ fprintf(f, "\\\\");
+ } else if (c > ' ' && c <= '~') {
+ putc((char) c, f);
+ } else {
+ fprintf(f, "\\u%04lx", (long) c);
+ }
}
/*
^ #endif
*/
#endif /* ifdef REG_DEBUG */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regc_cvec.c b/generic/regc_cvec.c
index 0b976b8..64f34cd 100644
--- a/generic/regc_cvec.c
+++ b/generic/regc_cvec.c
@@ -6,7 +6,7 @@
*
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
- * Corporation, none of whom are responsible for the results. The author
+ * Corporation, none of whom are responsible for the results. The author
* thanks all of them.
*
* Redistribution and use in source and binary forms -- with or without
@@ -14,8 +14,8 @@
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
*
- * I'd appreciate being given credit for this package in the documentation
- * of software which uses it, but that is not a requirement.
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
@@ -27,149 +27,120 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
*/
/*
+ * Notes:
+ * Only (selected) functions in _this_ file should treat chr* as non-constant.
+ */
+
+/*
- newcvec - allocate a new cvec
- ^ static struct cvec *newcvec(int, int, int);
+ ^ static struct cvec *newcvec(int, int);
*/
static struct cvec *
-newcvec(nchrs, nranges, nmcces)
- int nchrs; /* to hold this many chrs... */
- int nranges; /* ... and this many ranges... */
- int nmcces; /* ... and this many MCCEs */
+newcvec(
+ int nchrs, /* to hold this many chrs... */
+ int nranges) /* ... and this many ranges... */
{
- size_t n;
- size_t nc;
- struct cvec *cv;
+ size_t nc = (size_t)nchrs + (size_t)nranges*2;
+ size_t n = sizeof(struct cvec) + nc*sizeof(chr);
+ struct cvec *cv = (struct cvec *) MALLOC(n);
- nc = (size_t)nchrs + (size_t)nmcces*(MAXMCCE+1) + (size_t)nranges*2;
- n = sizeof(struct cvec) + (size_t)(nmcces-1)*sizeof(chr *)
- + nc*sizeof(chr);
- cv = (struct cvec *)MALLOC(n);
if (cv == NULL) {
return NULL;
}
cv->chrspace = nchrs;
- cv->chrs = (chr *)&cv->mcces[nmcces]; /* chrs just after MCCE ptrs */
- cv->mccespace = nmcces;
- cv->ranges = cv->chrs + nchrs + nmcces*(MAXMCCE+1);
+ cv->chrs = (chr *)(((char *)cv)+sizeof(struct cvec));
+ cv->ranges = cv->chrs + nchrs;
cv->rangespace = nranges;
return clearcvec(cv);
}
-
+
/*
- clearcvec - clear a possibly-new cvec
* Returns pointer as convenience.
^ static struct cvec *clearcvec(struct cvec *);
*/
static struct cvec *
-clearcvec(cv)
- struct cvec *cv; /* character vector */
+clearcvec(
+ struct cvec *cv) /* character vector */
{
- int i;
-
assert(cv != NULL);
cv->nchrs = 0;
- assert(cv->chrs == (chr *)&cv->mcces[cv->mccespace]);
- cv->nmcces = 0;
- cv->nmccechrs = 0;
cv->nranges = 0;
- for (i = 0; i < cv->mccespace; i++) {
- cv->mcces[i] = NULL;
- }
-
return cv;
}
-
+
/*
- addchr - add a chr to a cvec
^ static VOID addchr(struct cvec *, pchr);
*/
-static VOID
-addchr(cv, c)
- struct cvec *cv; /* character vector */
- pchr c; /* character to add */
+static void
+addchr(
+ struct cvec *cv, /* character vector */
+ pchr c) /* character to add */
{
- assert(cv->nchrs < cv->chrspace - cv->nmccechrs);
cv->chrs[cv->nchrs++] = (chr)c;
}
-
+
/*
- addrange - add a range to a cvec
^ static VOID addrange(struct cvec *, pchr, pchr);
*/
-static VOID
-addrange(cv, from, to)
- struct cvec *cv; /* character vector */
- pchr from; /* first character of range */
- pchr to; /* last character of range */
+static void
+addrange(
+ struct cvec *cv, /* character vector */
+ pchr from, /* first character of range */
+ pchr to) /* last character of range */
{
assert(cv->nranges < cv->rangespace);
cv->ranges[cv->nranges*2] = (chr)from;
cv->ranges[cv->nranges*2 + 1] = (chr)to;
cv->nranges++;
}
-
-/*
- - haschr - does a cvec contain this chr?
- ^ static int haschr(struct cvec *, pchr);
- */
-static int /* predicate */
-haschr(cv, c)
- struct cvec *cv; /* character vector */
- pchr c; /* character to test for */
-{
- int i;
- chr *p;
-
- for (p = cv->chrs, i = cv->nchrs; i > 0; p++, i--) {
- if (*p == c) {
- return 1;
- }
- }
- for (p = cv->ranges, i = cv->nranges; i > 0; p += 2, i--) {
- if ((*p <= c) && (c <= *(p+1))) {
- return 1;
- }
- }
- return 0;
-}
-
+
/*
- getcvec - get a cvec, remembering it as v->cv
^ static struct cvec *getcvec(struct vars *, int, int);
*/
static struct cvec *
-getcvec(v, nchrs, nranges)
- struct vars *v; /* context */
- int nchrs; /* to hold this many chrs... */
- int nranges; /* ... and this many ranges... */
+getcvec(
+ struct vars *v, /* context */
+ int nchrs, /* to hold this many chrs... */
+ int nranges) /* ... and this many ranges... */
{
- if (v->cv != NULL && nchrs <= v->cv->chrspace &&
- nranges <= v->cv->rangespace) {
+ if ((v->cv != NULL) && (nchrs <= v->cv->chrspace) &&
+ (nranges <= v->cv->rangespace)) {
return clearcvec(v->cv);
}
if (v->cv != NULL) {
freecvec(v->cv);
}
- v->cv = newcvec(nchrs, nranges, 0);
+ v->cv = newcvec(nchrs, nranges);
if (v->cv == NULL) {
ERR(REG_ESPACE);
}
return v->cv;
}
-
+
/*
- freecvec - free a cvec
^ static VOID freecvec(struct cvec *);
*/
-static VOID
-freecvec(cv)
- struct cvec *cv; /* character vector */
+static void
+freecvec(
+ struct cvec *cv) /* character vector */
{
FREE(cv);
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regc_lex.c b/generic/regc_lex.c
index 588718d..bc61e14 100644
--- a/generic/regc_lex.c
+++ b/generic/regc_lex.c
@@ -3,20 +3,20 @@
* This file is #included by regcomp.c.
*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
- *
+ *
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author
- * thanks all of them.
- *
+ * thanks all of them.
+ *
* Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
- *
- * I'd appreciate being given credit for this package in the documentation
- * of software which uses it, but that is not a requirement.
- *
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -27,7 +27,6 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
*/
/* scanning macros (know about v) */
@@ -35,9 +34,10 @@
#define HAVE(n) (v->stop - v->now >= (n))
#define NEXT1(c) (!ATEOS() && *v->now == CHR(c))
#define NEXT2(a,b) (HAVE(2) && *v->now == CHR(a) && *(v->now+1) == CHR(b))
-#define NEXT3(a,b,c) (HAVE(3) && *v->now == CHR(a) && \
- *(v->now+1) == CHR(b) && \
- *(v->now+2) == CHR(c))
+#define NEXT3(a,b,c) \
+ (HAVE(3) && *v->now == CHR(a) && \
+ *(v->now+1) == CHR(b) && \
+ *(v->now+2) == CHR(c))
#define SET(c) (v->nexttype = (c))
#define SETV(c, n) (v->nexttype = (c), v->nextvalue = (n))
#define RET(c) return (SET(c), 1)
@@ -60,804 +60,907 @@
/* construct pointer past end of chr array */
#define ENDOF(array) ((array) + sizeof(array)/sizeof(chr))
-
+
/*
- lexstart - set up lexical stuff, scan leading options
^ static VOID lexstart(struct vars *);
*/
-static VOID
-lexstart(v)
-struct vars *v;
+static void
+lexstart(
+ struct vars *v)
{
- prefixes(v); /* may turn on new type bits etc. */
- NOERR();
+ prefixes(v); /* may turn on new type bits etc. */
+ NOERR();
- if (v->cflags&REG_QUOTE) {
- assert(!(v->cflags&(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE)));
- INTOCON(L_Q);
- } else if (v->cflags&REG_EXTENDED) {
- assert(!(v->cflags&REG_QUOTE));
- INTOCON(L_ERE);
- } else {
- assert(!(v->cflags&(REG_QUOTE|REG_ADVF)));
- INTOCON(L_BRE);
- }
+ if (v->cflags&REG_QUOTE) {
+ assert(!(v->cflags&(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE)));
+ INTOCON(L_Q);
+ } else if (v->cflags&REG_EXTENDED) {
+ assert(!(v->cflags&REG_QUOTE));
+ INTOCON(L_ERE);
+ } else {
+ assert(!(v->cflags&(REG_QUOTE|REG_ADVF)));
+ INTOCON(L_BRE);
+ }
- v->nexttype = EMPTY; /* remember we were at the start */
- next(v); /* set up the first token */
+ v->nexttype = EMPTY; /* remember we were at the start */
+ next(v); /* set up the first token */
}
-
+
/*
- prefixes - implement various special prefixes
^ static VOID prefixes(struct vars *);
*/
-static VOID
-prefixes(v)
-struct vars *v;
+static void
+prefixes(
+ struct vars *v)
{
- /* literal string doesn't get any of this stuff */
- if (v->cflags&REG_QUOTE)
- return;
+ /*
+ * Literal string doesn't get any of this stuff.
+ */
- /* initial "***" gets special things */
- if (HAVE(4) && NEXT3('*', '*', '*'))
- switch (*(v->now + 3)) {
- case CHR('?'): /* "***?" error, msg shows version */
- ERR(REG_BADPAT);
- return; /* proceed no further */
- break;
- case CHR('='): /* "***=" shifts to literal string */
- NOTE(REG_UNONPOSIX);
- v->cflags |= REG_QUOTE;
- v->cflags &= ~(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE);
- v->now += 4;
- return; /* and there can be no more prefixes */
- break;
- case CHR(':'): /* "***:" shifts to AREs */
- NOTE(REG_UNONPOSIX);
- v->cflags |= REG_ADVANCED;
- v->now += 4;
- break;
- default: /* otherwise *** is just an error */
- ERR(REG_BADRPT);
- return;
- break;
- }
+ if (v->cflags&REG_QUOTE) {
+ return;
+ }
- /* BREs and EREs don't get embedded options */
- if ((v->cflags&REG_ADVANCED) != REG_ADVANCED)
- return;
+ /*
+ * Initial "***" gets special things.
+ */
- /* embedded options (AREs only) */
- if (HAVE(3) && NEXT2('(', '?') && iscalpha(*(v->now + 2))) {
- NOTE(REG_UNONPOSIX);
- v->now += 2;
- for (; !ATEOS() && iscalpha(*v->now); v->now++)
- switch (*v->now) {
- case CHR('b'): /* BREs (but why???) */
- v->cflags &= ~(REG_ADVANCED|REG_QUOTE);
- break;
- case CHR('c'): /* case sensitive */
- v->cflags &= ~REG_ICASE;
- break;
- case CHR('e'): /* plain EREs */
- v->cflags |= REG_EXTENDED;
- v->cflags &= ~(REG_ADVF|REG_QUOTE);
- break;
- case CHR('i'): /* case insensitive */
- v->cflags |= REG_ICASE;
- break;
- case CHR('m'): /* Perloid synonym for n */
- case CHR('n'): /* \n affects ^ $ . [^ */
- v->cflags |= REG_NEWLINE;
- break;
- case CHR('p'): /* ~Perl, \n affects . [^ */
- v->cflags |= REG_NLSTOP;
- v->cflags &= ~REG_NLANCH;
- break;
- case CHR('q'): /* literal string */
- v->cflags |= REG_QUOTE;
- v->cflags &= ~REG_ADVANCED;
- break;
- case CHR('s'): /* single line, \n ordinary */
- v->cflags &= ~REG_NEWLINE;
- break;
- case CHR('t'): /* tight syntax */
- v->cflags &= ~REG_EXPANDED;
- break;
- case CHR('w'): /* weird, \n affects ^ $ only */
- v->cflags &= ~REG_NLSTOP;
- v->cflags |= REG_NLANCH;
- break;
- case CHR('x'): /* expanded syntax */
- v->cflags |= REG_EXPANDED;
- break;
- default:
- ERR(REG_BADOPT);
- return;
- }
- if (!NEXT1(')')) {
- ERR(REG_BADOPT);
- return;
- }
- v->now++;
- if (v->cflags&REG_QUOTE)
- v->cflags &= ~(REG_EXPANDED|REG_NEWLINE);
+ if (HAVE(4) && NEXT3('*', '*', '*')) {
+ switch (*(v->now + 3)) {
+ case CHR('?'): /* "***?" error, msg shows version */
+ ERR(REG_BADPAT);
+ return; /* proceed no further */
+ break;
+ case CHR('='): /* "***=" shifts to literal string */
+ NOTE(REG_UNONPOSIX);
+ v->cflags |= REG_QUOTE;
+ v->cflags &= ~(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE);
+ v->now += 4;
+ return; /* and there can be no more prefixes */
+ break;
+ case CHR(':'): /* "***:" shifts to AREs */
+ NOTE(REG_UNONPOSIX);
+ v->cflags |= REG_ADVANCED;
+ v->now += 4;
+ break;
+ default: /* otherwise *** is just an error */
+ ERR(REG_BADRPT);
+ return;
+ break;
}
-}
+ }
+ /*
+ * BREs and EREs don't get embedded options.
+ */
+
+ if ((v->cflags&REG_ADVANCED) != REG_ADVANCED) {
+ return;
+ }
+
+ /*
+ * Embedded options (AREs only).
+ */
+
+ if (HAVE(3) && NEXT2('(', '?') && iscalpha(*(v->now + 2))) {
+ NOTE(REG_UNONPOSIX);
+ v->now += 2;
+ for (; !ATEOS() && iscalpha(*v->now); v->now++) {
+ switch (*v->now) {
+ case CHR('b'): /* BREs (but why???) */
+ v->cflags &= ~(REG_ADVANCED|REG_QUOTE);
+ break;
+ case CHR('c'): /* case sensitive */
+ v->cflags &= ~REG_ICASE;
+ break;
+ case CHR('e'): /* plain EREs */
+ v->cflags |= REG_EXTENDED;
+ v->cflags &= ~(REG_ADVF|REG_QUOTE);
+ break;
+ case CHR('i'): /* case insensitive */
+ v->cflags |= REG_ICASE;
+ break;
+ case CHR('m'): /* Perloid synonym for n */
+ case CHR('n'): /* \n affects ^ $ . [^ */
+ v->cflags |= REG_NEWLINE;
+ break;
+ case CHR('p'): /* ~Perl, \n affects . [^ */
+ v->cflags |= REG_NLSTOP;
+ v->cflags &= ~REG_NLANCH;
+ break;
+ case CHR('q'): /* literal string */
+ v->cflags |= REG_QUOTE;
+ v->cflags &= ~REG_ADVANCED;
+ break;
+ case CHR('s'): /* single line, \n ordinary */
+ v->cflags &= ~REG_NEWLINE;
+ break;
+ case CHR('t'): /* tight syntax */
+ v->cflags &= ~REG_EXPANDED;
+ break;
+ case CHR('w'): /* weird, \n affects ^ $ only */
+ v->cflags &= ~REG_NLSTOP;
+ v->cflags |= REG_NLANCH;
+ break;
+ case CHR('x'): /* expanded syntax */
+ v->cflags |= REG_EXPANDED;
+ break;
+ default:
+ ERR(REG_BADOPT);
+ return;
+ }
+ }
+ if (!NEXT1(')')) {
+ ERR(REG_BADOPT);
+ return;
+ }
+ v->now++;
+ if (v->cflags&REG_QUOTE) {
+ v->cflags &= ~(REG_EXPANDED|REG_NEWLINE);
+ }
+ }
+}
+
/*
- lexnest - "call a subroutine", interpolating string at the lexical level
* Note, this is not a very general facility. There are a number of
* implicit assumptions about what sorts of strings can be subroutines.
- ^ static VOID lexnest(struct vars *, chr *, chr *);
+ ^ static VOID lexnest(struct vars *, const chr *, const chr *);
*/
-static VOID
-lexnest(v, beginp, endp)
-struct vars *v;
-chr *beginp; /* start of interpolation */
-chr *endp; /* one past end of interpolation */
+static void
+lexnest(
+ struct vars *v,
+ const chr *beginp, /* start of interpolation */
+ const chr *endp) /* one past end of interpolation */
{
- assert(v->savenow == NULL); /* only one level of nesting */
- v->savenow = v->now;
- v->savestop = v->stop;
- v->now = beginp;
- v->stop = endp;
+ assert(v->savenow == NULL); /* only one level of nesting */
+ v->savenow = v->now;
+ v->savestop = v->stop;
+ v->now = beginp;
+ v->stop = endp;
}
-
+
/*
* string constants to interpolate as expansions of things like \d
*/
-static chr backd[] = { /* \d */
- CHR('['), CHR('['), CHR(':'),
- CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'),
- CHR(':'), CHR(']'), CHR(']')
+
+static const chr backd[] = { /* \d */
+ CHR('['), CHR('['), CHR(':'),
+ CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'),
+ CHR(':'), CHR(']'), CHR(']')
};
-static chr backD[] = { /* \D */
- CHR('['), CHR('^'), CHR('['), CHR(':'),
- CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'),
- CHR(':'), CHR(']'), CHR(']')
+static const chr backD[] = { /* \D */
+ CHR('['), CHR('^'), CHR('['), CHR(':'),
+ CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'),
+ CHR(':'), CHR(']'), CHR(']')
};
-static chr brbackd[] = { /* \d within brackets */
- CHR('['), CHR(':'),
- CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'),
- CHR(':'), CHR(']')
+static const chr brbackd[] = { /* \d within brackets */
+ CHR('['), CHR(':'),
+ CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'),
+ CHR(':'), CHR(']')
};
-static chr backs[] = { /* \s */
- CHR('['), CHR('['), CHR(':'),
- CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
- CHR(':'), CHR(']'), CHR(']')
+static const chr backs[] = { /* \s */
+ CHR('['), CHR('['), CHR(':'),
+ CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
+ CHR(':'), CHR(']'), CHR(']')
};
-static chr backS[] = { /* \S */
- CHR('['), CHR('^'), CHR('['), CHR(':'),
- CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
- CHR(':'), CHR(']'), CHR(']')
+static const chr backS[] = { /* \S */
+ CHR('['), CHR('^'), CHR('['), CHR(':'),
+ CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
+ CHR(':'), CHR(']'), CHR(']')
};
-static chr brbacks[] = { /* \s within brackets */
- CHR('['), CHR(':'),
- CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
- CHR(':'), CHR(']')
+static const chr brbacks[] = { /* \s within brackets */
+ CHR('['), CHR(':'),
+ CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
+ CHR(':'), CHR(']')
};
-static chr backw[] = { /* \w */
- CHR('['), CHR('['), CHR(':'),
- CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
- CHR(':'), CHR(']'), CHR('_'), CHR(']')
+static const chr backw[] = { /* \w */
+ CHR('['), CHR('['), CHR(':'),
+ CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
+ CHR(':'), CHR(']'), CHR('_'), CHR(']')
};
-static chr backW[] = { /* \W */
- CHR('['), CHR('^'), CHR('['), CHR(':'),
- CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
- CHR(':'), CHR(']'), CHR('_'), CHR(']')
+static const chr backW[] = { /* \W */
+ CHR('['), CHR('^'), CHR('['), CHR(':'),
+ CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
+ CHR(':'), CHR(']'), CHR('_'), CHR(']')
};
-static chr brbackw[] = { /* \w within brackets */
- CHR('['), CHR(':'),
- CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
- CHR(':'), CHR(']'), CHR('_')
+static const chr brbackw[] = { /* \w within brackets */
+ CHR('['), CHR(':'),
+ CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
+ CHR(':'), CHR(']'), CHR('_')
};
-
+
/*
- lexword - interpolate a bracket expression for word characters
* Possibly ought to inquire whether there is a "word" character class.
^ static VOID lexword(struct vars *);
*/
-static VOID
-lexword(v)
-struct vars *v;
+static void
+lexword(
+ struct vars *v)
{
- lexnest(v, backw, ENDOF(backw));
+ lexnest(v, backw, ENDOF(backw));
}
-
+
/*
- next - get next token
^ static int next(struct vars *);
*/
static int /* 1 normal, 0 failure */
-next(v)
-struct vars *v;
+next(
+ struct vars *v)
{
- chr c;
+ chr c;
- /* errors yield an infinite sequence of failures */
- if (ISERR())
- return 0; /* the error has set nexttype to EOS */
+ /*
+ * Errors yield an infinite sequence of failures.
+ */
- /* remember flavor of last token */
- v->lasttype = v->nexttype;
+ if (ISERR()) {
+ return 0; /* the error has set nexttype to EOS */
+ }
- /* REG_BOSONLY */
- if (v->nexttype == EMPTY && (v->cflags&REG_BOSONLY)) {
- /* at start of a REG_BOSONLY RE */
- RETV(SBEGIN, 0); /* same as \A */
- }
+ /*
+ * Remember flavor of last token.
+ */
- /* if we're nested and we've hit end, return to outer level */
- if (v->savenow != NULL && ATEOS()) {
- v->now = v->savenow;
- v->stop = v->savestop;
- v->savenow = v->savestop = NULL;
- }
+ v->lasttype = v->nexttype;
- /* skip white space etc. if appropriate (not in literal or []) */
- if (v->cflags&REG_EXPANDED)
- switch (v->lexcon) {
- case L_ERE:
- case L_BRE:
- case L_EBND:
- case L_BBND:
- skip(v);
- break;
- }
+ /*
+ * REG_BOSONLY
+ */
- /* handle EOS, depending on context */
- if (ATEOS()) {
- switch (v->lexcon) {
- case L_ERE:
- case L_BRE:
- case L_Q:
- RET(EOS);
- break;
- case L_EBND:
- case L_BBND:
- FAILW(REG_EBRACE);
- break;
- case L_BRACK:
- case L_CEL:
- case L_ECL:
- case L_CCL:
- FAILW(REG_EBRACK);
- break;
- }
- assert(NOTREACHED);
+ if (v->nexttype == EMPTY && (v->cflags&REG_BOSONLY)) {
+ /* at start of a REG_BOSONLY RE */
+ RETV(SBEGIN, 0); /* same as \A */
+ }
+
+ /*
+ * If we're nested and we've hit end, return to outer level.
+ */
+
+ if (v->savenow != NULL && ATEOS()) {
+ v->now = v->savenow;
+ v->stop = v->savestop;
+ v->savenow = v->savestop = NULL;
+ }
+
+ /*
+ * Skip white space etc. if appropriate (not in literal or [])
+ */
+
+ if (v->cflags&REG_EXPANDED) {
+ switch (v->lexcon) {
+ case L_ERE:
+ case L_BRE:
+ case L_EBND:
+ case L_BBND:
+ skip(v);
+ break;
}
+ }
- /* okay, time to actually get a character */
- c = *v->now++;
+ /*
+ * Handle EOS, depending on context.
+ */
- /* deal with the easy contexts, punt EREs to code below */
+ if (ATEOS()) {
switch (v->lexcon) {
- case L_BRE: /* punt BREs to separate function */
- return brenext(v, c);
- break;
- case L_ERE: /* see below */
- break;
- case L_Q: /* literal strings are easy */
- RETV(PLAIN, c);
- break;
- case L_BBND: /* bounds are fairly simple */
+ case L_ERE:
+ case L_BRE:
+ case L_Q:
+ RET(EOS);
+ break;
case L_EBND:
- switch (c) {
- case CHR('0'): case CHR('1'): case CHR('2'): case CHR('3'):
- case CHR('4'): case CHR('5'): case CHR('6'): case CHR('7'):
- case CHR('8'): case CHR('9'):
- RETV(DIGIT, (chr)DIGITVAL(c));
- break;
- case CHR(','):
- RET(',');
- break;
- case CHR('}'): /* ERE bound ends with } */
- if (INCON(L_EBND)) {
- INTOCON(L_ERE);
- if ((v->cflags&REG_ADVF) && NEXT1('?')) {
- v->now++;
- NOTE(REG_UNONPOSIX);
- RETV('}', 0);
- }
- RETV('}', 1);
- } else
- FAILW(REG_BADBR);
- break;
- case CHR('\\'): /* BRE bound ends with \} */
- if (INCON(L_BBND) && NEXT1('}')) {
- v->now++;
- INTOCON(L_BRE);
- RET('}');
- } else
- FAILW(REG_BADBR);
- break;
- default:
- FAILW(REG_BADBR);
- break;
- }
- assert(NOTREACHED);
- break;
- case L_BRACK: /* brackets are not too hard */
- switch (c) {
- case CHR(']'):
- if (LASTTYPE('['))
- RETV(PLAIN, c);
- else {
- INTOCON((v->cflags&REG_EXTENDED) ?
- L_ERE : L_BRE);
- RET(']');
- }
- break;
- case CHR('\\'):
- NOTE(REG_UBBS);
- if (!(v->cflags&REG_ADVF))
- RETV(PLAIN, c);
- NOTE(REG_UNONPOSIX);
- if (ATEOS())
- FAILW(REG_EESCAPE);
- (DISCARD)lexescape(v);
- switch (v->nexttype) { /* not all escapes okay here */
- case PLAIN:
- return 1;
- break;
- case CCLASS:
- switch (v->nextvalue) {
- case 'd':
- lexnest(v, brbackd, ENDOF(brbackd));
- break;
- case 's':
- lexnest(v, brbacks, ENDOF(brbacks));
- break;
- case 'w':
- lexnest(v, brbackw, ENDOF(brbackw));
- break;
- default:
- FAILW(REG_EESCAPE);
- break;
- }
- /* lexnest done, back up and try again */
- v->nexttype = v->lasttype;
- return next(v);
- break;
- }
- /* not one of the acceptable escapes */
- FAILW(REG_EESCAPE);
- break;
- case CHR('-'):
- if (LASTTYPE('[') || NEXT1(']'))
- RETV(PLAIN, c);
- else
- RETV(RANGE, c);
- break;
- case CHR('['):
- if (ATEOS())
- FAILW(REG_EBRACK);
- switch (*v->now++) {
- case CHR('.'):
- INTOCON(L_CEL);
- /* might or might not be locale-specific */
- RET(COLLEL);
- break;
- case CHR('='):
- INTOCON(L_ECL);
- NOTE(REG_ULOCALE);
- RET(ECLASS);
- break;
- case CHR(':'):
- INTOCON(L_CCL);
- NOTE(REG_ULOCALE);
- RET(CCLASS);
- break;
- default: /* oops */
- v->now--;
- RETV(PLAIN, c);
- break;
- }
- assert(NOTREACHED);
- break;
- default:
- RETV(PLAIN, c);
- break;
- }
- assert(NOTREACHED);
- break;
- case L_CEL: /* collating elements are easy */
- if (c == CHR('.') && NEXT1(']')) {
- v->now++;
- INTOCON(L_BRACK);
- RETV(END, '.');
- } else
- RETV(PLAIN, c);
- break;
- case L_ECL: /* ditto equivalence classes */
- if (c == CHR('=') && NEXT1(']')) {
- v->now++;
- INTOCON(L_BRACK);
- RETV(END, '=');
- } else
- RETV(PLAIN, c);
- break;
- case L_CCL: /* ditto character classes */
- if (c == CHR(':') && NEXT1(']')) {
- v->now++;
- INTOCON(L_BRACK);
- RETV(END, ':');
- } else
- RETV(PLAIN, c);
- break;
- default:
- assert(NOTREACHED);
- break;
+ case L_BBND:
+ FAILW(REG_EBRACE);
+ break;
+ case L_BRACK:
+ case L_CEL:
+ case L_ECL:
+ case L_CCL:
+ FAILW(REG_EBRACK);
+ break;
}
+ assert(NOTREACHED);
+ }
+
+ /*
+ * Okay, time to actually get a character.
+ */
+
+ c = *v->now++;
- /* that got rid of everything except EREs and AREs */
- assert(INCON(L_ERE));
+ /*
+ * Deal with the easy contexts, punt EREs to code below.
+ */
- /* deal with EREs and AREs, except for backslashes */
+ switch (v->lexcon) {
+ case L_BRE: /* punt BREs to separate function */
+ return brenext(v, c);
+ break;
+ case L_ERE: /* see below */
+ break;
+ case L_Q: /* literal strings are easy */
+ RETV(PLAIN, c);
+ break;
+ case L_BBND: /* bounds are fairly simple */
+ case L_EBND:
switch (c) {
- case CHR('|'):
- RET('|');
- break;
- case CHR('*'):
+ case CHR('0'): case CHR('1'): case CHR('2'): case CHR('3'):
+ case CHR('4'): case CHR('5'): case CHR('6'): case CHR('7'):
+ case CHR('8'): case CHR('9'):
+ RETV(DIGIT, (chr)DIGITVAL(c));
+ break;
+ case CHR(','):
+ RET(',');
+ break;
+ case CHR('}'): /* ERE bound ends with } */
+ if (INCON(L_EBND)) {
+ INTOCON(L_ERE);
if ((v->cflags&REG_ADVF) && NEXT1('?')) {
- v->now++;
- NOTE(REG_UNONPOSIX);
- RETV('*', 0);
+ v->now++;
+ NOTE(REG_UNONPOSIX);
+ RETV('}', 0);
}
- RETV('*', 1);
+ RETV('}', 1);
+ } else {
+ FAILW(REG_BADBR);
+ }
+ break;
+ case CHR('\\'): /* BRE bound ends with \} */
+ if (INCON(L_BBND) && NEXT1('}')) {
+ v->now++;
+ INTOCON(L_BRE);
+ RET('}');
+ } else {
+ FAILW(REG_BADBR);
+ }
+ break;
+ default:
+ FAILW(REG_BADBR);
+ break;
+ }
+ assert(NOTREACHED);
+ break;
+ case L_BRACK: /* brackets are not too hard */
+ switch (c) {
+ case CHR(']'):
+ if (LASTTYPE('[')) {
+ RETV(PLAIN, c);
+ } else {
+ INTOCON((v->cflags&REG_EXTENDED) ? L_ERE : L_BRE);
+ RET(']');
+ }
+ break;
+ case CHR('\\'):
+ NOTE(REG_UBBS);
+ if (!(v->cflags&REG_ADVF)) {
+ RETV(PLAIN, c);
+ }
+ NOTE(REG_UNONPOSIX);
+ if (ATEOS()) {
+ FAILW(REG_EESCAPE);
+ }
+ (DISCARD)lexescape(v);
+ switch (v->nexttype) { /* not all escapes okay here */
+ case PLAIN:
+ return 1;
break;
- case CHR('+'):
- if ((v->cflags&REG_ADVF) && NEXT1('?')) {
- v->now++;
- NOTE(REG_UNONPOSIX);
- RETV('+', 0);
+ case CCLASS:
+ switch (v->nextvalue) {
+ case 'd':
+ lexnest(v, brbackd, ENDOF(brbackd));
+ break;
+ case 's':
+ lexnest(v, brbacks, ENDOF(brbacks));
+ break;
+ case 'w':
+ lexnest(v, brbackw, ENDOF(brbackw));
+ break;
+ default:
+ FAILW(REG_EESCAPE);
+ break;
}
- RETV('+', 1);
+
+ /*
+ * lexnest() done, back up and try again.
+ */
+
+ v->nexttype = v->lasttype;
+ return next(v);
break;
- case CHR('?'):
- if ((v->cflags&REG_ADVF) && NEXT1('?')) {
- v->now++;
- NOTE(REG_UNONPOSIX);
- RETV('?', 0);
- }
- RETV('?', 1);
+ }
+
+ /*
+ * Not one of the acceptable escapes.
+ */
+
+ FAILW(REG_EESCAPE);
+ break;
+ case CHR('-'):
+ if (LASTTYPE('[') || NEXT1(']')) {
+ RETV(PLAIN, c);
+ } else {
+ RETV(RANGE, c);
+ }
+ break;
+ case CHR('['):
+ if (ATEOS()) {
+ FAILW(REG_EBRACK);
+ }
+ switch (*v->now++) {
+ case CHR('.'):
+ INTOCON(L_CEL);
+
+ /*
+ * Might or might not be locale-specific.
+ */
+
+ RET(COLLEL);
break;
- case CHR('{'): /* bounds start or plain character */
- if (v->cflags&REG_EXPANDED)
- skip(v);
- if (ATEOS() || !iscdigit(*v->now)) {
- NOTE(REG_UBRACES);
- NOTE(REG_UUNSPEC);
- RETV(PLAIN, c);
- } else {
- NOTE(REG_UBOUNDS);
- INTOCON(L_EBND);
- RET('{');
- }
- assert(NOTREACHED);
+ case CHR('='):
+ INTOCON(L_ECL);
+ NOTE(REG_ULOCALE);
+ RET(ECLASS);
break;
- case CHR('('): /* parenthesis, or advanced extension */
- if ((v->cflags&REG_ADVF) && NEXT1('?')) {
- NOTE(REG_UNONPOSIX);
- v->now++;
- switch (*v->now++) {
- case CHR(':'): /* non-capturing paren */
- RETV('(', 0);
- break;
- case CHR('#'): /* comment */
- while (!ATEOS() && *v->now != CHR(')'))
- v->now++;
- if (!ATEOS())
- v->now++;
- assert(v->nexttype == v->lasttype);
- return next(v);
- break;
- case CHR('='): /* positive lookahead */
- NOTE(REG_ULOOKAHEAD);
- RETV(LACON, 1);
- break;
- case CHR('!'): /* negative lookahead */
- NOTE(REG_ULOOKAHEAD);
- RETV(LACON, 0);
- break;
- default:
- FAILW(REG_BADRPT);
- break;
- }
- assert(NOTREACHED);
- }
- if (v->cflags&REG_NOSUB)
- RETV('(', 0); /* all parens non-capturing */
- else
- RETV('(', 1);
+ case CHR(':'):
+ INTOCON(L_CCL);
+ NOTE(REG_ULOCALE);
+ RET(CCLASS);
break;
- case CHR(')'):
- if (LASTTYPE('(')) {
- NOTE(REG_UUNSPEC);
- }
- RETV(')', c);
+ default: /* oops */
+ v->now--;
+ RETV(PLAIN, c);
break;
- case CHR('['): /* easy except for [[:<:]] and [[:>:]] */
- if (HAVE(6) && *(v->now+0) == CHR('[') &&
- *(v->now+1) == CHR(':') &&
- (*(v->now+2) == CHR('<') ||
- *(v->now+2) == CHR('>')) &&
- *(v->now+3) == CHR(':') &&
- *(v->now+4) == CHR(']') &&
- *(v->now+5) == CHR(']')) {
- c = *(v->now+2);
- v->now += 6;
- NOTE(REG_UNONPOSIX);
- RET((c == CHR('<')) ? '<' : '>');
+ }
+ assert(NOTREACHED);
+ break;
+ default:
+ RETV(PLAIN, c);
+ break;
+ }
+ assert(NOTREACHED);
+ break;
+ case L_CEL: /* collating elements are easy */
+ if (c == CHR('.') && NEXT1(']')) {
+ v->now++;
+ INTOCON(L_BRACK);
+ RETV(END, '.');
+ } else {
+ RETV(PLAIN, c);
+ }
+ break;
+ case L_ECL: /* ditto equivalence classes */
+ if (c == CHR('=') && NEXT1(']')) {
+ v->now++;
+ INTOCON(L_BRACK);
+ RETV(END, '=');
+ } else {
+ RETV(PLAIN, c);
+ }
+ break;
+ case L_CCL: /* ditto character classes */
+ if (c == CHR(':') && NEXT1(']')) {
+ v->now++;
+ INTOCON(L_BRACK);
+ RETV(END, ':');
+ } else {
+ RETV(PLAIN, c);
+ }
+ break;
+ default:
+ assert(NOTREACHED);
+ break;
+ }
+
+ /*
+ * That got rid of everything except EREs and AREs.
+ */
+
+ assert(INCON(L_ERE));
+
+ /*
+ * Deal with EREs and AREs, except for backslashes.
+ */
+
+ switch (c) {
+ case CHR('|'):
+ RET('|');
+ break;
+ case CHR('*'):
+ if ((v->cflags&REG_ADVF) && NEXT1('?')) {
+ v->now++;
+ NOTE(REG_UNONPOSIX);
+ RETV('*', 0);
+ }
+ RETV('*', 1);
+ break;
+ case CHR('+'):
+ if ((v->cflags&REG_ADVF) && NEXT1('?')) {
+ v->now++;
+ NOTE(REG_UNONPOSIX);
+ RETV('+', 0);
+ }
+ RETV('+', 1);
+ break;
+ case CHR('?'):
+ if ((v->cflags&REG_ADVF) && NEXT1('?')) {
+ v->now++;
+ NOTE(REG_UNONPOSIX);
+ RETV('?', 0);
+ }
+ RETV('?', 1);
+ break;
+ case CHR('{'): /* bounds start or plain character */
+ if (v->cflags&REG_EXPANDED) {
+ skip(v);
+ }
+ if (ATEOS() || !iscdigit(*v->now)) {
+ NOTE(REG_UBRACES);
+ NOTE(REG_UUNSPEC);
+ RETV(PLAIN, c);
+ } else {
+ NOTE(REG_UBOUNDS);
+ INTOCON(L_EBND);
+ RET('{');
+ }
+ assert(NOTREACHED);
+ break;
+ case CHR('('): /* parenthesis, or advanced extension */
+ if ((v->cflags&REG_ADVF) && NEXT1('?')) {
+ NOTE(REG_UNONPOSIX);
+ v->now++;
+ switch (*v->now++) {
+ case CHR(':'): /* non-capturing paren */
+ RETV('(', 0);
+ break;
+ case CHR('#'): /* comment */
+ while (!ATEOS() && *v->now != CHR(')')) {
+ v->now++;
}
- INTOCON(L_BRACK);
- if (NEXT1('^')) {
- v->now++;
- RETV('[', 0);
+ if (!ATEOS()) {
+ v->now++;
}
- RETV('[', 1);
- break;
- case CHR('.'):
- RET('.');
+ assert(v->nexttype == v->lasttype);
+ return next(v);
break;
- case CHR('^'):
- RET('^');
+ case CHR('='): /* positive lookahead */
+ NOTE(REG_ULOOKAHEAD);
+ RETV(LACON, 1);
break;
- case CHR('$'):
- RET('$');
+ case CHR('!'): /* negative lookahead */
+ NOTE(REG_ULOOKAHEAD);
+ RETV(LACON, 0);
break;
- case CHR('\\'): /* mostly punt backslashes to code below */
- if (ATEOS())
- FAILW(REG_EESCAPE);
- break;
- default: /* ordinary character */
- RETV(PLAIN, c);
+ default:
+ FAILW(REG_BADRPT);
break;
+ }
+ assert(NOTREACHED);
+ }
+ if (v->cflags&REG_NOSUB) {
+ RETV('(', 0); /* all parens non-capturing */
+ } else {
+ RETV('(', 1);
+ }
+ break;
+ case CHR(')'):
+ if (LASTTYPE('(')) {
+ NOTE(REG_UUNSPEC);
+ }
+ RETV(')', c);
+ break;
+ case CHR('['): /* easy except for [[:<:]] and [[:>:]] */
+ if (HAVE(6) && *(v->now+0) == CHR('[') &&
+ *(v->now+1) == CHR(':') &&
+ (*(v->now+2) == CHR('<') || *(v->now+2) == CHR('>')) &&
+ *(v->now+3) == CHR(':') &&
+ *(v->now+4) == CHR(']') &&
+ *(v->now+5) == CHR(']')) {
+ c = *(v->now+2);
+ v->now += 6;
+ NOTE(REG_UNONPOSIX);
+ RET((c == CHR('<')) ? '<' : '>');
+ }
+ INTOCON(L_BRACK);
+ if (NEXT1('^')) {
+ v->now++;
+ RETV('[', 0);
+ }
+ RETV('[', 1);
+ break;
+ case CHR('.'):
+ RET('.');
+ break;
+ case CHR('^'):
+ RET('^');
+ break;
+ case CHR('$'):
+ RET('$');
+ break;
+ case CHR('\\'): /* mostly punt backslashes to code below */
+ if (ATEOS()) {
+ FAILW(REG_EESCAPE);
}
+ break;
+ default: /* ordinary character */
+ RETV(PLAIN, c);
+ break;
+ }
- /* ERE/ARE backslash handling; backslash already eaten */
- assert(!ATEOS());
- if (!(v->cflags&REG_ADVF)) { /* only AREs have non-trivial escapes */
- if (iscalnum(*v->now)) {
- NOTE(REG_UBSALNUM);
- NOTE(REG_UUNSPEC);
- }
- RETV(PLAIN, *v->now++);
+ /*
+ * ERE/ARE backslash handling; backslash already eaten.
+ */
+
+ assert(!ATEOS());
+ if (!(v->cflags&REG_ADVF)) {/* only AREs have non-trivial escapes */
+ if (iscalnum(*v->now)) {
+ NOTE(REG_UBSALNUM);
+ NOTE(REG_UUNSPEC);
}
- (DISCARD)lexescape(v);
- if (ISERR())
- FAILW(REG_EESCAPE);
- if (v->nexttype == CCLASS) { /* fudge at lexical level */
- switch (v->nextvalue) {
- case 'd': lexnest(v, backd, ENDOF(backd)); break;
- case 'D': lexnest(v, backD, ENDOF(backD)); break;
- case 's': lexnest(v, backs, ENDOF(backs)); break;
- case 'S': lexnest(v, backS, ENDOF(backS)); break;
- case 'w': lexnest(v, backw, ENDOF(backw)); break;
- case 'W': lexnest(v, backW, ENDOF(backW)); break;
- default:
- assert(NOTREACHED);
- FAILW(REG_ASSERT);
- break;
- }
- /* lexnest done, back up and try again */
- v->nexttype = v->lasttype;
- return next(v);
+ RETV(PLAIN, *v->now++);
+ }
+ (DISCARD)lexescape(v);
+ if (ISERR()) {
+ FAILW(REG_EESCAPE);
+ }
+ if (v->nexttype == CCLASS) {/* fudge at lexical level */
+ switch (v->nextvalue) {
+ case 'd': lexnest(v, backd, ENDOF(backd)); break;
+ case 'D': lexnest(v, backD, ENDOF(backD)); break;
+ case 's': lexnest(v, backs, ENDOF(backs)); break;
+ case 'S': lexnest(v, backS, ENDOF(backS)); break;
+ case 'w': lexnest(v, backw, ENDOF(backw)); break;
+ case 'W': lexnest(v, backW, ENDOF(backW)); break;
+ default:
+ assert(NOTREACHED);
+ FAILW(REG_ASSERT);
+ break;
}
- /* otherwise, lexescape has already done the work */
- return !ISERR();
-}
+ /* lexnest done, back up and try again */
+ v->nexttype = v->lasttype;
+ return next(v);
+ }
+
+ /*
+ * Otherwise, lexescape has already done the work.
+ */
+ return !ISERR();
+}
+
/*
- lexescape - parse an ARE backslash escape (backslash already eaten)
* Note slightly nonstandard use of the CCLASS type code.
^ static int lexescape(struct vars *);
*/
static int /* not actually used, but convenient for RETV */
-lexescape(v)
-struct vars *v;
+lexescape(
+ struct vars *v)
{
- chr c;
- static chr alert[] = {
- CHR('a'), CHR('l'), CHR('e'), CHR('r'), CHR('t')
- };
- static chr esc[] = {
- CHR('E'), CHR('S'), CHR('C')
- };
- chr *save;
-
- assert(v->cflags&REG_ADVF);
-
- assert(!ATEOS());
- c = *v->now++;
- if (!iscalnum(c))
- RETV(PLAIN, c);
+ chr c;
+ static chr alert[] = {
+ CHR('a'), CHR('l'), CHR('e'), CHR('r'), CHR('t')
+ };
+ static chr esc[] = {
+ CHR('E'), CHR('S'), CHR('C')
+ };
+ const chr *save;
- NOTE(REG_UNONPOSIX);
- switch (c) {
- case CHR('a'):
- RETV(PLAIN, chrnamed(v, alert, ENDOF(alert), CHR('\007')));
- break;
- case CHR('A'):
- RETV(SBEGIN, 0);
- break;
- case CHR('b'):
- RETV(PLAIN, CHR('\b'));
- break;
- case CHR('B'):
- RETV(PLAIN, CHR('\\'));
- break;
- case CHR('c'):
- NOTE(REG_UUNPORT);
- if (ATEOS())
- FAILW(REG_EESCAPE);
- RETV(PLAIN, (chr)(*v->now++ & 037));
- break;
- case CHR('d'):
- NOTE(REG_ULOCALE);
- RETV(CCLASS, 'd');
- break;
- case CHR('D'):
- NOTE(REG_ULOCALE);
- RETV(CCLASS, 'D');
- break;
- case CHR('e'):
- NOTE(REG_UUNPORT);
- RETV(PLAIN, chrnamed(v, esc, ENDOF(esc), CHR('\033')));
- break;
- case CHR('f'):
- RETV(PLAIN, CHR('\f'));
- break;
- case CHR('m'):
- RET('<');
- break;
- case CHR('M'):
- RET('>');
- break;
- case CHR('n'):
- RETV(PLAIN, CHR('\n'));
- break;
- case CHR('r'):
- RETV(PLAIN, CHR('\r'));
- break;
- case CHR('s'):
- NOTE(REG_ULOCALE);
- RETV(CCLASS, 's');
- break;
- case CHR('S'):
- NOTE(REG_ULOCALE);
- RETV(CCLASS, 'S');
- break;
- case CHR('t'):
- RETV(PLAIN, CHR('\t'));
- break;
- case CHR('u'):
- c = lexdigits(v, 16, 4, 4);
- if (ISERR())
- FAILW(REG_EESCAPE);
- RETV(PLAIN, c);
- break;
- case CHR('U'):
- c = lexdigits(v, 16, 8, 8);
- if (ISERR())
- FAILW(REG_EESCAPE);
- RETV(PLAIN, c);
- break;
- case CHR('v'):
- RETV(PLAIN, CHR('\v'));
- break;
- case CHR('w'):
- NOTE(REG_ULOCALE);
- RETV(CCLASS, 'w');
- break;
- case CHR('W'):
- NOTE(REG_ULOCALE);
- RETV(CCLASS, 'W');
- break;
- case CHR('x'):
- NOTE(REG_UUNPORT);
- c = lexdigits(v, 16, 1, 255); /* REs >255 long outside spec */
- if (ISERR())
- FAILW(REG_EESCAPE);
- RETV(PLAIN, c);
- break;
- case CHR('y'):
- NOTE(REG_ULOCALE);
- RETV(WBDRY, 0);
- break;
- case CHR('Y'):
- NOTE(REG_ULOCALE);
- RETV(NWBDRY, 0);
- break;
- case CHR('Z'):
- RETV(SEND, 0);
- break;
- case CHR('1'): case CHR('2'): case CHR('3'): case CHR('4'):
- case CHR('5'): case CHR('6'): case CHR('7'): case CHR('8'):
- case CHR('9'):
- save = v->now;
- v->now--; /* put first digit back */
- c = lexdigits(v, 10, 1, 255); /* REs >255 long outside spec */
- if (ISERR())
- FAILW(REG_EESCAPE);
- /* ugly heuristic (first test is "exactly 1 digit?") */
- if (v->now-save == 0 || ((int)c > 0 && (int)c <= v->nsubexp)) {
- NOTE(REG_UBACKREF);
- RETV(BACKREF, (chr)c);
- }
- /* oops, doesn't look like it's a backref after all... */
- v->now = save;
- /* and fall through into octal number */
- case CHR('0'):
- NOTE(REG_UUNPORT);
- v->now--; /* put first digit back */
- c = lexdigits(v, 8, 1, 3);
- if (ISERR())
- FAILW(REG_EESCAPE);
- RETV(PLAIN, c);
- break;
- default:
- assert(iscalpha(c));
- FAILW(REG_EESCAPE); /* unknown alphabetic escape */
- break;
+ assert(v->cflags&REG_ADVF);
+
+ assert(!ATEOS());
+ c = *v->now++;
+ if (!iscalnum(c)) {
+ RETV(PLAIN, c);
+ }
+
+ NOTE(REG_UNONPOSIX);
+ switch (c) {
+ case CHR('a'):
+ RETV(PLAIN, chrnamed(v, alert, ENDOF(alert), CHR('\007')));
+ break;
+ case CHR('A'):
+ RETV(SBEGIN, 0);
+ break;
+ case CHR('b'):
+ RETV(PLAIN, CHR('\b'));
+ break;
+ case CHR('B'):
+ RETV(PLAIN, CHR('\\'));
+ break;
+ case CHR('c'):
+ NOTE(REG_UUNPORT);
+ if (ATEOS()) {
+ FAILW(REG_EESCAPE);
}
- assert(NOTREACHED);
-}
+ RETV(PLAIN, (chr)(*v->now++ & 037));
+ break;
+ case CHR('d'):
+ NOTE(REG_ULOCALE);
+ RETV(CCLASS, 'd');
+ break;
+ case CHR('D'):
+ NOTE(REG_ULOCALE);
+ RETV(CCLASS, 'D');
+ break;
+ case CHR('e'):
+ NOTE(REG_UUNPORT);
+ RETV(PLAIN, chrnamed(v, esc, ENDOF(esc), CHR('\033')));
+ break;
+ case CHR('f'):
+ RETV(PLAIN, CHR('\f'));
+ break;
+ case CHR('m'):
+ RET('<');
+ break;
+ case CHR('M'):
+ RET('>');
+ break;
+ case CHR('n'):
+ RETV(PLAIN, CHR('\n'));
+ break;
+ case CHR('r'):
+ RETV(PLAIN, CHR('\r'));
+ break;
+ case CHR('s'):
+ NOTE(REG_ULOCALE);
+ RETV(CCLASS, 's');
+ break;
+ case CHR('S'):
+ NOTE(REG_ULOCALE);
+ RETV(CCLASS, 'S');
+ break;
+ case CHR('t'):
+ RETV(PLAIN, CHR('\t'));
+ break;
+ case CHR('u'):
+ c = lexdigits(v, 16, 4, 4);
+ if (ISERR()) {
+ FAILW(REG_EESCAPE);
+ }
+ RETV(PLAIN, c);
+ break;
+ case CHR('U'):
+ c = lexdigits(v, 16, 8, 8);
+ if (ISERR()) {
+ FAILW(REG_EESCAPE);
+ }
+ RETV(PLAIN, c);
+ break;
+ case CHR('v'):
+ RETV(PLAIN, CHR('\v'));
+ break;
+ case CHR('w'):
+ NOTE(REG_ULOCALE);
+ RETV(CCLASS, 'w');
+ break;
+ case CHR('W'):
+ NOTE(REG_ULOCALE);
+ RETV(CCLASS, 'W');
+ break;
+ case CHR('x'):
+ NOTE(REG_UUNPORT);
+ c = lexdigits(v, 16, 1, 255); /* REs >255 long outside spec */
+ if (ISERR()) {
+ FAILW(REG_EESCAPE);
+ }
+ RETV(PLAIN, c);
+ break;
+ case CHR('y'):
+ NOTE(REG_ULOCALE);
+ RETV(WBDRY, 0);
+ break;
+ case CHR('Y'):
+ NOTE(REG_ULOCALE);
+ RETV(NWBDRY, 0);
+ break;
+ case CHR('Z'):
+ RETV(SEND, 0);
+ break;
+ case CHR('1'): case CHR('2'): case CHR('3'): case CHR('4'):
+ case CHR('5'): case CHR('6'): case CHR('7'): case CHR('8'):
+ case CHR('9'):
+ save = v->now;
+ v->now--; /* put first digit back */
+ c = lexdigits(v, 10, 1, 255); /* REs >255 long outside spec */
+ if (ISERR()) {
+ FAILW(REG_EESCAPE);
+ }
+
+ /*
+ * Ugly heuristic (first test is "exactly 1 digit?")
+ */
+
+ if (v->now - save == 0 || ((int) c > 0 && (int)c <= v->nsubexp)) {
+ NOTE(REG_UBACKREF);
+ RETV(BACKREF, (chr)c);
+ }
+
+ /*
+ * Oops, doesn't look like it's a backref after all...
+ */
+ v->now = save;
+
+ /*
+ * And fall through into octal number.
+ */
+
+ case CHR('0'):
+ NOTE(REG_UUNPORT);
+ v->now--; /* put first digit back */
+ c = lexdigits(v, 8, 1, 3);
+ if (ISERR()) {
+ FAILW(REG_EESCAPE);
+ }
+ RETV(PLAIN, c);
+ break;
+ default:
+ assert(iscalpha(c));
+ FAILW(REG_EESCAPE); /* unknown alphabetic escape */
+ break;
+ }
+ assert(NOTREACHED);
+}
+
/*
- lexdigits - slurp up digits and return chr value
^ static chr lexdigits(struct vars *, int, int, int);
*/
static chr /* chr value; errors signalled via ERR */
-lexdigits(v, base, minlen, maxlen)
-struct vars *v;
-int base;
-int minlen;
-int maxlen;
+lexdigits(
+ struct vars *v,
+ int base,
+ int minlen,
+ int maxlen)
{
- uchr n; /* unsigned to avoid overflow misbehavior */
- int len;
- chr c;
- int d;
- CONST uchr ub = (uchr) base;
-
- n = 0;
- for (len = 0; len < maxlen && !ATEOS(); len++) {
- c = *v->now++;
- switch (c) {
- case CHR('0'): case CHR('1'): case CHR('2'): case CHR('3'):
- case CHR('4'): case CHR('5'): case CHR('6'): case CHR('7'):
- case CHR('8'): case CHR('9'):
- d = DIGITVAL(c);
- break;
- case CHR('a'): case CHR('A'): d = 10; break;
- case CHR('b'): case CHR('B'): d = 11; break;
- case CHR('c'): case CHR('C'): d = 12; break;
- case CHR('d'): case CHR('D'): d = 13; break;
- case CHR('e'): case CHR('E'): d = 14; break;
- case CHR('f'): case CHR('F'): d = 15; break;
- default:
- v->now--; /* oops, not a digit at all */
- d = -1;
- break;
- }
+ uchr n; /* unsigned to avoid overflow misbehavior */
+ int len;
+ chr c;
+ int d;
+ CONST uchr ub = (uchr) base;
- if (d >= base) { /* not a plausible digit */
- v->now--;
- d = -1;
- }
- if (d < 0)
- break; /* NOTE BREAK OUT */
- n = n*ub + (uchr)d;
+ n = 0;
+ for (len = 0; len < maxlen && !ATEOS(); len++) {
+ c = *v->now++;
+ switch (c) {
+ case CHR('0'): case CHR('1'): case CHR('2'): case CHR('3'):
+ case CHR('4'): case CHR('5'): case CHR('6'): case CHR('7'):
+ case CHR('8'): case CHR('9'):
+ d = DIGITVAL(c);
+ break;
+ case CHR('a'): case CHR('A'): d = 10; break;
+ case CHR('b'): case CHR('B'): d = 11; break;
+ case CHR('c'): case CHR('C'): d = 12; break;
+ case CHR('d'): case CHR('D'): d = 13; break;
+ case CHR('e'): case CHR('E'): d = 14; break;
+ case CHR('f'): case CHR('F'): d = 15; break;
+ default:
+ v->now--; /* oops, not a digit at all */
+ d = -1;
+ break;
}
- if (len < minlen)
- ERR(REG_EESCAPE);
- return (chr)n;
-}
+ if (d >= base) { /* not a plausible digit */
+ v->now--;
+ d = -1;
+ }
+ if (d < 0) {
+ break; /* NOTE BREAK OUT */
+ }
+ n = n*ub + (uchr)d;
+ }
+ if (len < minlen) {
+ ERR(REG_EESCAPE);
+ }
+ return (chr)n;
+}
+
/*
- brenext - get next BRE token
* This is much like EREs except for all the stupid backslashes and the
@@ -865,197 +968,218 @@ int maxlen;
^ static int brenext(struct vars *, pchr);
*/
static int /* 1 normal, 0 failure */
-brenext(v, pc)
-struct vars *v;
-pchr pc;
+brenext(
+ struct vars *v,
+ pchr pc)
{
- chr c = (chr)pc;
+ chr c = (chr)pc;
- switch (c) {
- case CHR('*'):
- if (LASTTYPE(EMPTY) || LASTTYPE('(') || LASTTYPE('^'))
- RETV(PLAIN, c);
- RET('*');
- break;
- case CHR('['):
- if (HAVE(6) && *(v->now+0) == CHR('[') &&
- *(v->now+1) == CHR(':') &&
- (*(v->now+2) == CHR('<') ||
- *(v->now+2) == CHR('>')) &&
- *(v->now+3) == CHR(':') &&
- *(v->now+4) == CHR(']') &&
- *(v->now+5) == CHR(']')) {
- c = *(v->now+2);
- v->now += 6;
- NOTE(REG_UNONPOSIX);
- RET((c == CHR('<')) ? '<' : '>');
- }
- INTOCON(L_BRACK);
- if (NEXT1('^')) {
- v->now++;
- RETV('[', 0);
- }
- RETV('[', 1);
- break;
- case CHR('.'):
- RET('.');
- break;
- case CHR('^'):
- if (LASTTYPE(EMPTY))
- RET('^');
- if (LASTTYPE('(')) {
- NOTE(REG_UUNSPEC);
- RET('^');
- }
- RETV(PLAIN, c);
- break;
- case CHR('$'):
- if (v->cflags&REG_EXPANDED)
- skip(v);
- if (ATEOS())
- RET('$');
- if (NEXT2('\\', ')')) {
- NOTE(REG_UUNSPEC);
- RET('$');
- }
- RETV(PLAIN, c);
- break;
- case CHR('\\'):
- break; /* see below */
- default:
- RETV(PLAIN, c);
- break;
+ switch (c) {
+ case CHR('*'):
+ if (LASTTYPE(EMPTY) || LASTTYPE('(') || LASTTYPE('^')) {
+ RETV(PLAIN, c);
+ }
+ RET('*');
+ break;
+ case CHR('['):
+ if (HAVE(6) && *(v->now+0) == CHR('[') &&
+ *(v->now+1) == CHR(':') &&
+ (*(v->now+2) == CHR('<') || *(v->now+2) == CHR('>')) &&
+ *(v->now+3) == CHR(':') &&
+ *(v->now+4) == CHR(']') &&
+ *(v->now+5) == CHR(']')) {
+ c = *(v->now+2);
+ v->now += 6;
+ NOTE(REG_UNONPOSIX);
+ RET((c == CHR('<')) ? '<' : '>');
+ }
+ INTOCON(L_BRACK);
+ if (NEXT1('^')) {
+ v->now++;
+ RETV('[', 0);
+ }
+ RETV('[', 1);
+ break;
+ case CHR('.'):
+ RET('.');
+ break;
+ case CHR('^'):
+ if (LASTTYPE(EMPTY)) {
+ RET('^');
+ }
+ if (LASTTYPE('(')) {
+ NOTE(REG_UUNSPEC);
+ RET('^');
}
+ RETV(PLAIN, c);
+ break;
+ case CHR('$'):
+ if (v->cflags&REG_EXPANDED) {
+ skip(v);
+ }
+ if (ATEOS()) {
+ RET('$');
+ }
+ if (NEXT2('\\', ')')) {
+ NOTE(REG_UUNSPEC);
+ RET('$');
+ }
+ RETV(PLAIN, c);
+ break;
+ case CHR('\\'):
+ break; /* see below */
+ default:
+ RETV(PLAIN, c);
+ break;
+ }
- assert(c == CHR('\\'));
+ assert(c == CHR('\\'));
- if (ATEOS())
- FAILW(REG_EESCAPE);
+ if (ATEOS()) {
+ FAILW(REG_EESCAPE);
+ }
- c = *v->now++;
- switch (c) {
- case CHR('{'):
- INTOCON(L_BBND);
- NOTE(REG_UBOUNDS);
- RET('{');
- break;
- case CHR('('):
- RETV('(', 1);
- break;
- case CHR(')'):
- RETV(')', c);
- break;
- case CHR('<'):
- NOTE(REG_UNONPOSIX);
- RET('<');
- break;
- case CHR('>'):
- NOTE(REG_UNONPOSIX);
- RET('>');
- break;
- case CHR('1'): case CHR('2'): case CHR('3'): case CHR('4'):
- case CHR('5'): case CHR('6'): case CHR('7'): case CHR('8'):
- case CHR('9'):
- NOTE(REG_UBACKREF);
- RETV(BACKREF, (chr)DIGITVAL(c));
- break;
- default:
- if (iscalnum(c)) {
- NOTE(REG_UBSALNUM);
- NOTE(REG_UUNSPEC);
- }
- RETV(PLAIN, c);
- break;
+ c = *v->now++;
+ switch (c) {
+ case CHR('{'):
+ INTOCON(L_BBND);
+ NOTE(REG_UBOUNDS);
+ RET('{');
+ break;
+ case CHR('('):
+ RETV('(', 1);
+ break;
+ case CHR(')'):
+ RETV(')', c);
+ break;
+ case CHR('<'):
+ NOTE(REG_UNONPOSIX);
+ RET('<');
+ break;
+ case CHR('>'):
+ NOTE(REG_UNONPOSIX);
+ RET('>');
+ break;
+ case CHR('1'): case CHR('2'): case CHR('3'): case CHR('4'):
+ case CHR('5'): case CHR('6'): case CHR('7'): case CHR('8'):
+ case CHR('9'):
+ NOTE(REG_UBACKREF);
+ RETV(BACKREF, (chr)DIGITVAL(c));
+ break;
+ default:
+ if (iscalnum(c)) {
+ NOTE(REG_UBSALNUM);
+ NOTE(REG_UUNSPEC);
}
+ RETV(PLAIN, c);
+ break;
+ }
- assert(NOTREACHED);
+ assert(NOTREACHED);
}
-
+
/*
- skip - skip white space and comments in expanded form
^ static VOID skip(struct vars *);
*/
-static VOID
-skip(v)
-struct vars *v;
+static void
+skip(
+ struct vars *v)
{
- chr *start = v->now;
-
- assert(v->cflags&REG_EXPANDED);
-
- for (;;) {
- while (!ATEOS() && iscspace(*v->now))
- v->now++;
- if (ATEOS() || *v->now != CHR('#'))
- break; /* NOTE BREAK OUT */
- assert(NEXT1('#'));
- while (!ATEOS() && *v->now != CHR('\n'))
- v->now++;
- /* leave the newline to be picked up by the iscspace loop */
+ const chr *start = v->now;
+
+ assert(v->cflags&REG_EXPANDED);
+
+ for (;;) {
+ while (!ATEOS() && iscspace(*v->now)) {
+ v->now++;
+ }
+ if (ATEOS() || *v->now != CHR('#')) {
+ break; /* NOTE BREAK OUT */
+ }
+ assert(NEXT1('#'));
+ while (!ATEOS() && *v->now != CHR('\n')) {
+ v->now++;
}
- if (v->now != start)
- NOTE(REG_UNONPOSIX);
-}
+ /*
+ * Leave the newline to be picked up by the iscspace loop.
+ */
+ }
+ if (v->now != start) {
+ NOTE(REG_UNONPOSIX);
+ }
+}
+
/*
- newline - return the chr for a newline
* This helps confine use of CHR to this source file.
^ static chr newline(NOPARMS);
*/
static chr
-newline()
+newline(void)
{
- return CHR('\n');
+ return CHR('\n');
}
-
+
/*
- ch - return the chr sequence for regc_locale.c's fake collating element ch
* This helps confine use of CHR to this source file. Beware that the caller
* knows how long the sequence is.
^ #ifdef REG_DEBUG
- ^ static chr *ch(NOPARMS);
+ ^ static const chr *ch(NOPARMS);
^ #endif
*/
#ifdef REG_DEBUG
-static chr *
-ch()
+static const chr *
+ch(void)
{
- static chr chstr[] = { CHR('c'), CHR('h'), CHR('\0') };
+ static chr chstr[] = { CHR('c'), CHR('h'), CHR('\0') };
- return chstr;
+ return chstr;
}
#endif
-
+
/*
- chrnamed - return the chr known by a given (chr string) name
* The code is a bit clumsy, but this routine gets only such specialized
* use that it hardly matters.
- ^ static chr chrnamed(struct vars *, chr *, chr *, pchr);
+ ^ static chr chrnamed(struct vars *, const chr *, const chr *, pchr);
*/
static chr
-chrnamed(v, startp, endp, lastresort)
-struct vars *v;
-chr *startp; /* start of name */
-chr *endp; /* just past end of name */
-pchr lastresort; /* what to return if name lookup fails */
+chrnamed(
+ struct vars *v,
+ const chr *startp, /* start of name */
+ const chr *endp, /* just past end of name */
+ pchr lastresort) /* what to return if name lookup fails */
{
- celt c;
- int errsave;
- int e;
- struct cvec *cv;
-
- errsave = v->err;
- v->err = 0;
- c = element(v, startp, endp);
- e = v->err;
- v->err = errsave;
-
- if (e != 0)
- return (chr)lastresort;
-
- cv = range(v, c, c, 0);
- if (cv->nchrs == 0)
- return (chr)lastresort;
- return cv->chrs[0];
+ celt c;
+ int errsave;
+ int e;
+ struct cvec *cv;
+
+ errsave = v->err;
+ v->err = 0;
+ c = element(v, startp, endp);
+ e = v->err;
+ v->err = errsave;
+
+ if (e != 0) {
+ return (chr)lastresort;
+ }
+
+ cv = range(v, c, c, 0);
+ if (cv->nchrs == 0) {
+ return (chr)lastresort;
+ }
+ return cv->chrs[0];
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regc_locale.c b/generic/regc_locale.c
index 6c421d7..188d6de 100644
--- a/generic/regc_locale.c
+++ b/generic/regc_locale.c
@@ -12,9 +12,9 @@
/* ASCII character-name table */
-static CONST struct cname {
- CONST char *name;
- CONST char code;
+static const struct cname {
+ const char *name;
+ const char code;
} cnames[] = {
{"NUL", '\0'},
{"SOH", '\001'},
@@ -133,7 +133,7 @@ typedef struct crange {
* Unicode: alphabetic characters.
*/
-static CONST crange alphaRangeTable[] = {
+static const crange alphaRangeTable[] = {
{0x41, 0x5a}, {0x61, 0x7a}, {0xc0, 0xd6}, {0xd8, 0xf6},
{0xf8, 0x2c1}, {0x2c6, 0x2d1}, {0x2e0, 0x2e4}, {0x370, 0x374},
{0x37a, 0x37d}, {0x388, 0x38a}, {0x38e, 0x3a1}, {0x3a3, 0x3f5},
@@ -224,7 +224,7 @@ static CONST crange alphaRangeTable[] = {
#define NUM_ALPHA_RANGE (sizeof(alphaRangeTable)/sizeof(crange))
-static CONST chr alphaCharTable[] = {
+static const chr alphaCharTable[] = {
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,
@@ -258,7 +258,7 @@ static CONST chr alphaCharTable[] = {
* Unicode: control characters.
*/
-static CONST crange controlRangeTable[] = {
+static const crange controlRangeTable[] = {
{0x7f, 0x9f}, {0x600, 0x604}, {0x200b, 0x200f}, {0x202a, 0x202e},
{0x2060, 0x2064}, {0x206a, 0x206f}, {0xe000, 0xf8ff}, {0xfff9, 0xfffb}
#if TCL_UTF_MAX > 4
@@ -268,7 +268,7 @@ static CONST crange controlRangeTable[] = {
#define NUM_CONTROL_RANGE (sizeof(controlRangeTable)/sizeof(crange))
-static CONST chr controlCharTable[] = {
+static const chr controlCharTable[] = {
0xad, 0x6dd, 0x70f, 0xfeff
#if TCL_UTF_MAX > 4
,0x110bd, 0xe0001
@@ -281,7 +281,7 @@ static CONST chr controlCharTable[] = {
* Unicode: decimal digit characters.
*/
-static CONST crange digitRangeTable[] = {
+static const crange digitRangeTable[] = {
{0x30, 0x39}, {0x660, 0x669}, {0x6f0, 0x6f9}, {0x7c0, 0x7c9},
{0x966, 0x96f}, {0x9e6, 0x9ef}, {0xa66, 0xa6f}, {0xae6, 0xaef},
{0xb66, 0xb6f}, {0xbe6, 0xbef}, {0xc66, 0xc6f}, {0xce6, 0xcef},
@@ -307,7 +307,7 @@ static CONST crange digitRangeTable[] = {
* Unicode: punctuation characters.
*/
-static CONST crange punctRangeTable[] = {
+static const crange punctRangeTable[] = {
{0x21, 0x23}, {0x25, 0x2a}, {0x2c, 0x2f}, {0x5b, 0x5d},
{0x55a, 0x55f}, {0x66a, 0x66d}, {0x700, 0x70d}, {0x7f7, 0x7f9},
{0x830, 0x83e}, {0xf04, 0xf12}, {0xf3a, 0xf3d}, {0xfd0, 0xfd4},
@@ -329,7 +329,7 @@ static CONST crange punctRangeTable[] = {
#define NUM_PUNCT_RANGE (sizeof(punctRangeTable)/sizeof(crange))
-static CONST chr punctCharTable[] = {
+static const chr punctCharTable[] = {
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,
@@ -353,13 +353,13 @@ static CONST chr punctCharTable[] = {
* Unicode: white space characters.
*/
-static CONST crange spaceRangeTable[] = {
+static const crange spaceRangeTable[] = {
{0x9, 0xd}, {0x2000, 0x200a}
};
#define NUM_SPACE_RANGE (sizeof(spaceRangeTable)/sizeof(crange))
-static CONST chr spaceCharTable[] = {
+static const chr spaceCharTable[] = {
0x20, 0xa0, 0x1680, 0x180e, 0x2028, 0x2029, 0x202f, 0x205f, 0x3000
};
@@ -369,7 +369,7 @@ static CONST chr spaceCharTable[] = {
* Unicode: lowercase characters.
*/
-static CONST crange lowerRangeTable[] = {
+static const crange lowerRangeTable[] = {
{0x61, 0x7a}, {0xdf, 0xf6}, {0xf8, 0xff}, {0x17e, 0x180},
{0x199, 0x19b}, {0x1bd, 0x1bf}, {0x233, 0x239}, {0x24f, 0x293},
{0x295, 0x2af}, {0x37b, 0x37d}, {0x3ac, 0x3ce}, {0x3d5, 0x3d7},
@@ -394,7 +394,7 @@ static CONST crange lowerRangeTable[] = {
#define NUM_LOWER_RANGE (sizeof(lowerRangeTable)/sizeof(crange))
-static CONST chr lowerCharTable[] = {
+static const chr lowerCharTable[] = {
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,
@@ -468,7 +468,7 @@ static CONST chr lowerCharTable[] = {
* Unicode: uppercase characters.
*/
-static CONST crange upperRangeTable[] = {
+static const crange upperRangeTable[] = {
{0x41, 0x5a}, {0xc0, 0xd6}, {0xd8, 0xde}, {0x189, 0x18b},
{0x18e, 0x191}, {0x196, 0x198}, {0x1b1, 0x1b3}, {0x1f6, 0x1f8},
{0x243, 0x246}, {0x388, 0x38a}, {0x391, 0x3a1}, {0x3a3, 0x3ab},
@@ -491,7 +491,7 @@ static CONST crange upperRangeTable[] = {
#define NUM_UPPER_RANGE (sizeof(upperRangeTable)/sizeof(crange))
-static CONST chr upperCharTable[] = {
+static const chr upperCharTable[] = {
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,
@@ -566,7 +566,7 @@ static CONST chr upperCharTable[] = {
* Unicode: unicode print characters excluding space.
*/
-static CONST crange graphRangeTable[] = {
+static const crange graphRangeTable[] = {
{0x21, 0x7e}, {0xa1, 0xac}, {0xae, 0x377}, {0x37a, 0x37e},
{0x384, 0x38a}, {0x38e, 0x3a1}, {0x3a3, 0x527}, {0x531, 0x556},
{0x559, 0x55f}, {0x561, 0x587}, {0x591, 0x5c7}, {0x5d0, 0x5ea},
@@ -682,7 +682,7 @@ static CONST crange graphRangeTable[] = {
#define NUM_GRAPH_RANGE (sizeof(graphRangeTable)/sizeof(crange))
-static CONST chr graphCharTable[] = {
+static const chr graphCharTable[] = {
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,
@@ -715,18 +715,18 @@ static CONST chr graphCharTable[] = {
/*
- element - map collating-element name to celt
- ^ static celt element(struct vars *, CONST chr *, CONST chr *);
+ ^ static celt element(struct vars *, const chr *, const chr *);
*/
static celt
-element(v, startp, endp)
- struct vars *v; /* context */
- CONST chr *startp; /* points to start of name */
- CONST chr *endp; /* points just past end of name */
+element(
+ struct vars *v, /* context */
+ const chr *startp, /* points to start of name */
+ const chr *endp) /* points just past end of name */
{
- CONST struct cname *cn;
+ const struct cname *cn;
size_t len;
Tcl_DString ds;
- CONST char *np;
+ const char *np;
/*
* Generic: one-chr names stand for themselves.
@@ -769,11 +769,11 @@ element(v, startp, endp)
^ static struct cvec *range(struct vars *, celt, celt, int);
*/
static struct cvec *
-range(v, a, b, cases)
- struct vars *v; /* context */
- celt a; /* range start */
- celt b; /* range end, might equal a */
- int cases; /* case-independent? */
+range(
+ struct vars *v, /* context */
+ celt a, /* range start */
+ celt b, /* range end, might equal a */
+ int cases) /* case-independent? */
{
int nchrs;
struct cvec *cv;
@@ -826,8 +826,8 @@ range(v, a, b, cases)
^ static int before(celt, celt);
*/
static int /* predicate */
-before(x, y)
- celt x, y; /* collating elements */
+before(
+ celt x, celt y) /* collating elements */
{
if (x < y) {
return 1;
@@ -841,11 +841,11 @@ before(x, y)
^ static struct cvec *eclass(struct vars *, celt, int);
*/
static struct cvec *
-eclass(v, c, cases)
- struct vars *v; /* context */
- celt c; /* Collating element representing
- * the equivalence class. */
- int cases; /* all cases? */
+eclass(
+ struct vars *v, /* context */
+ celt c, /* Collating element representing the
+ * equivalence class. */
+ int cases) /* all cases? */
{
struct cvec *cv;
@@ -880,27 +880,27 @@ eclass(v, c, cases)
/*
- cclass - supply cvec for a character class
* Must include case counterparts on request.
- ^ static struct cvec *cclass(struct vars *, CONST chr *, CONST chr *, int);
+ ^ static struct cvec *cclass(struct vars *, const chr *, const chr *, int);
*/
static struct cvec *
-cclass(v, startp, endp, cases)
- struct vars *v; /* context */
- CONST chr *startp; /* where the name starts */
- CONST chr *endp; /* just past the end of the name */
- int cases; /* case-independent? */
+cclass(
+ struct vars *v, /* context */
+ const chr *startp, /* where the name starts */
+ const chr *endp, /* just past the end of the name */
+ int cases) /* case-independent? */
{
size_t len;
struct cvec *cv = NULL;
Tcl_DString ds;
- CONST char *np;
- CONST char *CONST *namePtr;
+ const char *np;
+ const char *const *namePtr;
int i, index;
/*
* The following arrays define the valid character class names.
*/
- static CONST char *CONST classNames[] = {
+ static const char *const classNames[] = {
"alnum", "alpha", "ascii", "blank", "cntrl", "digit", "graph",
"lower", "print", "punct", "space", "upper", "xdigit", NULL
};
@@ -1119,9 +1119,9 @@ cclass(v, startp, endp, cases)
^ static struct cvec *allcases(struct vars *, pchr);
*/
static struct cvec *
-allcases(v, pc)
- struct vars *v; /* context */
- pchr pc; /* character to get case equivs of */
+allcases(
+ struct vars *v, /* context */
+ pchr pc) /* character to get case equivs of */
{
struct cvec *cv;
chr c = (chr)pc;
@@ -1150,12 +1150,12 @@ allcases(v, pc)
* Note that it does not need to report anything except equal/unequal.
* Note also that the length is exact, and the comparison should not
* stop at embedded NULs!
- ^ static int cmp(CONST chr *, CONST chr *, size_t);
+ ^ static int cmp(const chr *, const chr *, size_t);
*/
-static int /* 0 for equal, nonzero for unequal */
-cmp(x, y, len)
- CONST chr *x, *y; /* strings to compare */
- size_t len; /* exact length of comparison */
+static int /* 0 for equal, nonzero for unequal */
+cmp(
+ const chr *x, const chr *y, /* strings to compare */
+ size_t len) /* exact length of comparison */
{
return memcmp(VS(x), VS(y), len*sizeof(chr));
}
@@ -1166,12 +1166,12 @@ cmp(x, y, len)
* Note that it does not need to report anything except equal/unequal.
* Note also that the length is exact, and the comparison should not
* stop at embedded NULs!
- ^ static int casecmp(CONST chr *, CONST chr *, size_t);
+ ^ static int casecmp(const chr *, const chr *, size_t);
*/
-static int /* 0 for equal, nonzero for unequal */
-casecmp(x, y, len)
- CONST chr *x, *y; /* strings to compare */
- size_t len; /* exact length of comparison */
+static int /* 0 for equal, nonzero for unequal */
+casecmp(
+ const chr *x, const chr *y, /* strings to compare */
+ size_t len) /* exact length of comparison */
{
for (; len > 0; len--, x++, y++) {
if ((*x!=*y) && (Tcl_UniCharToLower(*x) != Tcl_UniCharToLower(*y))) {
diff --git a/generic/regc_nfa.c b/generic/regc_nfa.c
index 48f56a9..19dbe63 100644
--- a/generic/regc_nfa.c
+++ b/generic/regc_nfa.c
@@ -2,24 +2,24 @@
* NFA utilities.
* This file is #included by regcomp.c.
*
- * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
- *
+ * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
+ *
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
- * Corporation, none of whom are responsible for the results. The author
- * thanks all of them.
- *
+ * Corporation, none of whom are responsible for the results. The author
+ * thanks all of them.
+ *
* Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
- *
- * I'd appreciate being given credit for this package in the documentation
- * of software which uses it, but that is not a requirement.
- *
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
@@ -28,471 +28,510 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- *
- *
- * One or two things that technically ought to be in here
- * are actually in color.c, thanks to some incestuous relationships in
- * the color chains.
+ * One or two things that technically ought to be in here are actually in
+ * color.c, thanks to some incestuous relationships in the color chains.
*/
#define NISERR() VISERR(nfa->v)
#define NERR(e) VERR(nfa->v, (e))
-
-
+
/*
- newnfa - set up an NFA
^ static struct nfa *newnfa(struct vars *, struct colormap *, struct nfa *);
*/
static struct nfa * /* the NFA, or NULL */
-newnfa(v, cm, parent)
-struct vars *v;
-struct colormap *cm;
-struct nfa *parent; /* NULL if primary NFA */
+newnfa(
+ struct vars *v,
+ struct colormap *cm,
+ struct nfa *parent) /* NULL if primary NFA */
{
- struct nfa *nfa;
-
- nfa = (struct nfa *)MALLOC(sizeof(struct nfa));
- if (nfa == NULL)
- return NULL;
-
- nfa->states = NULL;
- nfa->slast = NULL;
- nfa->free = NULL;
- nfa->nstates = 0;
- nfa->cm = cm;
- nfa->v = v;
- nfa->size = 0;
- nfa->bos[0] = nfa->bos[1] = COLORLESS;
- nfa->eos[0] = nfa->eos[1] = COLORLESS;
- nfa->parent = parent;
- nfa->post = newfstate(nfa, '@'); /* number 0 */
- nfa->pre = newfstate(nfa, '>'); /* number 1 */
-
- nfa->init = newstate(nfa); /* may become invalid later */
- nfa->final = newstate(nfa);
- if (ISERR()) {
- freenfa(nfa);
- return NULL;
- }
- rainbow(nfa, nfa->cm, PLAIN, COLORLESS, nfa->pre, nfa->init);
- newarc(nfa, '^', 1, nfa->pre, nfa->init);
- newarc(nfa, '^', 0, nfa->pre, nfa->init);
- rainbow(nfa, nfa->cm, PLAIN, COLORLESS, nfa->final, nfa->post);
- newarc(nfa, '$', 1, nfa->final, nfa->post);
- newarc(nfa, '$', 0, nfa->final, nfa->post);
-
- if (ISERR()) {
- freenfa(nfa);
- return NULL;
- }
- return nfa;
-}
+ struct nfa *nfa;
+ nfa = (struct nfa *) MALLOC(sizeof(struct nfa));
+ if (nfa == NULL) {
+ return NULL;
+ }
+
+ nfa->states = NULL;
+ nfa->slast = NULL;
+ nfa->free = NULL;
+ nfa->nstates = 0;
+ nfa->cm = cm;
+ nfa->v = v;
+ nfa->size = 0;
+ nfa->bos[0] = nfa->bos[1] = COLORLESS;
+ nfa->eos[0] = nfa->eos[1] = COLORLESS;
+ nfa->parent = parent; /* Precedes newfstate so parent is valid. */
+ nfa->post = newfstate(nfa, '@'); /* number 0 */
+ nfa->pre = newfstate(nfa, '>'); /* number 1 */
+
+ nfa->init = newstate(nfa); /* May become invalid later. */
+ nfa->final = newstate(nfa);
+ if (ISERR()) {
+ freenfa(nfa);
+ return NULL;
+ }
+ rainbow(nfa, nfa->cm, PLAIN, COLORLESS, nfa->pre, nfa->init);
+ newarc(nfa, '^', 1, nfa->pre, nfa->init);
+ newarc(nfa, '^', 0, nfa->pre, nfa->init);
+ rainbow(nfa, nfa->cm, PLAIN, COLORLESS, nfa->final, nfa->post);
+ newarc(nfa, '$', 1, nfa->final, nfa->post);
+ newarc(nfa, '$', 0, nfa->final, nfa->post);
+
+ if (ISERR()) {
+ freenfa(nfa);
+ return NULL;
+ }
+ return nfa;
+}
+
/*
- - too_many_states - checks if the max states exceeds the compile-time value
- ^ static int too_many_states(struct nfa *);
+ - TooManyStates - checks if the max states exceeds the compile-time value
+ ^ static int TooManyStates(struct nfa *);
*/
static int
-too_many_states(nfa)
-struct nfa *nfa;
+TooManyStates(
+ struct nfa *nfa)
{
- struct nfa *parent = nfa->parent;
- size_t sz = nfa->size;
- while (parent != NULL) {
- sz = parent->size;
- parent = parent->parent;
- }
- if (sz > REG_MAX_STATES)
- return 1;
- return 0;
+ struct nfa *parent = nfa->parent;
+ size_t sz = nfa->size;
+
+ while (parent != NULL) {
+ sz = parent->size;
+ parent = parent->parent;
+ }
+ if (sz > REG_MAX_STATES) {
+ return 1;
+ }
+ return 0;
}
-
+
/*
- - increment_size - increases the tracked size of the NFA and its parents.
- ^ static void increment_size(struct nfa *);
+ - IncrementSize - increases the tracked size of the NFA and its parents.
+ ^ static void IncrementSize(struct nfa *);
*/
static void
-increment_size(nfa)
-struct nfa *nfa;
+IncrementSize(
+ struct nfa *nfa)
{
- struct nfa *parent = nfa->parent;
- nfa->size++;
- while (parent != NULL) {
- parent->size++;
- parent = parent->parent;
- }
-}
+ struct nfa *parent = nfa->parent;
+ nfa->size++;
+ while (parent != NULL) {
+ parent->size++;
+ parent = parent->parent;
+ }
+}
+
/*
- - decrement_size - increases the tracked size of the NFA and its parents.
- ^ static void decrement_size(struct nfa *);
+ - DecrementSize - increases the tracked size of the NFA and its parents.
+ ^ static void DecrementSize(struct nfa *);
*/
static void
-decrement_size(nfa)
-struct nfa *nfa;
+DecrementSize(
+ struct nfa *nfa)
{
- struct nfa *parent = nfa->parent;
- nfa->size--;
- while (parent != NULL) {
- parent->size--;
- parent = parent->parent;
- }
-}
+ struct nfa *parent = nfa->parent;
+ nfa->size--;
+ while (parent != NULL) {
+ parent->size--;
+ parent = parent->parent;
+ }
+}
+
/*
- freenfa - free an entire NFA
^ static VOID freenfa(struct nfa *);
*/
-static VOID
-freenfa(nfa)
-struct nfa *nfa;
+static void
+freenfa(
+ struct nfa *nfa)
{
- struct state *s;
-
- while ((s = nfa->states) != NULL) {
- s->nins = s->nouts = 0; /* don't worry about arcs */
- freestate(nfa, s);
- }
- while ((s = nfa->free) != NULL) {
- nfa->free = s->next;
- destroystate(nfa, s);
- }
+ struct state *s;
- nfa->slast = NULL;
- nfa->nstates = -1;
- nfa->pre = NULL;
- nfa->post = NULL;
- FREE(nfa);
+ while ((s = nfa->states) != NULL) {
+ s->nins = s->nouts = 0; /* don't worry about arcs */
+ freestate(nfa, s);
+ }
+ while ((s = nfa->free) != NULL) {
+ nfa->free = s->next;
+ destroystate(nfa, s);
+ }
+
+ nfa->slast = NULL;
+ nfa->nstates = -1;
+ nfa->pre = NULL;
+ nfa->post = NULL;
+ FREE(nfa);
}
-
+
/*
- newstate - allocate an NFA state, with zero flag value
^ static struct state *newstate(struct nfa *);
*/
static struct state * /* NULL on error */
-newstate(nfa)
-struct nfa *nfa;
+newstate(
+ struct nfa *nfa)
{
- struct state *s;
-
- if (too_many_states(nfa)) {
- /* XXX: add specific error for this */
- NERR(REG_ETOOBIG);
- return NULL;
- }
- if (nfa->free != NULL) {
- s = nfa->free;
- nfa->free = s->next;
- } else {
- s = (struct state *)MALLOC(sizeof(struct state));
- if (s == NULL) {
- NERR(REG_ESPACE);
- return NULL;
- }
- s->oas.next = NULL;
- s->free = NULL;
- s->noas = 0;
- }
+ struct state *s;
- assert(nfa->nstates >= 0);
- s->no = nfa->nstates++;
- s->flag = 0;
- if (nfa->states == NULL)
- nfa->states = s;
- s->nins = 0;
- s->ins = NULL;
- s->nouts = 0;
- s->outs = NULL;
- s->tmp = NULL;
- s->next = NULL;
- if (nfa->slast != NULL) {
- assert(nfa->slast->next == NULL);
- nfa->slast->next = s;
+ if (TooManyStates(nfa)) {
+ /* XXX: add specific error for this */
+ NERR(REG_ETOOBIG);
+ return NULL;
+ }
+ if (nfa->free != NULL) {
+ s = nfa->free;
+ nfa->free = s->next;
+ } else {
+ s = (struct state *) MALLOC(sizeof(struct state));
+ if (s == NULL) {
+ NERR(REG_ESPACE);
+ return NULL;
}
- s->prev = nfa->slast;
- nfa->slast = s;
- /* Track the current size and the parent size */
- increment_size(nfa);
- return s;
+ s->oas.next = NULL;
+ s->free = NULL;
+ s->noas = 0;
+ }
+
+ assert(nfa->nstates >= 0);
+ s->no = nfa->nstates++;
+ s->flag = 0;
+ if (nfa->states == NULL) {
+ nfa->states = s;
+ }
+ s->nins = 0;
+ s->ins = NULL;
+ s->nouts = 0;
+ s->outs = NULL;
+ s->tmp = NULL;
+ s->next = NULL;
+ if (nfa->slast != NULL) {
+ assert(nfa->slast->next == NULL);
+ nfa->slast->next = s;
+ }
+ s->prev = nfa->slast;
+ nfa->slast = s;
+
+ /*
+ * Track the current size and the parent size.
+ */
+
+ IncrementSize(nfa);
+ return s;
}
-
+
/*
- newfstate - allocate an NFA state with a specified flag value
^ static struct state *newfstate(struct nfa *, int flag);
*/
static struct state * /* NULL on error */
-newfstate(nfa, flag)
-struct nfa *nfa;
-int flag;
+newfstate(
+ struct nfa *nfa,
+ int flag)
{
- struct state *s;
+ struct state *s;
- s = newstate(nfa);
- if (s != NULL)
- s->flag = (char)flag;
- return s;
+ s = newstate(nfa);
+ if (s != NULL) {
+ s->flag = (char) flag;
+ }
+ return s;
}
-
+
/*
- dropstate - delete a state's inarcs and outarcs and free it
^ static VOID dropstate(struct nfa *, struct state *);
*/
-static VOID
-dropstate(nfa, s)
-struct nfa *nfa;
-struct state *s;
+static void
+dropstate(
+ struct nfa *nfa,
+ struct state *s)
{
- struct arc *a;
+ struct arc *a;
- while ((a = s->ins) != NULL)
- freearc(nfa, a);
- while ((a = s->outs) != NULL)
- freearc(nfa, a);
- freestate(nfa, s);
+ while ((a = s->ins) != NULL) {
+ freearc(nfa, a);
+ }
+ while ((a = s->outs) != NULL) {
+ freearc(nfa, a);
+ }
+ freestate(nfa, s);
}
-
+
/*
- freestate - free a state, which has no in-arcs or out-arcs
^ static VOID freestate(struct nfa *, struct state *);
*/
-static VOID
-freestate(nfa, s)
-struct nfa *nfa;
-struct state *s;
+static void
+freestate(
+ struct nfa *nfa,
+ struct state *s)
{
- assert(s != NULL);
- assert(s->nins == 0 && s->nouts == 0);
-
- s->no = FREESTATE;
- s->flag = 0;
- if (s->next != NULL)
- s->next->prev = s->prev;
- else {
- assert(s == nfa->slast);
- nfa->slast = s->prev;
- }
- if (s->prev != NULL)
- s->prev->next = s->next;
- else {
- assert(s == nfa->states);
- nfa->states = s->next;
- }
- s->prev = NULL;
- s->next = nfa->free; /* don't delete it, put it on the free list */
- nfa->free = s;
- decrement_size(nfa);
+ assert(s != NULL);
+ assert(s->nins == 0 && s->nouts == 0);
+
+ s->no = FREESTATE;
+ s->flag = 0;
+ if (s->next != NULL) {
+ s->next->prev = s->prev;
+ } else {
+ assert(s == nfa->slast);
+ nfa->slast = s->prev;
+ }
+ if (s->prev != NULL) {
+ s->prev->next = s->next;
+ } else {
+ assert(s == nfa->states);
+ nfa->states = s->next;
+ }
+ s->prev = NULL;
+ s->next = nfa->free; /* don't delete it, put it on the free list */
+ nfa->free = s;
+ DecrementSize(nfa);
}
-
+
/*
- destroystate - really get rid of an already-freed state
^ static VOID destroystate(struct nfa *, struct state *);
*/
-static VOID
-destroystate(nfa, s)
-struct nfa *nfa;
-struct state *s;
+static void
+destroystate(
+ struct nfa *nfa,
+ struct state *s)
{
- struct arcbatch *ab;
- struct arcbatch *abnext;
-
- assert(s->no == FREESTATE);
- for (ab = s->oas.next; ab != NULL; ab = abnext) {
- abnext = ab->next;
- FREE(ab);
- }
- s->ins = NULL;
- s->outs = NULL;
- s->next = NULL;
- FREE(s);
+ struct arcbatch *ab;
+ struct arcbatch *abnext;
+
+ assert(s->no == FREESTATE);
+ for (ab=s->oas.next ; ab!=NULL ; ab=abnext) {
+ abnext = ab->next;
+ FREE(ab);
+ }
+ s->ins = NULL;
+ s->outs = NULL;
+ s->next = NULL;
+ FREE(s);
}
-
+
/*
- newarc - set up a new arc within an NFA
- ^ static VOID newarc(struct nfa *, int, pcolor, struct state *,
+ ^ static VOID newarc(struct nfa *, int, pcolor, struct state *,
^ struct state *);
*/
-static VOID
-newarc(nfa, t, co, from, to)
-struct nfa *nfa;
-int t;
-pcolor co;
-struct state *from;
-struct state *to;
+static void
+newarc(
+ struct nfa *nfa,
+ int t,
+ pcolor co,
+ struct state *from,
+ struct state *to)
{
- struct arc *a;
-
- assert(from != NULL && to != NULL);
+ struct arc *a;
- /* check for duplicates */
- for (a = from->outs; a != NULL; a = a->outchain)
- if (a->to == to && a->co == co && a->type == t)
- return;
-
- a = allocarc(nfa, from);
- if (NISERR())
- return;
- assert(a != NULL);
-
- a->type = t;
- a->co = (color)co;
- a->to = to;
- a->from = from;
-
- /*
- * Put the new arc on the beginning, not the end, of the chains.
- * Not only is this easier, it has the very useful side effect that
- * deleting the most-recently-added arc is the cheapest case rather
- * than the most expensive one.
- */
- a->inchain = to->ins;
- to->ins = a;
- a->outchain = from->outs;
- from->outs = a;
+ assert(from != NULL && to != NULL);
- from->nouts++;
- to->nins++;
+ /*
+ * Check for duplicates.
+ */
- if (COLORED(a) && nfa->parent == NULL)
- colorchain(nfa->cm, a);
+ for (a=from->outs ; a!=NULL ; a=a->outchain) {
+ if (a->to == to && a->co == co && a->type == t) {
+ return;
+ }
+ }
+ a = allocarc(nfa, from);
+ if (NISERR()) {
return;
+ }
+ assert(a != NULL);
+
+ a->type = t;
+ a->co = (color) co;
+ a->to = to;
+ a->from = from;
+
+ /*
+ * Put the new arc on the beginning, not the end, of the chains. Not only
+ * is this easier, it has the very useful side effect that deleting the
+ * most-recently-added arc is the cheapest case rather than the most
+ * expensive one.
+ */
+
+ a->inchain = to->ins;
+ to->ins = a;
+ a->outchain = from->outs;
+ from->outs = a;
+
+ from->nouts++;
+ to->nins++;
+
+ if (COLORED(a) && nfa->parent == NULL) {
+ colorchain(nfa->cm, a);
+ }
}
-
+
/*
- allocarc - allocate a new out-arc within a state
^ static struct arc *allocarc(struct nfa *, struct state *);
*/
static struct arc * /* NULL for failure */
-allocarc(nfa, s)
-struct nfa *nfa;
-struct state *s;
+allocarc(
+ struct nfa *nfa,
+ struct state *s)
{
- struct arc *a;
- struct arcbatch *new;
- int i;
+ struct arc *a;
- /* shortcut */
- if (s->free == NULL && s->noas < ABSIZE) {
- a = &s->oas.a[s->noas];
- s->noas++;
- return a;
- }
+ /*
+ * Shortcut
+ */
- /* if none at hand, get more */
- if (s->free == NULL) {
- new = (struct arcbatch *)MALLOC(sizeof(struct arcbatch));
- if (new == NULL) {
- NERR(REG_ESPACE);
- return NULL;
- }
- new->next = s->oas.next;
- s->oas.next = new;
+ if (s->free == NULL && s->noas < ABSIZE) {
+ a = &s->oas.a[s->noas];
+ s->noas++;
+ return a;
+ }
- for (i = 0; i < ABSIZE; i++) {
- new->a[i].type = 0;
- new->a[i].freechain = &new->a[i+1];
- }
- new->a[ABSIZE-1].freechain = NULL;
- s->free = &new->a[0];
+ /*
+ * if none at hand, get more
+ */
+
+ if (s->free == NULL) {
+ struct arcbatch *newAb = (struct arcbatch *)
+ MALLOC(sizeof(struct arcbatch));
+ int i;
+
+ if (newAb == NULL) {
+ NERR(REG_ESPACE);
+ return NULL;
}
- assert(s->free != NULL);
+ newAb->next = s->oas.next;
+ s->oas.next = newAb;
- a = s->free;
- s->free = a->freechain;
- return a;
+ for (i=0 ; i<ABSIZE ; i++) {
+ newAb->a[i].type = 0;
+ newAb->a[i].freechain = &newAb->a[i+1];
+ }
+ newAb->a[ABSIZE-1].freechain = NULL;
+ s->free = &newAb->a[0];
+ }
+ assert(s->free != NULL);
+
+ a = s->free;
+ s->free = a->freechain;
+ return a;
}
-
+
/*
- freearc - free an arc
^ static VOID freearc(struct nfa *, struct arc *);
*/
-static VOID
-freearc(nfa, victim)
-struct nfa *nfa;
-struct arc *victim;
+static void
+freearc(
+ struct nfa *nfa,
+ struct arc *victim)
{
- struct state *from = victim->from;
- struct state *to = victim->to;
- struct arc *a;
-
- assert(victim->type != 0);
-
- /* take it off color chain if necessary */
- if (COLORED(victim) && nfa->parent == NULL)
- uncolorchain(nfa->cm, victim);
-
- /* take it off source's out-chain */
- assert(from != NULL);
- assert(from->outs != NULL);
- a = from->outs;
- if (a == victim) /* simple case: first in chain */
- from->outs = victim->outchain;
- else {
- for (; a != NULL && a->outchain != victim; a = a->outchain)
- continue;
- assert(a != NULL);
- a->outchain = victim->outchain;
+ struct state *from = victim->from;
+ struct state *to = victim->to;
+ struct arc *a;
+
+ assert(victim->type != 0);
+
+ /*
+ * Take it off color chain if necessary.
+ */
+
+ if (COLORED(victim) && nfa->parent == NULL) {
+ uncolorchain(nfa->cm, victim);
+ }
+
+ /*
+ * Take it off source's out-chain.
+ */
+
+ assert(from != NULL);
+ assert(from->outs != NULL);
+ a = from->outs;
+ if (a == victim) { /* simple case: first in chain */
+ from->outs = victim->outchain;
+ } else {
+ for (; a!=NULL && a->outchain!=victim ; a=a->outchain) {
+ continue;
}
- from->nouts--;
-
- /* take it off target's in-chain */
- assert(to != NULL);
- assert(to->ins != NULL);
- a = to->ins;
- if (a == victim) /* simple case: first in chain */
- to->ins = victim->inchain;
- else {
- for (; a != NULL && a->inchain != victim; a = a->inchain)
- continue;
- assert(a != NULL);
- a->inchain = victim->inchain;
+ assert(a != NULL);
+ a->outchain = victim->outchain;
+ }
+ from->nouts--;
+
+ /*
+ * Take it off target's in-chain.
+ */
+
+ assert(to != NULL);
+ assert(to->ins != NULL);
+ a = to->ins;
+ if (a == victim) { /* simple case: first in chain */
+ to->ins = victim->inchain;
+ } else {
+ for (; a->inchain!=victim ; a=a->inchain) {
+ assert(a->inchain != NULL);
+ continue;
}
- to->nins--;
-
- /* clean up and place on free list */
- victim->type = 0;
- victim->from = NULL; /* precautions... */
- victim->to = NULL;
- victim->inchain = NULL;
- victim->outchain = NULL;
- victim->freechain = from->free;
- from->free = victim;
+ a->inchain = victim->inchain;
+ }
+ to->nins--;
+
+ /*
+ * Clean up and place on free list.
+ */
+
+ victim->type = 0;
+ victim->from = NULL; /* precautions... */
+ victim->to = NULL;
+ victim->inchain = NULL;
+ victim->outchain = NULL;
+ victim->freechain = from->free;
+ from->free = victim;
}
-
+
/*
- 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);
*/
static struct arc *
-findarc(s, type, co)
-struct state *s;
-int type;
-pcolor co;
+findarc(
+ struct state *s,
+ int type,
+ pcolor co)
{
- struct arc *a;
+ struct arc *a;
- for (a = s->outs; a != NULL; a = a->outchain)
- if (a->type == type && a->co == co)
- return a;
- return NULL;
+ for (a=s->outs ; a!=NULL ; a=a->outchain) {
+ if (a->type == type && a->co == co) {
+ return a;
+ }
+ }
+ return NULL;
}
-
+
/*
- cparc - allocate a new arc within an NFA, copying details from old one
- ^ static VOID cparc(struct nfa *, struct arc *, struct state *,
+ ^ static VOID cparc(struct nfa *, struct arc *, struct state *,
^ struct state *);
*/
-static VOID
-cparc(nfa, oa, from, to)
-struct nfa *nfa;
-struct arc *oa;
-struct state *from;
-struct state *to;
+static void
+cparc(
+ struct nfa *nfa,
+ struct arc *oa,
+ struct state *from,
+ struct state *to)
{
- newarc(nfa, oa->type, oa->co, from, to);
+ newarc(nfa, oa->type, oa->co, from, to);
}
-
+
/*
- moveins - move all in arcs of a state to another state
* You might think this could be done better by just updating the
@@ -501,341 +540,365 @@ struct state *to;
* ones to exploit the suppression built into newarc.
^ static VOID moveins(struct nfa *, struct state *, struct state *);
*/
-static VOID
-moveins(nfa, old, new)
-struct nfa *nfa;
-struct state *old;
-struct state *new;
+static void
+moveins(
+ struct nfa *nfa,
+ struct state *oldState,
+ struct state *newState)
{
- struct arc *a;
+ struct arc *a;
- assert(old != new);
+ assert(oldState != newState);
- while ((a = old->ins) != NULL) {
- cparc(nfa, a, a->from, new);
- freearc(nfa, a);
- }
- assert(old->nins == 0);
- assert(old->ins == NULL);
+ while ((a = oldState->ins) != NULL) {
+ cparc(nfa, a, a->from, newState);
+ freearc(nfa, a);
+ }
+ assert(oldState->nins == 0);
+ assert(oldState->ins == NULL);
}
-
+
/*
- copyins - copy all in arcs of a state to another state
^ static VOID copyins(struct nfa *, struct state *, struct state *);
*/
-static VOID
-copyins(nfa, old, new)
-struct nfa *nfa;
-struct state *old;
-struct state *new;
+static void
+copyins(
+ struct nfa *nfa,
+ struct state *oldState,
+ struct state *newState)
{
- struct arc *a;
+ struct arc *a;
- assert(old != new);
+ assert(oldState != newState);
- for (a = old->ins; a != NULL; a = a->inchain)
- cparc(nfa, a, a->from, new);
+ for (a=oldState->ins ; a!=NULL ; a=a->inchain) {
+ cparc(nfa, a, a->from, newState);
+ }
}
-
+
/*
- moveouts - move all out arcs of a state to another state
^ static VOID moveouts(struct nfa *, struct state *, struct state *);
*/
-static VOID
-moveouts(nfa, old, new)
-struct nfa *nfa;
-struct state *old;
-struct state *new;
+static void
+moveouts(
+ struct nfa *nfa,
+ struct state *oldState,
+ struct state *newState)
{
- struct arc *a;
+ struct arc *a;
- assert(old != new);
+ assert(oldState != newState);
- while ((a = old->outs) != NULL) {
- cparc(nfa, a, new, a->to);
- freearc(nfa, a);
- }
+ while ((a = oldState->outs) != NULL) {
+ cparc(nfa, a, newState, a->to);
+ freearc(nfa, a);
+ }
}
-
+
/*
- copyouts - copy all out arcs of a state to another state
^ static VOID copyouts(struct nfa *, struct state *, struct state *);
*/
-static VOID
-copyouts(nfa, old, new)
-struct nfa *nfa;
-struct state *old;
-struct state *new;
+static void
+copyouts(
+ struct nfa *nfa,
+ struct state *oldState,
+ struct state *newState)
{
- struct arc *a;
+ struct arc *a;
- assert(old != new);
+ assert(oldState != newState);
- for (a = old->outs; a != NULL; a = a->outchain)
- cparc(nfa, a, new, a->to);
+ for (a=oldState->outs ; a!=NULL ; a=a->outchain) {
+ cparc(nfa, a, newState, a->to);
+ }
}
-
+
/*
- cloneouts - copy out arcs of a state to another state pair, modifying type
^ static VOID cloneouts(struct nfa *, struct state *, struct state *,
^ struct state *, int);
*/
-static VOID
-cloneouts(nfa, old, from, to, type)
-struct nfa *nfa;
-struct state *old;
-struct state *from;
-struct state *to;
-int type;
+static void
+cloneouts(
+ struct nfa *nfa,
+ struct state *old,
+ struct state *from,
+ struct state *to,
+ int type)
{
- struct arc *a;
+ struct arc *a;
- assert(old != from);
+ assert(old != from);
- for (a = old->outs; a != NULL; a = a->outchain)
- newarc(nfa, type, a->co, from, to);
+ for (a=old->outs ; a!=NULL ; a=a->outchain) {
+ newarc(nfa, type, a->co, from, to);
+ }
}
-
+
/*
- delsub - delete a sub-NFA, updating subre pointers if necessary
* This uses a recursive traversal of the sub-NFA, marking already-seen
* states using their tmp pointer.
^ static VOID delsub(struct nfa *, struct state *, struct state *);
*/
-static VOID
-delsub(nfa, lp, rp)
-struct nfa *nfa;
-struct state *lp; /* the sub-NFA goes from here... */
-struct state *rp; /* ...to here, *not* inclusive */
+static void
+delsub(
+ struct nfa *nfa,
+ struct state *lp, /* the sub-NFA goes from here... */
+ struct state *rp) /* ...to here, *not* inclusive */
{
- assert(lp != rp);
+ assert(lp != rp);
- rp->tmp = rp; /* mark end */
+ rp->tmp = rp; /* mark end */
- deltraverse(nfa, lp, lp);
- assert(lp->nouts == 0 && rp->nins == 0); /* did the job */
- assert(lp->no != FREESTATE && rp->no != FREESTATE); /* no more */
+ deltraverse(nfa, lp, lp);
+ assert(lp->nouts == 0 && rp->nins == 0); /* did the job */
+ assert(lp->no != FREESTATE && rp->no != FREESTATE); /* no more */
- rp->tmp = NULL; /* unmark end */
- lp->tmp = NULL; /* and begin, marked by deltraverse */
+ rp->tmp = NULL; /* unmark end */
+ lp->tmp = NULL; /* and begin, marked by deltraverse */
}
-
+
/*
- deltraverse - the recursive heart of delsub
* This routine's basic job is to destroy all out-arcs of the state.
^ static VOID deltraverse(struct nfa *, struct state *, struct state *);
*/
-static VOID
-deltraverse(nfa, leftend, s)
-struct nfa *nfa;
-struct state *leftend;
-struct state *s;
+static void
+deltraverse(
+ struct nfa *nfa,
+ struct state *leftend,
+ struct state *s)
{
- struct arc *a;
- struct state *to;
-
- if (s->nouts == 0)
- return; /* nothing to do */
- if (s->tmp != NULL)
- return; /* already in progress */
-
- s->tmp = s; /* mark as in progress */
-
- while ((a = s->outs) != NULL) {
- to = a->to;
- deltraverse(nfa, leftend, to);
- assert(to->nouts == 0 || to->tmp != NULL);
- freearc(nfa, a);
- if (to->nins == 0 && to->tmp == NULL) {
- assert(to->nouts == 0);
- freestate(nfa, to);
- }
+ struct arc *a;
+ struct state *to;
+
+ if (s->nouts == 0) {
+ return; /* nothing to do */
+ }
+ if (s->tmp != NULL) {
+ return; /* already in progress */
+ }
+
+ s->tmp = s; /* mark as in progress */
+
+ while ((a = s->outs) != NULL) {
+ to = a->to;
+ deltraverse(nfa, leftend, to);
+ assert(to->nouts == 0 || to->tmp != NULL);
+ freearc(nfa, a);
+ if (to->nins == 0 && to->tmp == NULL) {
+ assert(to->nouts == 0);
+ freestate(nfa, to);
}
+ }
- assert(s->no != FREESTATE); /* we're still here */
- assert(s == leftend || s->nins != 0); /* and still reachable */
- assert(s->nouts == 0); /* but have no outarcs */
+ assert(s->no != FREESTATE); /* we're still here */
+ assert(s == leftend || s->nins != 0); /* and still reachable */
+ assert(s->nouts == 0); /* but have no outarcs */
- s->tmp = NULL; /* we're done here */
+ s->tmp = NULL; /* we're done here */
}
-
+
/*
- dupnfa - duplicate sub-NFA
- * Another recursive traversal, this time using tmp to point to duplicates
- * as well as mark already-seen states. (You knew there was a reason why
- * it's a state pointer, didn't you? :-))
- ^ static VOID dupnfa(struct nfa *, struct state *, struct state *,
+ * Another recursive traversal, this time using tmp to point to duplicates as
+ * well as mark already-seen states. (You knew there was a reason why it's a
+ * state pointer, didn't you? :-))
+ ^ static VOID dupnfa(struct nfa *, struct state *, struct state *,
^ struct state *, struct state *);
*/
-static VOID
-dupnfa(nfa, start, stop, from, to)
-struct nfa *nfa;
-struct state *start; /* duplicate of subNFA starting here */
-struct state *stop; /* and stopping here */
-struct state *from; /* stringing duplicate from here */
-struct state *to; /* to here */
+static void
+dupnfa(
+ struct nfa *nfa,
+ struct state *start, /* duplicate of subNFA starting here */
+ struct state *stop, /* and stopping here */
+ struct state *from, /* stringing duplicate from here */
+ struct state *to) /* to here */
{
- if (start == stop) {
- newarc(nfa, EMPTY, 0, from, to);
- return;
- }
+ if (start == stop) {
+ newarc(nfa, EMPTY, 0, from, to);
+ return;
+ }
- stop->tmp = to;
- duptraverse(nfa, start, from);
- /* done, except for clearing out the tmp pointers */
+ stop->tmp = to;
+ duptraverse(nfa, start, from);
+ /* done, except for clearing out the tmp pointers */
- stop->tmp = NULL;
- cleartraverse(nfa, start);
+ stop->tmp = NULL;
+ cleartraverse(nfa, start);
}
-
+
/*
- duptraverse - recursive heart of dupnfa
^ static VOID duptraverse(struct nfa *, struct state *, struct state *);
*/
-static VOID
-duptraverse(nfa, s, stmp)
-struct nfa *nfa;
-struct state *s;
-struct state *stmp; /* s's duplicate, or NULL */
+static void
+duptraverse(
+ struct nfa *nfa,
+ struct state *s,
+ struct state *stmp) /* s's duplicate, or NULL */
{
- struct arc *a;
+ struct arc *a;
- if (s->tmp != NULL)
- return; /* already done */
+ if (s->tmp != NULL) {
+ return; /* already done */
+ }
- s->tmp = (stmp == NULL) ? newstate(nfa) : stmp;
- if (s->tmp == NULL) {
- assert(NISERR());
- return;
- }
+ s->tmp = (stmp == NULL) ? newstate(nfa) : stmp;
+ if (s->tmp == NULL) {
+ assert(NISERR());
+ return;
+ }
- for (a = s->outs; a != NULL && !NISERR(); a = a->outchain) {
- duptraverse(nfa, a->to, (struct state *)NULL);
- if (NISERR())
- break;
- assert(a->to->tmp != NULL);
- cparc(nfa, a, s->tmp, a->to->tmp);
+ for (a=s->outs ; a!=NULL && !NISERR() ; a=a->outchain) {
+ duptraverse(nfa, a->to, NULL);
+ if (NISERR()) {
+ break;
}
+ assert(a->to->tmp != NULL);
+ cparc(nfa, a, s->tmp, a->to->tmp);
+ }
}
-
+
/*
- cleartraverse - recursive cleanup for algorithms that leave tmp ptrs set
^ static VOID cleartraverse(struct nfa *, struct state *);
*/
-static VOID
-cleartraverse(nfa, s)
-struct nfa *nfa;
-struct state *s;
+static void
+cleartraverse(
+ struct nfa *nfa,
+ struct state *s)
{
- struct arc *a;
+ struct arc *a;
- if (s->tmp == NULL)
- return;
- s->tmp = NULL;
+ if (s->tmp == NULL) {
+ return;
+ }
+ s->tmp = NULL;
- for (a = s->outs; a != NULL; a = a->outchain)
- cleartraverse(nfa, a->to);
+ for (a=s->outs ; a!=NULL ; a=a->outchain) {
+ cleartraverse(nfa, a->to);
+ }
}
-
+
/*
- specialcolors - fill in special colors for an NFA
^ static VOID specialcolors(struct nfa *);
*/
-static VOID
-specialcolors(nfa)
-struct nfa *nfa;
+static void
+specialcolors(
+ struct nfa *nfa)
{
- /* false colors for BOS, BOL, EOS, EOL */
- if (nfa->parent == NULL) {
- nfa->bos[0] = pseudocolor(nfa->cm);
- nfa->bos[1] = pseudocolor(nfa->cm);
- nfa->eos[0] = pseudocolor(nfa->cm);
- nfa->eos[1] = pseudocolor(nfa->cm);
- } else {
- assert(nfa->parent->bos[0] != COLORLESS);
- nfa->bos[0] = nfa->parent->bos[0];
- assert(nfa->parent->bos[1] != COLORLESS);
- nfa->bos[1] = nfa->parent->bos[1];
- assert(nfa->parent->eos[0] != COLORLESS);
- nfa->eos[0] = nfa->parent->eos[0];
- assert(nfa->parent->eos[1] != COLORLESS);
- nfa->eos[1] = nfa->parent->eos[1];
- }
+ /*
+ * False colors for BOS, BOL, EOS, EOL
+ */
+
+ if (nfa->parent == NULL) {
+ nfa->bos[0] = pseudocolor(nfa->cm);
+ nfa->bos[1] = pseudocolor(nfa->cm);
+ nfa->eos[0] = pseudocolor(nfa->cm);
+ nfa->eos[1] = pseudocolor(nfa->cm);
+ } else {
+ assert(nfa->parent->bos[0] != COLORLESS);
+ nfa->bos[0] = nfa->parent->bos[0];
+ assert(nfa->parent->bos[1] != COLORLESS);
+ nfa->bos[1] = nfa->parent->bos[1];
+ assert(nfa->parent->eos[0] != COLORLESS);
+ nfa->eos[0] = nfa->parent->eos[0];
+ assert(nfa->parent->eos[1] != COLORLESS);
+ nfa->eos[1] = nfa->parent->eos[1];
+ }
}
-
+
/*
- optimize - optimize an NFA
^ static long optimize(struct nfa *, FILE *);
*/
static long /* re_info bits */
-optimize(nfa, f)
-struct nfa *nfa;
-FILE *f; /* for debug output; NULL none */
+optimize(
+ struct nfa *nfa,
+ FILE *f) /* for debug output; NULL none */
{
- int verbose = (f != NULL) ? 1 : 0;
-
- if (verbose)
- fprintf(f, "\ninitial cleanup:\n");
- cleanup(nfa); /* may simplify situation */
- if (verbose)
- dumpnfa(nfa, f);
- if (verbose)
- fprintf(f, "\nempties:\n");
- fixempties(nfa, f); /* get rid of EMPTY arcs */
- if (verbose)
- fprintf(f, "\nconstraints:\n");
- pullback(nfa, f); /* pull back constraints backward */
- pushfwd(nfa, f); /* push fwd constraints forward */
- if (verbose)
- fprintf(f, "\nfinal cleanup:\n");
- cleanup(nfa); /* final tidying */
- return analyze(nfa); /* and analysis */
+ int verbose = (f != NULL) ? 1 : 0;
+
+ if (verbose) {
+ fprintf(f, "\ninitial cleanup:\n");
+ }
+ cleanup(nfa); /* may simplify situation */
+ if (verbose) {
+ dumpnfa(nfa, f);
+ }
+ if (verbose) {
+ fprintf(f, "\nempties:\n");
+ }
+ fixempties(nfa, f); /* get rid of EMPTY arcs */
+ if (verbose) {
+ fprintf(f, "\nconstraints:\n");
+ }
+ pullback(nfa, f); /* pull back constraints backward */
+ pushfwd(nfa, f); /* push fwd constraints forward */
+ if (verbose) {
+ fprintf(f, "\nfinal cleanup:\n");
+ }
+ cleanup(nfa); /* final tidying */
+ return analyze(nfa); /* and analysis */
}
-
+
/*
- pullback - pull back constraints backward to (with luck) eliminate them
^ static VOID pullback(struct nfa *, FILE *);
*/
-static VOID
-pullback(nfa, f)
-struct nfa *nfa;
-FILE *f; /* for debug output; NULL none */
+static void
+pullback(
+ struct nfa *nfa,
+ FILE *f) /* for debug output; NULL none */
{
- struct state *s;
- struct state *nexts;
- struct arc *a;
- struct arc *nexta;
- int progress;
-
- /* find and pull until there are no more */
- do {
- progress = 0;
- for (s = nfa->states; s != NULL && !NISERR(); s = nexts) {
- nexts = s->next;
- for (a = s->outs; a != NULL && !NISERR(); a = nexta) {
- nexta = a->outchain;
- if (a->type == '^' || a->type == BEHIND)
- if (pull(nfa, a))
- progress = 1;
- assert(nexta == NULL || s->no != FREESTATE);
- }
- }
- if (progress && f != NULL)
- dumpnfa(nfa, f);
- } while (progress && !NISERR());
- if (NISERR())
- return;
-
- for (a = nfa->pre->outs; a != NULL; a = nexta) {
+ struct state *s;
+ struct state *nexts;
+ struct arc *a;
+ struct arc *nexta;
+ int progress;
+
+ /*
+ * Find and pull until there are no more.
+ */
+
+ do {
+ progress = 0;
+ for (s=nfa->states ; s!=NULL && !NISERR() ; s=nexts) {
+ nexts = s->next;
+ for (a=s->outs ; a!=NULL && !NISERR() ; a=nexta) {
nexta = a->outchain;
- if (a->type == '^') {
- assert(a->co == 0 || a->co == 1);
- newarc(nfa, PLAIN, nfa->bos[a->co], a->from, a->to);
- freearc(nfa, a);
+ if (a->type == '^' || a->type == BEHIND) {
+ if (pull(nfa, a)) {
+ progress = 1;
+ }
}
+ assert(nexta == NULL || s->no != FREESTATE);
+ }
}
+ if (progress && f != NULL) {
+ dumpnfa(nfa, f);
+ }
+ } while (progress && !NISERR());
+ if (NISERR()) {
+ return;
+ }
+
+ for (a=nfa->pre->outs ; a!=NULL ; a=nexta) {
+ nexta = a->outchain;
+ if (a->type == '^') {
+ assert(a->co == 0 || a->co == 1);
+ newarc(nfa, PLAIN, nfa->bos[a->co], a->from, a->to);
+ freearc(nfa, a);
+ }
+ }
}
-
+
/*
- pull - pull a back constraint backward past its source state
* A significant property of this function is that it deletes at most
@@ -844,136 +907,155 @@ FILE *f; /* for debug output; NULL none */
^ static int pull(struct nfa *, struct arc *);
*/
static int /* 0 couldn't, 1 could */
-pull(nfa, con)
-struct nfa *nfa;
-struct arc *con;
+pull(
+ struct nfa *nfa,
+ struct arc *con)
{
- struct state *from = con->from;
- struct state *to = con->to;
- struct arc *a;
- struct arc *nexta;
- struct state *s;
-
- if (from == to) { /* circular constraint is pointless */
- freearc(nfa, con);
- return 1;
- }
- if (from->flag) /* can't pull back beyond start */
- return 0;
- if (from->nins == 0) { /* unreachable */
- freearc(nfa, con);
- return 1;
- }
+ struct state *from = con->from;
+ struct state *to = con->to;
+ struct arc *a;
+ struct arc *nexta;
+ struct state *s;
+
+ if (from == to) { /* circular constraint is pointless */
+ freearc(nfa, con);
+ return 1;
+ }
+ if (from->flag) { /* can't pull back beyond start */
+ return 0;
+ }
+ if (from->nins == 0) { /* unreachable */
+ freearc(nfa, con);
+ return 1;
+ }
- /*
- * DGP 2007-11-15: Cloning a state with a circular constraint on its
- * list of outs can lead to trouble [Bug 1810038], so get rid of them
- * first.
- */
+ /*
+ * DGP 2007-11-15: Cloning a state with a circular constraint on its list
+ * of outs can lead to trouble [Bug 1810038], so get rid of them first.
+ */
- for (a = from->outs; a != NULL; a = nexta) {
- nexta = a->outchain;
- switch (a->type) {
- case '^':
- case '$':
- case BEHIND:
- case AHEAD:
- if (from == a->to) {
- freearc(nfa, a);
- }
- break;
- }
+ for (a = from->outs; a != NULL; a = nexta) {
+ nexta = a->outchain;
+ switch (a->type) {
+ case '^':
+ case '$':
+ case BEHIND:
+ case AHEAD:
+ if (from == a->to) {
+ freearc(nfa, a);
+ }
+ break;
}
+ }
- /* first, clone from state if necessary to avoid other outarcs */
- if (from->nouts > 1) {
- s = newstate(nfa);
- 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 */
- freearc(nfa, con);
- from = s;
- con = from->outs;
- }
- assert(from->nouts == 1);
+ /*
+ * First, clone from state if necessary to avoid other outarcs.
+ */
- /* propagate the constraint into the from state's inarcs */
- for (a = from->ins; a != NULL; a = nexta) {
- nexta = a->inchain;
- switch (combine(con, a)) {
- case INCOMPATIBLE: /* destroy the arc */
- freearc(nfa, a);
- break;
- case SATISFIED: /* no action needed */
- break;
- case COMPATIBLE: /* swap the two arcs, more or less */
- s = newstate(nfa);
- if (NISERR())
- return 0;
- cparc(nfa, a, s, to); /* anticipate move */
- cparc(nfa, con, a->from, s);
- if (NISERR())
- return 0;
- freearc(nfa, a);
- break;
- default:
- assert(NOTREACHED);
- break;
- }
+ if (from->nouts > 1) {
+ s = newstate(nfa);
+ 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 */
+ freearc(nfa, con);
+ from = s;
+ con = from->outs;
+ }
+ assert(from->nouts == 1);
+
+ /*
+ * Propagate the constraint into the from state's inarcs.
+ */
+
+ for (a=from->ins ; a!=NULL ; a=nexta) {
+ nexta = a->inchain;
+ switch (combine(con, a)) {
+ case INCOMPATIBLE: /* destroy the arc */
+ freearc(nfa, a);
+ break;
+ case SATISFIED: /* no action needed */
+ break;
+ case COMPATIBLE: /* swap the two arcs, more or less */
+ s = newstate(nfa);
+ if (NISERR()) {
+ return 0;
+ }
+ cparc(nfa, a, s, to); /* anticipate move */
+ cparc(nfa, con, a->from, s);
+ if (NISERR()) {
+ return 0;
+ }
+ freearc(nfa, a);
+ break;
+ default:
+ assert(NOTREACHED);
+ break;
+ }
+ }
- /* remaining inarcs, if any, incorporate the constraint */
- moveins(nfa, from, to);
- dropstate(nfa, from); /* will free the constraint */
- return 1;
-}
+ /*
+ * Remaining inarcs, if any, incorporate the constraint.
+ */
+ moveins(nfa, from, to);
+ dropstate(nfa, from); /* will free the constraint */
+ return 1;
+}
+
/*
- pushfwd - push forward constraints forward to (with luck) eliminate them
^ static VOID pushfwd(struct nfa *, FILE *);
*/
-static VOID
-pushfwd(nfa, f)
-struct nfa *nfa;
-FILE *f; /* for debug output; NULL none */
+static void
+pushfwd(
+ struct nfa *nfa,
+ FILE *f) /* for debug output; NULL none */
{
- struct state *s;
- struct state *nexts;
- struct arc *a;
- struct arc *nexta;
- int progress;
-
- /* find and push until there are no more */
- do {
- progress = 0;
- for (s = nfa->states; s != NULL && !NISERR(); s = nexts) {
- nexts = s->next;
- for (a = s->ins; a != NULL && !NISERR(); a = nexta) {
- nexta = a->inchain;
- if (a->type == '$' || a->type == AHEAD)
- if (push(nfa, a))
- progress = 1;
- assert(nexta == NULL || s->no != FREESTATE);
- }
- }
- if (progress && f != NULL)
- dumpnfa(nfa, f);
- } while (progress && !NISERR());
- if (NISERR())
- return;
-
- for (a = nfa->post->ins; a != NULL; a = nexta) {
+ struct state *s;
+ struct state *nexts;
+ struct arc *a;
+ struct arc *nexta;
+ int progress;
+
+ /*
+ * Find and push until there are no more.
+ */
+
+ do {
+ progress = 0;
+ for (s=nfa->states ; s!=NULL && !NISERR() ; s=nexts) {
+ nexts = s->next;
+ for (a = s->ins; a != NULL && !NISERR(); a = nexta) {
nexta = a->inchain;
- if (a->type == '$') {
- assert(a->co == 0 || a->co == 1);
- newarc(nfa, PLAIN, nfa->eos[a->co], a->from, a->to);
- freearc(nfa, a);
+ if (a->type == '$' || a->type == AHEAD) {
+ if (push(nfa, a)) {
+ progress = 1;
+ }
}
+ assert(nexta == NULL || s->no != FREESTATE);
+ }
+ }
+ if (progress && f != NULL) {
+ dumpnfa(nfa, f);
}
+ } while (progress && !NISERR());
+ if (NISERR()) {
+ return;
+ }
+
+ for (a = nfa->post->ins; a != NULL; a = nexta) {
+ nexta = a->inchain;
+ if (a->type == '$') {
+ assert(a->co == 0 || a->co == 1);
+ newarc(nfa, PLAIN, nfa->eos[a->co], a->from, a->to);
+ freearc(nfa, a);
+ }
+ }
}
-
+
/*
- push - push a forward constraint forward past its destination state
* A significant property of this function is that it deletes at most
@@ -982,94 +1064,106 @@ FILE *f; /* for debug output; NULL none */
^ static int push(struct nfa *, struct arc *);
*/
static int /* 0 couldn't, 1 could */
-push(nfa, con)
-struct nfa *nfa;
-struct arc *con;
+push(
+ struct nfa *nfa,
+ struct arc *con)
{
- struct state *from = con->from;
- struct state *to = con->to;
- struct arc *a;
- struct arc *nexta;
- struct state *s;
-
- if (to == from) { /* circular constraint is pointless */
- freearc(nfa, con);
- return 1;
- }
- if (to->flag) /* can't push forward beyond end */
- return 0;
- if (to->nouts == 0) { /* dead end */
- freearc(nfa, con);
- return 1;
+ struct state *from = con->from;
+ struct state *to = con->to;
+ struct arc *a;
+ struct arc *nexta;
+ struct state *s;
+
+ if (to == from) { /* circular constraint is pointless */
+ freearc(nfa, con);
+ return 1;
+ }
+ if (to->flag) { /* can't push forward beyond end */
+ return 0;
+ }
+ if (to->nouts == 0) { /* dead end */
+ freearc(nfa, con);
+ return 1;
+ }
+
+ /*
+ * DGP 2007-11-15: Here we duplicate the same protections as appear
+ * in pull() above to avoid troubles with cloning a state with a
+ * circular constraint on its list of ins. It is not clear whether
+ * this is necessary, or is protecting against a "can't happen".
+ * Any test case that actually leads to a freearc() call here would
+ * be a welcome addition to the test suite.
+ */
+
+ for (a = to->ins; a != NULL; a = nexta) {
+ nexta = a->inchain;
+ switch (a->type) {
+ case '^':
+ case '$':
+ case BEHIND:
+ case AHEAD:
+ if (a->from == to) {
+ freearc(nfa, a);
+ }
+ break;
}
+ }
+ /*
+ * First, clone to state if necessary to avoid other inarcs.
+ */
- /*
- * DGP 2007-11-15: Here we duplicate the same protections as appear
- * in pull() above to avoid troubles with cloning a state with a
- * circular constraint on its list of ins. It is not clear whether
- * this is necessary, or is protecting against a "can't happen".
- * Any test case that actually leads to a freearc() call here would
- * be a welcome addition to the test suite.
- */
-
- for (a = to->ins; a != NULL; a = nexta) {
- nexta = a->inchain;
- switch (a->type) {
- case '^':
- case '$':
- case BEHIND:
- case AHEAD:
- if (a->from == to) {
- freearc(nfa, a);
- }
- break;
- }
+ if (to->nins > 1) {
+ s = newstate(nfa);
+ if (NISERR()) {
+ return 0;
}
-
- /* first, clone to state if necessary to avoid other inarcs */
- if (to->nins > 1) {
- s = newstate(nfa);
- if (NISERR())
- return 0;
- copyouts(nfa, to, s); /* duplicate outarcs */
- cparc(nfa, con, from, s); /* move constraint */
- freearc(nfa, con);
- to = s;
- con = to->ins;
+ copyouts(nfa, to, s); /* duplicate outarcs */
+ cparc(nfa, con, from, s); /* move constraint */
+ freearc(nfa, con);
+ to = s;
+ con = to->ins;
+ }
+ assert(to->nins == 1);
+
+ /*
+ * Propagate the constraint into the to state's outarcs.
+ */
+
+ for (a = to->outs; a != NULL; a = nexta) {
+ nexta = a->outchain;
+ switch (combine(con, a)) {
+ case INCOMPATIBLE: /* destroy the arc */
+ freearc(nfa, a);
+ break;
+ case SATISFIED: /* no action needed */
+ break;
+ case COMPATIBLE: /* swap the two arcs, more or less */
+ s = newstate(nfa);
+ if (NISERR()) {
+ return 0;
+ }
+ cparc(nfa, con, s, a->to); /* anticipate move */
+ cparc(nfa, a, from, s);
+ if (NISERR()) {
+ return 0;
+ }
+ freearc(nfa, a);
+ break;
+ default:
+ assert(NOTREACHED);
+ break;
}
- assert(to->nins == 1);
+ }
- /* propagate the constraint into the to state's outarcs */
- for (a = to->outs; a != NULL; a = nexta) {
- nexta = a->outchain;
- switch (combine(con, a)) {
- case INCOMPATIBLE: /* destroy the arc */
- freearc(nfa, a);
- break;
- case SATISFIED: /* no action needed */
- break;
- case COMPATIBLE: /* swap the two arcs, more or less */
- s = newstate(nfa);
- if (NISERR())
- return 0;
- cparc(nfa, con, s, a->to); /* anticipate move */
- cparc(nfa, a, from, s);
- if (NISERR())
- return 0;
- freearc(nfa, a);
- break;
- default:
- assert(NOTREACHED);
- break;
- }
- }
+ /*
+ * Remaining outarcs, if any, incorporate the constraint.
+ */
- /* remaining outarcs, if any, incorporate the constraint */
- moveouts(nfa, to, from);
- dropstate(nfa, to); /* will free the constraint */
- return 1;
+ moveouts(nfa, to, from);
+ dropstate(nfa, to); /* will free the constraint */
+ return 1;
}
-
+
/*
- combine - constraint lands on an arc, what happens?
^ #def INCOMPATIBLE 1 // destroys arc
@@ -1078,397 +1172,450 @@ struct arc *con;
^ static int combine(struct arc *, struct arc *);
*/
static int
-combine(con, a)
-struct arc *con;
-struct arc *a;
+combine(
+ struct arc *con,
+ struct arc *a)
{
-# define CA(ct,at) (((ct)<<CHAR_BIT) | (at))
-
- switch (CA(con->type, a->type)) {
- case CA('^', PLAIN): /* newlines are handled separately */
- case CA('$', PLAIN):
- return INCOMPATIBLE;
- break;
- case CA(AHEAD, PLAIN): /* color constraints meet colors */
- case CA(BEHIND, PLAIN):
- if (con->co == a->co)
- return SATISFIED;
- return INCOMPATIBLE;
- break;
- case CA('^', '^'): /* collision, similar constraints */
- case CA('$', '$'):
- case CA(AHEAD, AHEAD):
- case CA(BEHIND, BEHIND):
- if (con->co == a->co) /* true duplication */
- return SATISFIED;
- return INCOMPATIBLE;
- break;
- case CA('^', BEHIND): /* collision, dissimilar constraints */
- case CA(BEHIND, '^'):
- case CA('$', AHEAD):
- case CA(AHEAD, '$'):
- return INCOMPATIBLE;
- break;
- case CA('^', '$'): /* constraints passing each other */
- case CA('^', AHEAD):
- case CA(BEHIND, '$'):
- case CA(BEHIND, AHEAD):
- case CA('$', '^'):
- case CA('$', BEHIND):
- case CA(AHEAD, '^'):
- case CA(AHEAD, BEHIND):
- case CA('^', LACON):
- case CA(BEHIND, LACON):
- case CA('$', LACON):
- case CA(AHEAD, LACON):
- return COMPATIBLE;
- break;
+#define CA(ct,at) (((ct)<<CHAR_BIT) | (at))
+
+ switch (CA(con->type, a->type)) {
+ case CA('^', PLAIN): /* newlines are handled separately */
+ case CA('$', PLAIN):
+ return INCOMPATIBLE;
+ break;
+ case CA(AHEAD, PLAIN): /* color constraints meet colors */
+ case CA(BEHIND, PLAIN):
+ if (con->co == a->co) {
+ return SATISFIED;
+ }
+ return INCOMPATIBLE;
+ break;
+ case CA('^', '^'): /* collision, similar constraints */
+ case CA('$', '$'):
+ case CA(AHEAD, AHEAD):
+ case CA(BEHIND, BEHIND):
+ if (con->co == a->co) { /* true duplication */
+ return SATISFIED;
}
- assert(NOTREACHED);
- return INCOMPATIBLE; /* for benefit of blind compilers */
+ return INCOMPATIBLE;
+ break;
+ case CA('^', BEHIND): /* collision, dissimilar constraints */
+ case CA(BEHIND, '^'):
+ case CA('$', AHEAD):
+ case CA(AHEAD, '$'):
+ return INCOMPATIBLE;
+ break;
+ case CA('^', '$'): /* constraints passing each other */
+ case CA('^', AHEAD):
+ case CA(BEHIND, '$'):
+ case CA(BEHIND, AHEAD):
+ case CA('$', '^'):
+ case CA('$', BEHIND):
+ case CA(AHEAD, '^'):
+ case CA(AHEAD, BEHIND):
+ case CA('^', LACON):
+ case CA(BEHIND, LACON):
+ case CA('$', LACON):
+ case CA(AHEAD, LACON):
+ return COMPATIBLE;
+ break;
+ }
+ assert(NOTREACHED);
+ return INCOMPATIBLE; /* for benefit of blind compilers */
}
-
+
/*
- fixempties - get rid of EMPTY arcs
^ static VOID fixempties(struct nfa *, FILE *);
*/
-static VOID
-fixempties(nfa, f)
-struct nfa *nfa;
-FILE *f; /* for debug output; NULL none */
+static void
+fixempties(
+ struct nfa *nfa,
+ FILE *f) /* for debug output; NULL none */
{
- struct state *s;
- struct state *nexts;
- struct arc *a;
- struct arc *nexta;
- int progress;
-
- /* find and eliminate empties until there are no more */
- 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);
- }
+ struct state *s;
+ struct state *nexts;
+ struct arc *a;
+ struct arc *nexta;
+ int progress;
+
+ /*
+ * Find and eliminate empties until there are no more.
+ */
+
+ 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;
}
- if (progress && f != NULL)
- dumpnfa(nfa, f);
- } while (progress && !NISERR());
+ assert(nexta == NULL || s->no != FREESTATE);
+ }
+ }
+ if (progress && f != NULL) {
+ dumpnfa(nfa, f);
+ }
+ } while (progress && !NISERR());
}
-
+
/*
- 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.
+ * 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 *);
*/
static int /* 0 couldn't, 1 could */
-unempty(nfa, a)
-struct nfa *nfa;
-struct arc *a;
+unempty(
+ struct nfa *nfa,
+ struct arc *a)
{
- struct state *from = a->from;
- struct state *to = a->to;
- int usefrom; /* work on from, as opposed to to? */
+ 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);
+ assert(a->type == EMPTY);
+ assert(from != nfa->pre && to != nfa->post);
- if (from == to) { /* vacuous loop */
- freearc(nfa, a);
- return 1;
+ if (from == to) { /* vacuous loop */
+ freearc(nfa, a);
+ return 1;
+ }
+
+ /*
+ * Decide which end to work on.
+ */
+
+ 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;
}
+ }
- /* decide which end to work on */
- 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;
+ 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);
}
-
- 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 {
- if (to->nins == 0) {
- /* was the state's only inarc */
- moveouts(nfa, to, from);
- freestate(nfa, to);
- } else
- copyouts(nfa, to, from);
+ copyouts(nfa, to, from);
}
+ }
- return 1;
+ return 1;
}
-
+
/*
- cleanup - clean up NFA after optimizations
^ static VOID cleanup(struct nfa *);
*/
-static VOID
-cleanup(nfa)
-struct nfa *nfa;
+static void
+cleanup(
+ struct nfa *nfa)
{
- struct state *s;
- struct state *nexts;
- int n;
-
- /* clear out unreachable or dead-end states */
- /* use pre to mark reachable, then post to mark can-reach-post */
- markreachable(nfa, nfa->pre, (struct state *)NULL, nfa->pre);
- markcanreach(nfa, nfa->post, nfa->pre, nfa->post);
- for (s = nfa->states; s != NULL; s = nexts) {
- nexts = s->next;
- if (s->tmp != nfa->post && !s->flag)
- dropstate(nfa, s);
+ struct state *s;
+ struct state *nexts;
+ int n;
+
+ /*
+ * Clear out unreachable or dead-end states. Use pre to mark reachable,
+ * then post to mark can-reach-post.
+ */
+
+ markreachable(nfa, nfa->pre, NULL, nfa->pre);
+ markcanreach(nfa, nfa->post, nfa->pre, nfa->post);
+ for (s = nfa->states; s != NULL; s = nexts) {
+ nexts = s->next;
+ if (s->tmp != nfa->post && !s->flag) {
+ dropstate(nfa, s);
}
- assert(nfa->post->nins == 0 || nfa->post->tmp == nfa->post);
- cleartraverse(nfa, nfa->pre);
- assert(nfa->post->nins == 0 || nfa->post->tmp == NULL);
- /* the nins==0 (final unreachable) case will be caught later */
-
- /* renumber surviving states */
- n = 0;
- for (s = nfa->states; s != NULL; s = s->next)
- s->no = n++;
- nfa->nstates = n;
+ }
+ assert(nfa->post->nins == 0 || nfa->post->tmp == nfa->post);
+ cleartraverse(nfa, nfa->pre);
+ assert(nfa->post->nins == 0 || nfa->post->tmp == NULL);
+ /* the nins==0 (final unreachable) case will be caught later */
+
+ /*
+ * Renumber surviving states.
+ */
+
+ n = 0;
+ for (s = nfa->states; s != NULL; s = s->next) {
+ s->no = n++;
+ }
+ nfa->nstates = n;
}
-
+
/*
- markreachable - recursive marking of reachable states
^ static VOID markreachable(struct nfa *, struct state *, struct state *,
^ struct state *);
*/
-static VOID
-markreachable(nfa, s, okay, mark)
-struct nfa *nfa;
-struct state *s;
-struct state *okay; /* consider only states with this mark */
-struct state *mark; /* the value to mark with */
+static void
+markreachable(
+ struct nfa *nfa,
+ struct state *s,
+ struct state *okay, /* consider only states with this mark */
+ struct state *mark) /* the value to mark with */
{
- struct arc *a;
+ struct arc *a;
- if (s->tmp != okay)
- return;
- s->tmp = mark;
+ if (s->tmp != okay) {
+ return;
+ }
+ s->tmp = mark;
- for (a = s->outs; a != NULL; a = a->outchain)
- markreachable(nfa, a->to, okay, mark);
+ for (a = s->outs; a != NULL; a = a->outchain) {
+ markreachable(nfa, a->to, okay, mark);
+ }
}
-
+
/*
- markcanreach - recursive marking of states which can reach here
^ static VOID markcanreach(struct nfa *, struct state *, struct state *,
^ struct state *);
*/
-static VOID
-markcanreach(nfa, s, okay, mark)
-struct nfa *nfa;
-struct state *s;
-struct state *okay; /* consider only states with this mark */
-struct state *mark; /* the value to mark with */
+static void
+markcanreach(
+ struct nfa *nfa,
+ struct state *s,
+ struct state *okay, /* consider only states with this mark */
+ struct state *mark) /* the value to mark with */
{
- struct arc *a;
+ struct arc *a;
- if (s->tmp != okay)
- return;
- s->tmp = mark;
+ if (s->tmp != okay) {
+ return;
+ }
+ s->tmp = mark;
- for (a = s->ins; a != NULL; a = a->inchain)
- markcanreach(nfa, a->from, okay, mark);
+ for (a = s->ins; a != NULL; a = a->inchain) {
+ markcanreach(nfa, a->from, okay, mark);
+ }
}
-
+
/*
- analyze - ascertain potentially-useful facts about an optimized NFA
^ static long analyze(struct nfa *);
*/
static long /* re_info bits to be ORed in */
-analyze(nfa)
-struct nfa *nfa;
+analyze(
+ struct nfa *nfa)
{
- struct arc *a;
- struct arc *aa;
-
- if (nfa->pre->outs == NULL)
- return REG_UIMPOSSIBLE;
- for (a = nfa->pre->outs; a != NULL; a = a->outchain)
- for (aa = a->to->outs; aa != NULL; aa = aa->outchain)
- if (aa->to == nfa->post)
- return REG_UEMPTYMATCH;
- return 0;
+ struct arc *a;
+ struct arc *aa;
+
+ if (nfa->pre->outs == NULL) {
+ return REG_UIMPOSSIBLE;
+ }
+ for (a = nfa->pre->outs; a != NULL; a = a->outchain) {
+ for (aa = a->to->outs; aa != NULL; aa = aa->outchain) {
+ if (aa->to == nfa->post) {
+ return REG_UEMPTYMATCH;
+ }
+ }
+ }
+ return 0;
}
-
+
/*
- compact - compact an NFA
^ static VOID compact(struct nfa *, struct cnfa *);
*/
-static VOID
-compact(nfa, cnfa)
-struct nfa *nfa;
-struct cnfa *cnfa;
+static void
+compact(
+ struct nfa *nfa,
+ struct cnfa *cnfa)
{
- struct state *s;
- struct arc *a;
- size_t nstates;
- size_t narcs;
- struct carc *ca;
- struct carc *first;
-
- assert (!NISERR());
-
- nstates = 0;
- narcs = 0;
- for (s = nfa->states; s != NULL; s = s->next) {
- nstates++;
- narcs += 1 + s->nouts + 1;
- /* 1 as a fake for flags, nouts for arcs, 1 as endmarker */
+ struct state *s;
+ struct arc *a;
+ size_t nstates;
+ size_t narcs;
+ struct carc *ca;
+ struct carc *first;
+
+ assert(!NISERR());
+
+ nstates = 0;
+ narcs = 0;
+ for (s = nfa->states; s != NULL; s = s->next) {
+ nstates++;
+ narcs += 1 + s->nouts + 1;
+ /* 1 as a fake for flags, nouts for arcs, 1 as endmarker */
+ }
+
+ cnfa->states = (struct carc **) MALLOC(nstates * sizeof(struct carc *));
+ cnfa->arcs = (struct carc *) MALLOC(narcs * sizeof(struct carc));
+ if (cnfa->states == NULL || cnfa->arcs == NULL) {
+ if (cnfa->states != NULL) {
+ FREE(cnfa->states);
}
-
- cnfa->states = (struct carc **)MALLOC(nstates * sizeof(struct carc *));
- cnfa->arcs = (struct carc *)MALLOC(narcs * sizeof(struct carc));
- if (cnfa->states == NULL || cnfa->arcs == NULL) {
- if (cnfa->states != NULL)
- FREE(cnfa->states);
- if (cnfa->arcs != NULL)
- FREE(cnfa->arcs);
- NERR(REG_ESPACE);
- return;
+ if (cnfa->arcs != NULL) {
+ FREE(cnfa->arcs);
}
- cnfa->nstates = nstates;
- cnfa->pre = nfa->pre->no;
- cnfa->post = nfa->post->no;
- cnfa->bos[0] = nfa->bos[0];
- cnfa->bos[1] = nfa->bos[1];
- cnfa->eos[0] = nfa->eos[0];
- cnfa->eos[1] = nfa->eos[1];
- cnfa->ncolors = maxcolor(nfa->cm) + 1;
- cnfa->flags = 0;
-
- ca = cnfa->arcs;
- for (s = nfa->states; s != NULL; s = s->next) {
- assert((size_t)s->no < nstates);
- cnfa->states[s->no] = ca;
- ca->co = 0; /* clear and skip flags "arc" */
+ NERR(REG_ESPACE);
+ return;
+ }
+ cnfa->nstates = nstates;
+ cnfa->pre = nfa->pre->no;
+ cnfa->post = nfa->post->no;
+ cnfa->bos[0] = nfa->bos[0];
+ cnfa->bos[1] = nfa->bos[1];
+ cnfa->eos[0] = nfa->eos[0];
+ cnfa->eos[1] = nfa->eos[1];
+ cnfa->ncolors = maxcolor(nfa->cm) + 1;
+ cnfa->flags = 0;
+
+ ca = cnfa->arcs;
+ for (s = nfa->states; s != NULL; s = s->next) {
+ assert((size_t) s->no < nstates);
+ cnfa->states[s->no] = ca;
+ ca->co = 0; /* clear and skip flags "arc" */
+ ca++;
+ first = ca;
+ for (a = s->outs; a != NULL; a = a->outchain) {
+ switch (a->type) {
+ case PLAIN:
+ ca->co = a->co;
+ ca->to = a->to->no;
ca++;
- first = ca;
- for (a = s->outs; a != NULL; a = a->outchain)
- switch (a->type) {
- case PLAIN:
- ca->co = a->co;
- ca->to = a->to->no;
- ca++;
- break;
- case LACON:
- assert(s->no != cnfa->pre);
- ca->co = (color)(cnfa->ncolors + a->co);
- ca->to = a->to->no;
- ca++;
- cnfa->flags |= HASLACONS;
- break;
- default:
- assert(NOTREACHED);
- break;
- }
- carcsort(first, ca-1);
- ca->co = COLORLESS;
- ca->to = 0;
+ break;
+ case LACON:
+ assert(s->no != cnfa->pre);
+ ca->co = (color) (cnfa->ncolors + a->co);
+ ca->to = a->to->no;
ca++;
+ cnfa->flags |= HASLACONS;
+ break;
+ default:
+ assert(NOTREACHED);
+ break;
+ }
}
- assert(ca == &cnfa->arcs[narcs]);
- assert(cnfa->nstates != 0);
-
- /* mark no-progress states */
- for (a = nfa->pre->outs; a != NULL; a = a->outchain)
- cnfa->states[a->to->no]->co = 1;
- cnfa->states[nfa->pre->no]->co = 1;
+ carcsort(first, ca-1);
+ ca->co = COLORLESS;
+ ca->to = 0;
+ ca++;
+ }
+ assert(ca == &cnfa->arcs[narcs]);
+ assert(cnfa->nstates != 0);
+
+ /*
+ * Mark no-progress states.
+ */
+
+ for (a = nfa->pre->outs; a != NULL; a = a->outchain) {
+ cnfa->states[a->to->no]->co = 1;
+ }
+ cnfa->states[nfa->pre->no]->co = 1;
}
-
+
/*
- carcsort - sort compacted-NFA arcs by color
* Really dumb algorithm, but if the list is long enough for that to matter,
* you're in real trouble anyway.
^ static VOID carcsort(struct carc *, struct carc *);
*/
-static VOID
-carcsort(first, last)
-struct carc *first;
-struct carc *last;
+static void
+carcsort(
+ struct carc *first,
+ struct carc *last)
{
- struct carc *p;
- struct carc *q;
- struct carc tmp;
-
- if (last - first <= 1)
- return;
-
- for (p = first; p <= last; p++)
- for (q = p; q <= last; q++)
- if (p->co > q->co ||
- (p->co == q->co && p->to > q->to)) {
- assert(p != q);
- tmp = *p;
- *p = *q;
- *q = tmp;
- }
-}
+ struct carc *p;
+ struct carc *q;
+ struct carc tmp;
+ if (last - first <= 1) {
+ return;
+ }
+
+ for (p = first; p <= last; p++) {
+ for (q = p; q <= last; q++) {
+ if (p->co > q->co || (p->co == q->co && p->to > q->to)) {
+ assert(p != q);
+ tmp = *p;
+ *p = *q;
+ *q = tmp;
+ }
+ }
+ }
+}
+
/*
- freecnfa - free a compacted NFA
^ static VOID freecnfa(struct cnfa *);
*/
-static VOID
-freecnfa(cnfa)
-struct cnfa *cnfa;
+static void
+freecnfa(
+ struct cnfa *cnfa)
{
- assert(cnfa->nstates != 0); /* not empty already */
- cnfa->nstates = 0;
- FREE(cnfa->states);
- FREE(cnfa->arcs);
+ assert(cnfa->nstates != 0); /* not empty already */
+ cnfa->nstates = 0;
+ FREE(cnfa->states);
+ FREE(cnfa->arcs);
}
-
+
/*
- dumpnfa - dump an NFA in human-readable form
^ static VOID dumpnfa(struct nfa *, FILE *);
*/
-static VOID
-dumpnfa(nfa, f)
-struct nfa *nfa;
-FILE *f;
+static void
+dumpnfa(
+ struct nfa *nfa,
+ FILE *f)
{
#ifdef REG_DEBUG
- struct state *s;
-
- fprintf(f, "pre %d, post %d", nfa->pre->no, nfa->post->no);
- if (nfa->bos[0] != COLORLESS)
- fprintf(f, ", bos [%ld]", (long)nfa->bos[0]);
- if (nfa->bos[1] != COLORLESS)
- fprintf(f, ", bol [%ld]", (long)nfa->bos[1]);
- if (nfa->eos[0] != COLORLESS)
- fprintf(f, ", eos [%ld]", (long)nfa->eos[0]);
- if (nfa->eos[1] != COLORLESS)
- fprintf(f, ", eol [%ld]", (long)nfa->eos[1]);
- fprintf(f, "\n");
- for (s = nfa->states; s != NULL; s = s->next)
- dumpstate(s, f);
- if (nfa->parent == NULL)
- dumpcolors(nfa->cm, f);
- fflush(f);
+ struct state *s;
+
+ fprintf(f, "pre %d, post %d", nfa->pre->no, nfa->post->no);
+ if (nfa->bos[0] != COLORLESS) {
+ fprintf(f, ", bos [%ld]", (long) nfa->bos[0]);
+ }
+ if (nfa->bos[1] != COLORLESS) {
+ fprintf(f, ", bol [%ld]", (long) nfa->bos[1]);
+ }
+ if (nfa->eos[0] != COLORLESS) {
+ fprintf(f, ", eos [%ld]", (long) nfa->eos[0]);
+ }
+ if (nfa->eos[1] != COLORLESS) {
+ fprintf(f, ", eol [%ld]", (long) nfa->eos[1]);
+ }
+ fprintf(f, "\n");
+ for (s = nfa->states; s != NULL; s = s->next) {
+ dumpstate(s, f);
+ }
+ if (nfa->parent == NULL) {
+ dumpcolors(nfa->cm, f);
+ }
+ fflush(f);
#endif
}
-
+
#ifdef REG_DEBUG /* subordinates of dumpnfa */
/*
^ #ifdef REG_DEBUG
@@ -1478,165 +1625,185 @@ FILE *f;
- dumpstate - dump an NFA state in human-readable form
^ static VOID dumpstate(struct state *, FILE *);
*/
-static VOID
-dumpstate(s, f)
-struct state *s;
-FILE *f;
+static void
+dumpstate(
+ struct state *s,
+ FILE *f)
{
- struct arc *a;
-
- fprintf(f, "%d%s%c", s->no, (s->tmp != NULL) ? "T" : "",
- (s->flag) ? s->flag : '.');
- if (s->prev != NULL && s->prev->next != s)
- fprintf(f, "\tstate chain bad\n");
- if (s->nouts == 0)
- fprintf(f, "\tno out arcs\n");
- else
- dumparcs(s, f);
- fflush(f);
- for (a = s->ins; a != NULL; a = a->inchain) {
- if (a->to != s)
- fprintf(f, "\tlink from %d to %d on %d's in-chain\n",
- a->from->no, a->to->no, s->no);
+ struct arc *a;
+
+ fprintf(f, "%d%s%c", s->no, (s->tmp != NULL) ? "T" : "",
+ (s->flag) ? s->flag : '.');
+ if (s->prev != NULL && s->prev->next != s) {
+ fprintf(f, "\tstate chain bad\n");
+ }
+ if (s->nouts == 0) {
+ fprintf(f, "\tno out arcs\n");
+ } else {
+ dumparcs(s, f);
+ }
+ fflush(f);
+ for (a = s->ins; a != NULL; a = a->inchain) {
+ if (a->to != s) {
+ fprintf(f, "\tlink from %d to %d on %d's in-chain\n",
+ a->from->no, a->to->no, s->no);
}
+ }
}
-
+
/*
- dumparcs - dump out-arcs in human-readable form
^ static VOID dumparcs(struct state *, FILE *);
*/
-static VOID
-dumparcs(s, f)
-struct state *s;
-FILE *f;
+static void
+dumparcs(
+ struct state *s,
+ FILE *f)
{
- int pos;
+ int pos;
- assert(s->nouts > 0);
- /* printing arcs in reverse order is usually clearer */
- pos = dumprarcs(s->outs, s, f, 1);
- if (pos != 1)
- fprintf(f, "\n");
+ assert(s->nouts > 0);
+ /* printing arcs in reverse order is usually clearer */
+ pos = dumprarcs(s->outs, s, f, 1);
+ if (pos != 1) {
+ fprintf(f, "\n");
+ }
}
-
+
/*
- dumprarcs - dump remaining outarcs, recursively, in reverse order
^ static int dumprarcs(struct arc *, struct state *, FILE *, int);
*/
static int /* resulting print position */
-dumprarcs(a, s, f, pos)
-struct arc *a;
-struct state *s;
-FILE *f;
-int pos; /* initial print position */
+dumprarcs(
+ struct arc *a,
+ struct state *s,
+ FILE *f,
+ int pos) /* initial print position */
{
- if (a->outchain != NULL)
- pos = dumprarcs(a->outchain, s, f, pos);
- dumparc(a, s, f);
- if (pos == 5) {
- fprintf(f, "\n");
- pos = 1;
- } else
- pos++;
- return pos;
+ if (a->outchain != NULL) {
+ pos = dumprarcs(a->outchain, s, f, pos);
+ }
+ dumparc(a, s, f);
+ if (pos == 5) {
+ fprintf(f, "\n");
+ pos = 1;
+ } else {
+ pos++;
+ }
+ return pos;
}
-
+
/*
- dumparc - dump one outarc in readable form, including prefixing tab
^ static VOID dumparc(struct arc *, struct state *, FILE *);
*/
-static VOID
-dumparc(a, s, f)
-struct arc *a;
-struct state *s;
-FILE *f;
+static void
+dumparc(
+ struct arc *a,
+ struct state *s,
+ FILE *f)
{
- struct arc *aa;
- struct arcbatch *ab;
-
- fprintf(f, "\t");
- switch (a->type) {
- case PLAIN:
- fprintf(f, "[%ld]", (long)a->co);
- break;
- case AHEAD:
- fprintf(f, ">%ld>", (long)a->co);
- break;
- case BEHIND:
- fprintf(f, "<%ld<", (long)a->co);
- break;
- case LACON:
- fprintf(f, ":%ld:", (long)a->co);
- break;
- case '^':
- case '$':
- fprintf(f, "%c%d", a->type, (int)a->co);
- break;
- case EMPTY:
- break;
- default:
- fprintf(f, "0x%x/0%lo", a->type, (long)a->co);
- break;
+ struct arc *aa;
+ struct arcbatch *ab;
+
+ fprintf(f, "\t");
+ switch (a->type) {
+ case PLAIN:
+ fprintf(f, "[%ld]", (long) a->co);
+ break;
+ case AHEAD:
+ fprintf(f, ">%ld>", (long) a->co);
+ break;
+ case BEHIND:
+ fprintf(f, "<%ld<", (long) a->co);
+ break;
+ case LACON:
+ fprintf(f, ":%ld:", (long) a->co);
+ break;
+ case '^':
+ case '$':
+ fprintf(f, "%c%d", a->type, (int) a->co);
+ break;
+ case EMPTY:
+ break;
+ default:
+ fprintf(f, "0x%x/0%lo", a->type, (long) a->co);
+ break;
+ }
+ if (a->from != s) {
+ fprintf(f, "?%d?", a->from->no);
+ }
+ for (ab = &a->from->oas; ab != NULL; ab = ab->next) {
+ for (aa = &ab->a[0]; aa < &ab->a[ABSIZE]; aa++) {
+ if (aa == a) {
+ break; /* NOTE BREAK OUT */
+ }
}
- if (a->from != s)
- fprintf(f, "?%d?", a->from->no);
- for (ab = &a->from->oas; ab != NULL; ab = ab->next) {
- for (aa = &ab->a[0]; aa < &ab->a[ABSIZE]; aa++)
- if (aa == a)
- break; /* NOTE BREAK OUT */
- if (aa < &ab->a[ABSIZE]) /* propagate break */
- break; /* NOTE BREAK OUT */
+ if (aa < &ab->a[ABSIZE]) { /* propagate break */
+ break; /* NOTE BREAK OUT */
}
- if (ab == NULL)
- fprintf(f, "?!?"); /* not in allocated space */
- fprintf(f, "->");
- if (a->to == NULL) {
- fprintf(f, "NULL");
- return;
+ }
+ if (ab == NULL) {
+ fprintf(f, "?!?"); /* not in allocated space */
+ }
+ fprintf(f, "->");
+ if (a->to == NULL) {
+ fprintf(f, "NULL");
+ return;
+ }
+ fprintf(f, "%d", a->to->no);
+ for (aa = a->to->ins; aa != NULL; aa = aa->inchain) {
+ if (aa == a) {
+ break; /* NOTE BREAK OUT */
}
- fprintf(f, "%d", a->to->no);
- for (aa = a->to->ins; aa != NULL; aa = aa->inchain)
- if (aa == a)
- break; /* NOTE BREAK OUT */
- if (aa == NULL)
- fprintf(f, "?!?"); /* missing from in-chain */
+ }
+ if (aa == NULL) {
+ fprintf(f, "?!?"); /* missing from in-chain */
+ }
}
/*
^ #endif
*/
#endif /* ifdef REG_DEBUG */
-
+
/*
- dumpcnfa - dump a compacted NFA in human-readable form
^ static VOID dumpcnfa(struct cnfa *, FILE *);
*/
-static VOID
-dumpcnfa(cnfa, f)
-struct cnfa *cnfa;
-FILE *f;
+static void
+dumpcnfa(
+ struct cnfa *cnfa,
+ FILE *f)
{
#ifdef REG_DEBUG
- int st;
-
- fprintf(f, "pre %d, post %d", cnfa->pre, cnfa->post);
- if (cnfa->bos[0] != COLORLESS)
- fprintf(f, ", bos [%ld]", (long)cnfa->bos[0]);
- if (cnfa->bos[1] != COLORLESS)
- fprintf(f, ", bol [%ld]", (long)cnfa->bos[1]);
- if (cnfa->eos[0] != COLORLESS)
- fprintf(f, ", eos [%ld]", (long)cnfa->eos[0]);
- if (cnfa->eos[1] != COLORLESS)
- fprintf(f, ", eol [%ld]", (long)cnfa->eos[1]);
- if (cnfa->flags&HASLACONS)
- fprintf(f, ", haslacons");
- fprintf(f, "\n");
- for (st = 0; st < cnfa->nstates; st++)
- dumpcstate(st, cnfa->states[st], cnfa, f);
- fflush(f);
+ int st;
+
+ fprintf(f, "pre %d, post %d", cnfa->pre, cnfa->post);
+ if (cnfa->bos[0] != COLORLESS) {
+ fprintf(f, ", bos [%ld]", (long) cnfa->bos[0]);
+ }
+ if (cnfa->bos[1] != COLORLESS) {
+ fprintf(f, ", bol [%ld]", (long) cnfa->bos[1]);
+ }
+ if (cnfa->eos[0] != COLORLESS) {
+ fprintf(f, ", eos [%ld]", (long) cnfa->eos[0]);
+ }
+ if (cnfa->eos[1] != COLORLESS) {
+ fprintf(f, ", eol [%ld]", (long) cnfa->eos[1]);
+ }
+ if (cnfa->flags&HASLACONS) {
+ fprintf(f, ", haslacons");
+ }
+ fprintf(f, "\n");
+ for (st = 0; st < cnfa->nstates; st++) {
+ dumpcstate(st, cnfa->states[st], cnfa, f);
+ }
+ fflush(f);
#endif
}
-
+
#ifdef REG_DEBUG /* subordinates of dumpcnfa */
/*
^ #ifdef REG_DEBUG
@@ -1646,36 +1813,46 @@ FILE *f;
- dumpcstate - dump a compacted-NFA state in human-readable form
^ static VOID dumpcstate(int, struct carc *, struct cnfa *, FILE *);
*/
-static VOID
-dumpcstate(st, ca, cnfa, f)
-int st;
-struct carc *ca;
-struct cnfa *cnfa;
-FILE *f;
+static void
+dumpcstate(
+ int st,
+ struct carc *ca,
+ struct cnfa *cnfa,
+ FILE *f)
{
- int i;
- int pos;
-
- fprintf(f, "%d%s", st, (ca[0].co) ? ":" : ".");
- pos = 1;
- for (i = 1; ca[i].co != COLORLESS; i++) {
- if (ca[i].co < cnfa->ncolors)
- fprintf(f, "\t[%ld]->%d", (long)ca[i].co, ca[i].to);
- else
- fprintf(f, "\t:%ld:->%d", (long)ca[i].co-cnfa->ncolors,
- ca[i].to);
- if (pos == 5) {
- fprintf(f, "\n");
- pos = 1;
- } else
- pos++;
+ int i;
+ int pos;
+
+ fprintf(f, "%d%s", st, (ca[0].co) ? ":" : ".");
+ pos = 1;
+ for (i = 1; ca[i].co != COLORLESS; i++) {
+ if (ca[i].co < cnfa->ncolors) {
+ fprintf(f, "\t[%ld]->%d", (long) ca[i].co, ca[i].to);
+ } else {
+ fprintf(f, "\t:%ld:->%d", (long) ca[i].co-cnfa->ncolors,ca[i].to);
}
- if (i == 1 || pos != 1)
- fprintf(f, "\n");
- fflush(f);
+ if (pos == 5) {
+ fprintf(f, "\n");
+ pos = 1;
+ } else {
+ pos++;
+ }
+ }
+ if (i == 1 || pos != 1) {
+ fprintf(f, "\n");
+ }
+ fflush(f);
}
/*
^ #endif
*/
#endif /* ifdef REG_DEBUG */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regcomp.c b/generic/regcomp.c
index c239d8b..6dea04b 100644
--- a/generic/regcomp.c
+++ b/generic/regcomp.c
@@ -2,11 +2,11 @@
* re_*comp and friends - compile REs
* This file #includes several others (see the bottom).
*
- * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
+ * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
*
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
- * Corporation, none of whom are responsible for the results. The author
+ * Corporation, none of whom are responsible for the results. The author
* thanks all of them.
*
* Redistribution and use in source and binary forms -- with or without
@@ -14,12 +14,12 @@
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
*
- * I'd appreciate being given credit for this package in the documentation
- * of software which uses it, but that is not a requirement.
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
@@ -38,198 +38,189 @@
/* =====^!^===== begin forwards =====^!^===== */
/* automatically gathered by fwd; do not hand-edit */
/* === regcomp.c === */
-int compile _ANSI_ARGS_((regex_t *, CONST chr *, size_t, int));
-static VOID moresubs _ANSI_ARGS_((struct vars *, int));
-static int freev _ANSI_ARGS_((struct vars *, int));
-static VOID makesearch _ANSI_ARGS_((struct vars *, struct nfa *));
-static struct subre *parse _ANSI_ARGS_((struct vars *, int, int, struct state *, struct state *));
-static struct subre *parsebranch _ANSI_ARGS_((struct vars *, int, int, struct state *, struct state *, int));
-static VOID parseqatom _ANSI_ARGS_((struct vars *, int, int, struct state *, struct state *, struct subre *));
-static VOID nonword _ANSI_ARGS_((struct vars *, int, struct state *, struct state *));
-static VOID word _ANSI_ARGS_((struct vars *, int, struct state *, struct state *));
-static int scannum _ANSI_ARGS_((struct vars *));
-static VOID repeat _ANSI_ARGS_((struct vars *, struct state *, struct state *, int, int));
-static VOID bracket _ANSI_ARGS_((struct vars *, struct state *, struct state *));
-static VOID cbracket _ANSI_ARGS_((struct vars *, struct state *, struct state *));
-static VOID brackpart _ANSI_ARGS_((struct vars *, struct state *, struct state *));
-static chr *scanplain _ANSI_ARGS_((struct vars *));
-static VOID onechr _ANSI_ARGS_((struct vars *, pchr, struct state *, struct state *));
-static VOID dovec _ANSI_ARGS_((struct vars *, struct cvec *, struct state *, struct state *));
-static celt nextleader _ANSI_ARGS_((struct vars *, pchr, pchr));
-static VOID wordchrs _ANSI_ARGS_((struct vars *));
-static struct subre *subre _ANSI_ARGS_((struct vars *, int, int, struct state *, struct state *));
-static VOID freesubre _ANSI_ARGS_((struct vars *, struct subre *));
-static VOID freesrnode _ANSI_ARGS_((struct vars *, struct subre *));
-static VOID optst _ANSI_ARGS_((struct vars *, struct subre *));
-static int numst _ANSI_ARGS_((struct subre *, int));
-static VOID markst _ANSI_ARGS_((struct subre *));
-static VOID cleanst _ANSI_ARGS_((struct vars *));
-static long nfatree _ANSI_ARGS_((struct vars *, struct subre *, FILE *));
-static long nfanode _ANSI_ARGS_((struct vars *, struct subre *, FILE *));
-static int newlacon _ANSI_ARGS_((struct vars *, struct state *, struct state *, int));
-static VOID freelacons _ANSI_ARGS_((struct subre *, int));
-static VOID rfree _ANSI_ARGS_((regex_t *));
-static VOID dump _ANSI_ARGS_((regex_t *, FILE *));
-static VOID dumpst _ANSI_ARGS_((struct subre *, FILE *, int));
-static VOID stdump _ANSI_ARGS_((struct subre *, FILE *, int));
-static char *stid _ANSI_ARGS_((struct subre *, char *, size_t));
+int compile(regex_t *, const chr *, size_t, int);
+static void moresubs(struct vars *, int);
+static int freev(struct vars *, int);
+static void makesearch(struct vars *, struct nfa *);
+static struct subre *parse(struct vars *, int, int, struct state *, struct state *);
+static struct subre *parsebranch(struct vars *, int, int, struct state *, struct state *, int);
+static void parseqatom(struct vars *, int, int, struct state *, struct state *, struct subre *);
+static void nonword(struct vars *, int, struct state *, struct state *);
+static void word(struct vars *, int, struct state *, struct state *);
+static int scannum(struct vars *);
+static void repeat(struct vars *, struct state *, struct state *, int, int);
+static void bracket(struct vars *, struct state *, struct state *);
+static void cbracket(struct vars *, struct state *, struct state *);
+static void brackpart(struct vars *, struct state *, struct state *);
+static const chr *scanplain(struct vars *);
+static void onechr(struct vars *, pchr, struct state *, struct state *);
+static void dovec(struct vars *, struct cvec *, struct state *, struct state *);
+static void wordchrs(struct vars *);
+static struct subre *subre(struct vars *, int, int, struct state *, struct state *);
+static void freesubre(struct vars *, struct subre *);
+static void freesrnode(struct vars *, struct subre *);
+static void optst(struct vars *, struct subre *);
+static int numst(struct subre *, int);
+static void markst(struct subre *);
+static void cleanst(struct vars *);
+static long nfatree(struct vars *, struct subre *, FILE *);
+static long nfanode(struct vars *, struct subre *, FILE *);
+static int newlacon(struct vars *, struct state *, struct state *, int);
+static void freelacons(struct subre *, int);
+static void rfree(regex_t *);
+static void dump(regex_t *, FILE *);
+static void dumpst(struct subre *, FILE *, int);
+static void stdump(struct subre *, FILE *, int);
+static const char *stid(struct subre *, char *, size_t);
/* === regc_lex.c === */
-static VOID lexstart _ANSI_ARGS_((struct vars *));
-static VOID prefixes _ANSI_ARGS_((struct vars *));
-static VOID lexnest _ANSI_ARGS_((struct vars *, chr *, chr *));
-static VOID lexword _ANSI_ARGS_((struct vars *));
-static int next _ANSI_ARGS_((struct vars *));
-static int lexescape _ANSI_ARGS_((struct vars *));
-static chr lexdigits _ANSI_ARGS_((struct vars *, int, int, int));
-static int brenext _ANSI_ARGS_((struct vars *, pchr));
-static VOID skip _ANSI_ARGS_((struct vars *));
-static chr newline _ANSI_ARGS_((NOPARMS));
+static void lexstart(struct vars *);
+static void prefixes(struct vars *);
+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 brenext(struct vars *, pchr);
+static void skip(struct vars *);
+static chr newline(NOPARMS);
#ifdef REG_DEBUG
-static chr *ch _ANSI_ARGS_((NOPARMS));
+static const chr *ch(NOPARMS);
#endif
-static chr chrnamed _ANSI_ARGS_((struct vars *, chr *, chr *, pchr));
+static chr chrnamed(struct vars *, const chr *, const chr *, pchr);
/* === regc_color.c === */
-static VOID initcm _ANSI_ARGS_((struct vars *, struct colormap *));
-static VOID freecm _ANSI_ARGS_((struct colormap *));
-static VOID cmtreefree _ANSI_ARGS_((struct colormap *, union tree *, int));
-static color setcolor _ANSI_ARGS_((struct colormap *, pchr, pcolor));
-static color maxcolor _ANSI_ARGS_((struct colormap *));
-static color newcolor _ANSI_ARGS_((struct colormap *));
-static VOID freecolor _ANSI_ARGS_((struct colormap *, pcolor));
-static color pseudocolor _ANSI_ARGS_((struct colormap *));
-static color subcolor _ANSI_ARGS_((struct colormap *, pchr c));
-static color newsub _ANSI_ARGS_((struct colormap *, pcolor));
-static VOID subrange _ANSI_ARGS_((struct vars *, pchr, pchr, struct state *, struct state *));
-static VOID subblock _ANSI_ARGS_((struct vars *, pchr, struct state *, struct state *));
-static VOID okcolors _ANSI_ARGS_((struct nfa *, struct colormap *));
-static VOID colorchain _ANSI_ARGS_((struct colormap *, struct arc *));
-static VOID uncolorchain _ANSI_ARGS_((struct colormap *, struct arc *));
-static int singleton _ANSI_ARGS_((struct colormap *, pchr c));
-static VOID rainbow _ANSI_ARGS_((struct nfa *, struct colormap *, int, pcolor, struct state *, struct state *));
-static VOID colorcomplement _ANSI_ARGS_((struct nfa *, struct colormap *, int, struct state *, struct state *, struct state *));
+static void initcm(struct vars *, struct colormap *);
+static void freecm(struct colormap *);
+static void cmtreefree(struct colormap *, union tree *, int);
+static color setcolor(struct colormap *, pchr, pcolor);
+static color maxcolor(struct colormap *);
+static color newcolor(struct colormap *);
+static void freecolor(struct colormap *, pcolor);
+static color pseudocolor(struct colormap *);
+static color subcolor(struct colormap *, pchr c);
+static color newsub(struct colormap *, pcolor);
+static void subrange(struct vars *, pchr, pchr, struct state *, struct state *);
+static void subblock(struct vars *, pchr, struct state *, struct state *);
+static void okcolors(struct nfa *, struct colormap *);
+static void colorchain(struct colormap *, struct arc *);
+static void uncolorchain(struct colormap *, struct arc *);
+static void rainbow(struct nfa *, struct colormap *, int, pcolor, struct state *, struct state *);
+static void colorcomplement(struct nfa *, struct colormap *, int, struct state *, struct state *, struct state *);
#ifdef REG_DEBUG
-static VOID dumpcolors _ANSI_ARGS_((struct colormap *, FILE *));
-static VOID fillcheck _ANSI_ARGS_((struct colormap *, union tree *, int, FILE *));
-static VOID dumpchr _ANSI_ARGS_((pchr, FILE *));
+static void dumpcolors(struct colormap *, FILE *);
+static void fillcheck(struct colormap *, union tree *, int, FILE *);
+static void dumpchr(pchr, FILE *);
#endif
/* === regc_nfa.c === */
-static struct nfa *newnfa _ANSI_ARGS_((struct vars *, struct colormap *, struct nfa *));
-static VOID freenfa _ANSI_ARGS_((struct nfa *));
-static struct state *newstate _ANSI_ARGS_((struct nfa *));
-static struct state *newfstate _ANSI_ARGS_((struct nfa *, int flag));
-static VOID dropstate _ANSI_ARGS_((struct nfa *, struct state *));
-static VOID freestate _ANSI_ARGS_((struct nfa *, struct state *));
-static VOID destroystate _ANSI_ARGS_((struct nfa *, struct state *));
-static VOID newarc _ANSI_ARGS_((struct nfa *, int, pcolor, struct state *, struct state *));
-static struct arc *allocarc _ANSI_ARGS_((struct nfa *, struct state *));
-static VOID freearc _ANSI_ARGS_((struct nfa *, struct arc *));
-static struct arc *findarc _ANSI_ARGS_((struct state *, int, pcolor));
-static VOID cparc _ANSI_ARGS_((struct nfa *, struct arc *, struct state *, struct state *));
-static VOID moveins _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
-static VOID copyins _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
-static VOID moveouts _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
-static VOID copyouts _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
-static VOID cloneouts _ANSI_ARGS_((struct nfa *, struct state *, struct state *, struct state *, int));
-static VOID delsub _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
-static VOID deltraverse _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
-static VOID dupnfa _ANSI_ARGS_((struct nfa *, struct state *, struct state *, struct state *, struct state *));
-static VOID duptraverse _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
-static VOID cleartraverse _ANSI_ARGS_((struct nfa *, struct state *));
-static VOID specialcolors _ANSI_ARGS_((struct nfa *));
-static long optimize _ANSI_ARGS_((struct nfa *, FILE *));
-static VOID pullback _ANSI_ARGS_((struct nfa *, FILE *));
-static int pull _ANSI_ARGS_((struct nfa *, struct arc *));
-static VOID pushfwd _ANSI_ARGS_((struct nfa *, FILE *));
-static int push _ANSI_ARGS_((struct nfa *, struct arc *));
+static struct nfa *newnfa(struct vars *, struct colormap *, struct nfa *);
+static void freenfa(struct nfa *);
+static struct state *newstate(struct nfa *);
+static struct state *newfstate(struct nfa *, int flag);
+static void dropstate(struct nfa *, struct state *);
+static void freestate(struct nfa *, struct state *);
+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 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 moveouts(struct nfa *, struct state *, struct state *);
+static void copyouts(struct nfa *, struct state *, struct state *);
+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 *);
+static void dupnfa(struct nfa *, struct state *, struct state *, struct state *, struct state *);
+static void duptraverse(struct nfa *, struct state *, struct state *);
+static void cleartraverse(struct nfa *, struct state *);
+static void specialcolors(struct nfa *);
+static long optimize(struct nfa *, FILE *);
+static void pullback(struct nfa *, FILE *);
+static int pull(struct nfa *, struct arc *);
+static void pushfwd(struct nfa *, FILE *);
+static int push(struct nfa *, struct arc *);
#define INCOMPATIBLE 1 /* destroys arc */
#define SATISFIED 2 /* constraint satisfied */
#define COMPATIBLE 3 /* compatible but not satisfied yet */
-static int combine _ANSI_ARGS_((struct arc *, struct arc *));
-static VOID fixempties _ANSI_ARGS_((struct nfa *, FILE *));
-static int unempty _ANSI_ARGS_((struct nfa *, struct arc *));
-static VOID cleanup _ANSI_ARGS_((struct nfa *));
-static VOID markreachable _ANSI_ARGS_((struct nfa *, struct state *, struct state *, struct state *));
-static VOID markcanreach _ANSI_ARGS_((struct nfa *, struct state *, struct state *, struct state *));
-static long analyze _ANSI_ARGS_((struct nfa *));
-static VOID compact _ANSI_ARGS_((struct nfa *, struct cnfa *));
-static VOID carcsort _ANSI_ARGS_((struct carc *, struct carc *));
-static VOID freecnfa _ANSI_ARGS_((struct cnfa *));
-static VOID dumpnfa _ANSI_ARGS_((struct nfa *, FILE *));
+static int combine(struct arc *, struct arc *);
+static void fixempties(struct nfa *, FILE *);
+static int unempty(struct nfa *, struct arc *);
+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 *);
+static long analyze(struct nfa *);
+static void compact(struct nfa *, struct cnfa *);
+static void carcsort(struct carc *, struct carc *);
+static void freecnfa(struct cnfa *);
+static void dumpnfa(struct nfa *, FILE *);
#ifdef REG_DEBUG
-static VOID dumpstate _ANSI_ARGS_((struct state *, FILE *));
-static VOID dumparcs _ANSI_ARGS_((struct state *, FILE *));
-static int dumprarcs _ANSI_ARGS_((struct arc *, struct state *, FILE *, int));
-static VOID dumparc _ANSI_ARGS_((struct arc *, struct state *, FILE *));
+static void dumpstate(struct state *, FILE *);
+static void dumparcs(struct state *, FILE *);
+static int dumprarcs(struct arc *, struct state *, FILE *, int);
+static void dumparc(struct arc *, struct state *, FILE *);
#endif
-static VOID dumpcnfa _ANSI_ARGS_((struct cnfa *, FILE *));
+static void dumpcnfa(struct cnfa *, FILE *);
#ifdef REG_DEBUG
-static VOID dumpcstate _ANSI_ARGS_((int, struct carc *, struct cnfa *, FILE *));
+static void dumpcstate(int, struct carc *, struct cnfa *, FILE *);
#endif
/* === regc_cvec.c === */
-static struct cvec *newcvec _ANSI_ARGS_((int, int, int));
-static struct cvec *clearcvec _ANSI_ARGS_((struct cvec *));
-static VOID addchr _ANSI_ARGS_((struct cvec *, pchr));
-static VOID addrange _ANSI_ARGS_((struct cvec *, pchr, pchr));
-static int haschr _ANSI_ARGS_((struct cvec *, pchr));
-static struct cvec *getcvec _ANSI_ARGS_((struct vars *, int, int));
-static VOID freecvec _ANSI_ARGS_((struct cvec *));
+static struct cvec *clearcvec(struct cvec *);
+static void addchr(struct cvec *, pchr);
+static void addrange(struct cvec *, pchr, pchr);
+static struct cvec *newcvec(int, int);
+static struct cvec *getcvec(struct vars *, int, int);
+static void freecvec(struct cvec *);
/* === regc_locale.c === */
-static celt element _ANSI_ARGS_((struct vars *, CONST chr *, CONST chr *));
-static struct cvec *range _ANSI_ARGS_((struct vars *, celt, celt, int));
-static int before _ANSI_ARGS_((celt, celt));
-static struct cvec *eclass _ANSI_ARGS_((struct vars *, celt, int));
-static struct cvec *cclass _ANSI_ARGS_((struct vars *, CONST chr *, CONST chr *, int));
-static struct cvec *allcases _ANSI_ARGS_((struct vars *, pchr));
-static int cmp _ANSI_ARGS_((CONST chr *, CONST chr *, size_t));
-static int casecmp _ANSI_ARGS_((CONST chr *, CONST chr *, size_t));
+static celt element(struct vars *, const chr *, const chr *);
+static struct cvec *range(struct vars *, celt, celt, int);
+static int before(celt, celt);
+static struct cvec *eclass(struct vars *, celt, int);
+static struct cvec *cclass(struct vars *, const chr *, const chr *, int);
+static struct cvec *allcases(struct vars *, pchr);
+static int cmp(const chr *, const chr *, size_t);
+static int casecmp(const chr *, const chr *, size_t);
/* automatically gathered by fwd; do not hand-edit */
/* =====^!^===== end forwards =====^!^===== */
-
-
-
+
/* internal variables, bundled for easy passing around */
struct vars {
- regex_t *re;
- chr *now; /* scan pointer into string */
- chr *stop; /* end of string */
- chr *savenow; /* saved now and stop for "subroutine call" */
- chr *savestop;
- int err; /* error code (0 if none) */
- int cflags; /* copy of compile flags */
- int lasttype; /* type of previous token */
- int nexttype; /* type of next token */
- chr nextvalue; /* value (if any) of next token */
- int lexcon; /* lexical context type (see lex.c) */
- int nsubexp; /* subexpression count */
- struct subre **subs; /* subRE pointer vector */
- size_t nsubs; /* length of vector */
- struct subre *sub10[10]; /* initial vector, enough for most */
- struct nfa *nfa; /* the NFA */
- struct colormap *cm; /* character color map */
- color nlcolor; /* color of newline */
- struct state *wordchrs; /* state in nfa holding word-char outarcs */
- struct subre *tree; /* subexpression tree */
- struct subre *treechain; /* all tree nodes allocated */
- struct subre *treefree; /* any free tree nodes */
- int ntree; /* number of tree nodes */
- struct cvec *cv; /* interface cvec */
- struct cvec *cv2; /* utility cvec */
- struct cvec *mcces; /* collating-element information */
-# define ISCELEADER(v,c) (v->mcces != NULL && haschr(v->mcces, (c)))
- struct state *mccepbegin; /* in nfa, start of MCCE prototypes */
- struct state *mccepend; /* in nfa, end of MCCE prototypes */
- struct subre *lacons; /* lookahead-constraint vector */
- int nlacons; /* size of lacons */
+ regex_t *re;
+ const chr *now; /* scan pointer into string */
+ const chr *stop; /* end of string */
+ const chr *savenow; /* saved now and stop for "subroutine call" */
+ const chr *savestop;
+ int err; /* error code (0 if none) */
+ int cflags; /* copy of compile flags */
+ int lasttype; /* type of previous token */
+ int nexttype; /* type of next token */
+ chr nextvalue; /* value (if any) of next token */
+ int lexcon; /* lexical context type (see lex.c) */
+ int nsubexp; /* subexpression count */
+ struct subre **subs; /* subRE pointer vector */
+ size_t nsubs; /* length of vector */
+ struct subre *sub10[10]; /* initial vector, enough for most */
+ struct nfa *nfa; /* the NFA */
+ struct colormap *cm; /* character color map */
+ color nlcolor; /* color of newline */
+ struct state *wordchrs; /* state in nfa holding word-char outarcs */
+ struct subre *tree; /* subexpression tree */
+ struct subre *treechain; /* all tree nodes allocated */
+ struct subre *treefree; /* any free tree nodes */
+ int ntree; /* number of tree nodes */
+ struct cvec *cv; /* interface cvec */
+ struct cvec *cv2; /* utility cvec */
+ struct subre *lacons; /* lookahead-constraint vector */
+ int nlacons; /* size of lacons */
};
/* parsing macros; most know that `v' is the struct vars pointer */
#define NEXT() (next(v)) /* advance by one token */
#define SEE(t) (v->nexttype == (t)) /* is next token this? */
#define EAT(t) (SEE(t) && next(v)) /* if next is this, swallow it */
-#define VISERR(vv) ((vv)->err != 0) /* have we seen an error yet? */
+#define VISERR(vv) ((vv)->err != 0)/* have we seen an error yet? */
#define ISERR() VISERR(v)
-#define VERR(vv,e) ((vv)->nexttype = EOS, ((vv)->err) ? (vv)->err :\
- ((vv)->err = (e)))
+#define VERR(vv,e) \
+ ((vv)->nexttype = EOS, ((vv)->err) ? (vv)->err : ((vv)->err = (e)))
#define ERR(e) VERR(v, e) /* record an error */
#define NOERR() {if (ISERR()) return;} /* if error seen, return */
#define NOERRN() {if (ISERR()) return NULL;} /* NOERR with retval */
@@ -259,387 +250,459 @@ struct vars {
#define PREFER 'P' /* length preference */
/* is an arc colored, and hence on a color chain? */
-#define COLORED(a) ((a)->type == PLAIN || (a)->type == AHEAD || \
- (a)->type == BEHIND)
-
-
+#define COLORED(a) \
+ ((a)->type == PLAIN || (a)->type == AHEAD || (a)->type == BEHIND)
/* static function list */
static struct fns functions = {
- rfree, /* regfree insides */
+ rfree, /* regfree insides */
};
-
-
-
+
/*
- compile - compile regular expression
- ^ int compile(regex_t *, CONST chr *, size_t, int);
+ ^ int compile(regex_t *, const chr *, size_t, int);
*/
int
-compile(re, string, len, flags)
-regex_t *re;
-CONST chr *string;
-size_t len;
-int flags;
+compile(
+ regex_t *re,
+ const chr *string,
+ size_t len,
+ int flags)
{
- struct vars var;
- struct vars *v = &var;
- struct guts *g;
- int i;
- size_t j;
- FILE *debug = (flags&REG_PROGRESS) ? stdout : (FILE *)NULL;
-# define CNOERR() { if (ISERR()) return freev(v, v->err); }
-
- /* sanity checks */
-
- if (re == NULL || string == NULL)
- return REG_INVARG;
- if ((flags&REG_QUOTE) &&
- (flags&(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE)))
- return REG_INVARG;
- if (!(flags&REG_EXTENDED) && (flags&REG_ADVF))
- return REG_INVARG;
-
- /* initial setup (after which freev() is callable) */
- v->re = re;
- v->now = (chr *)string;
- v->stop = v->now + len;
- v->savenow = v->savestop = NULL;
- v->err = 0;
- v->cflags = flags;
- v->nsubexp = 0;
- v->subs = v->sub10;
- v->nsubs = 10;
- for (j = 0; j < v->nsubs; j++)
- v->subs[j] = NULL;
- v->nfa = NULL;
- v->cm = NULL;
- v->nlcolor = COLORLESS;
- v->wordchrs = NULL;
- v->tree = NULL;
- v->treechain = NULL;
- v->treefree = NULL;
- v->cv = NULL;
- v->cv2 = NULL;
- v->mcces = NULL;
- v->lacons = NULL;
- v->nlacons = 0;
- re->re_magic = REMAGIC;
- re->re_info = 0; /* bits get set during parse */
- re->re_csize = sizeof(chr);
- re->re_guts = NULL;
- re->re_fns = VS(&functions);
-
- /* more complex setup, malloced things */
- re->re_guts = VS(MALLOC(sizeof(struct guts)));
- if (re->re_guts == NULL)
- return freev(v, REG_ESPACE);
- g = (struct guts *)re->re_guts;
- g->tree = NULL;
- initcm(v, &g->cmap);
- v->cm = &g->cmap;
- g->lacons = NULL;
- g->nlacons = 0;
- ZAPCNFA(g->search);
- v->nfa = newnfa(v, v->cm, (struct nfa *)NULL);
- CNOERR();
- v->cv = newcvec(100, 20, 10);
- if (v->cv == NULL)
- return freev(v, REG_ESPACE);
- CNOERR();
-
- /* parsing */
- lexstart(v); /* also handles prefixes */
- if ((v->cflags&REG_NLSTOP) || (v->cflags&REG_NLANCH)) {
- /* assign newline a unique color */
- v->nlcolor = subcolor(v->cm, newline());
- okcolors(v->nfa, v->cm);
- }
- CNOERR();
- v->tree = parse(v, EOS, PLAIN, v->nfa->init, v->nfa->final);
- assert(SEE(EOS)); /* even if error; ISERR() => SEE(EOS) */
- CNOERR();
- assert(v->tree != NULL);
-
- /* finish setup of nfa and its subre tree */
- specialcolors(v->nfa);
- CNOERR();
- if (debug != NULL) {
- fprintf(debug, "\n\n\n========= RAW ==========\n");
- dumpnfa(v->nfa, debug);
- dumpst(v->tree, debug, 1);
- }
- optst(v, v->tree);
- v->ntree = numst(v->tree, 1);
- markst(v->tree);
- cleanst(v);
+ AllocVars(v);
+ struct guts *g;
+ int i;
+ size_t j;
+ FILE *debug = (flags&REG_PROGRESS) ? stdout : NULL;
+#define CNOERR() { if (ISERR()) return freev(v, v->err); }
+
+ /*
+ * Sanity checks.
+ */
+
+ if (re == NULL || string == NULL) {
+ FreeVars(v);
+ return REG_INVARG;
+ }
+ if ((flags&REG_QUOTE) && (flags&(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE))) {
+ FreeVars(v);
+ return REG_INVARG;
+ }
+ if (!(flags&REG_EXTENDED) && (flags&REG_ADVF)) {
+ FreeVars(v);
+ return REG_INVARG;
+ }
+
+ /*
+ * Initial setup (after which freev() is callable).
+ */
+
+ v->re = re;
+ v->now = string;
+ v->stop = v->now + len;
+ v->savenow = v->savestop = NULL;
+ v->err = 0;
+ v->cflags = flags;
+ v->nsubexp = 0;
+ v->subs = v->sub10;
+ v->nsubs = 10;
+ for (j = 0; j < v->nsubs; j++) {
+ v->subs[j] = NULL;
+ }
+ v->nfa = NULL;
+ v->cm = NULL;
+ v->nlcolor = COLORLESS;
+ v->wordchrs = NULL;
+ v->tree = NULL;
+ v->treechain = NULL;
+ v->treefree = NULL;
+ v->cv = NULL;
+ v->cv2 = NULL;
+ v->lacons = NULL;
+ v->nlacons = 0;
+ re->re_magic = REMAGIC;
+ re->re_info = 0; /* bits get set during parse */
+ re->re_csize = sizeof(chr);
+ re->re_guts = NULL;
+ re->re_fns = VS(&functions);
+
+ /*
+ * More complex setup, malloced things.
+ */
+
+ re->re_guts = VS(MALLOC(sizeof(struct guts)));
+ if (re->re_guts == NULL) {
+ return freev(v, REG_ESPACE);
+ }
+ g = (struct guts *) re->re_guts;
+ g->tree = NULL;
+ initcm(v, &g->cmap);
+ v->cm = &g->cmap;
+ g->lacons = NULL;
+ g->nlacons = 0;
+ ZAPCNFA(g->search);
+ v->nfa = newnfa(v, v->cm, NULL);
+ CNOERR();
+ v->cv = newcvec(100, 20);
+ if (v->cv == NULL) {
+ return freev(v, REG_ESPACE);
+ }
+
+ /*
+ * Parsing.
+ */
+
+ lexstart(v); /* also handles prefixes */
+ if ((v->cflags&REG_NLSTOP) || (v->cflags&REG_NLANCH)) {
+ /*
+ * Assign newline a unique color.
+ */
+
+ v->nlcolor = subcolor(v->cm, newline());
+ okcolors(v->nfa, v->cm);
+ }
+ CNOERR();
+ v->tree = parse(v, EOS, PLAIN, v->nfa->init, v->nfa->final);
+ assert(SEE(EOS)); /* even if error; ISERR() => SEE(EOS) */
+ CNOERR();
+ assert(v->tree != NULL);
+
+ /*
+ * Finish setup of nfa and its subre tree.
+ */
+
+ specialcolors(v->nfa);
+ CNOERR();
+ if (debug != NULL) {
+ fprintf(debug, "\n\n\n========= RAW ==========\n");
+ dumpnfa(v->nfa, debug);
+ dumpst(v->tree, debug, 1);
+ }
+ optst(v, v->tree);
+ v->ntree = numst(v->tree, 1);
+ markst(v->tree);
+ cleanst(v);
+ if (debug != NULL) {
+ fprintf(debug, "\n\n\n========= TREE FIXED ==========\n");
+ dumpst(v->tree, debug, 1);
+ }
+
+ /*
+ * Build compacted NFAs for tree and lacons.
+ */
+
+ re->re_info |= nfatree(v, v->tree, debug);
+ CNOERR();
+ assert(v->nlacons == 0 || v->lacons != NULL);
+ for (i = 1; i < v->nlacons; i++) {
if (debug != NULL) {
- fprintf(debug, "\n\n\n========= TREE FIXED ==========\n");
- dumpst(v->tree, debug, 1);
+ fprintf(debug, "\n\n\n========= LA%d ==========\n", i);
}
+ nfanode(v, &v->lacons[i], debug);
+ }
+ CNOERR();
+ if (v->tree->flags&SHORTER) {
+ NOTE(REG_USHORTEST);
+ }
- /* build compacted NFAs for tree and lacons */
- re->re_info |= nfatree(v, v->tree, debug);
- CNOERR();
- assert(v->nlacons == 0 || v->lacons != NULL);
- for (i = 1; i < v->nlacons; i++) {
- if (debug != NULL)
- fprintf(debug, "\n\n\n========= LA%d ==========\n", i);
- nfanode(v, &v->lacons[i], debug);
- }
- CNOERR();
- if (v->tree->flags&SHORTER)
- NOTE(REG_USHORTEST);
-
- /* build compacted NFAs for tree, lacons, fast search */
- if (debug != NULL)
- fprintf(debug, "\n\n\n========= SEARCH ==========\n");
- /* can sacrifice main NFA now, so use it as work area */
- (DISCARD)optimize(v->nfa, debug);
- CNOERR();
- makesearch(v, v->nfa);
- CNOERR();
- compact(v->nfa, &g->search);
- CNOERR();
-
- /* looks okay, package it up */
- re->re_nsub = v->nsubexp;
- v->re = NULL; /* freev no longer frees re */
- g->magic = GUTSMAGIC;
- g->cflags = v->cflags;
- g->info = re->re_info;
- g->nsub = re->re_nsub;
- g->tree = v->tree;
- v->tree = NULL;
- g->ntree = v->ntree;
- g->compare = (v->cflags&REG_ICASE) ? casecmp : cmp;
- g->lacons = v->lacons;
- v->lacons = NULL;
- g->nlacons = v->nlacons;
-
- if (flags&REG_DUMP)
- dump(re, stdout);
-
- assert(v->err == 0);
- return freev(v, 0);
-}
+ /*
+ * Build compacted NFAs for tree, lacons, fast search.
+ */
+ if (debug != NULL) {
+ fprintf(debug, "\n\n\n========= SEARCH ==========\n");
+ }
+
+ /*
+ * Can sacrifice main NFA now, so use it as work area.
+ */
+
+ (DISCARD) optimize(v->nfa, debug);
+ CNOERR();
+ makesearch(v, v->nfa);
+ CNOERR();
+ compact(v->nfa, &g->search);
+ CNOERR();
+
+ /*
+ * Looks okay, package it up.
+ */
+
+ re->re_nsub = v->nsubexp;
+ v->re = NULL; /* freev no longer frees re */
+ g->magic = GUTSMAGIC;
+ g->cflags = v->cflags;
+ g->info = re->re_info;
+ g->nsub = re->re_nsub;
+ g->tree = v->tree;
+ v->tree = NULL;
+ g->ntree = v->ntree;
+ g->compare = (v->cflags&REG_ICASE) ? casecmp : cmp;
+ g->lacons = v->lacons;
+ v->lacons = NULL;
+ g->nlacons = v->nlacons;
+
+ if (flags&REG_DUMP) {
+ dump(re, stdout);
+ }
+
+ assert(v->err == 0);
+ return freev(v, 0);
+}
+
/*
- moresubs - enlarge subRE vector
- ^ static VOID moresubs(struct vars *, int);
+ ^ static void moresubs(struct vars *, int);
*/
-static VOID
-moresubs(v, wanted)
-struct vars *v;
-int wanted; /* want enough room for this one */
+static void
+moresubs(
+ struct vars *v,
+ int wanted) /* want enough room for this one */
{
- struct subre **p;
- size_t n;
-
- assert(wanted > 0 && (size_t)wanted >= v->nsubs);
- n = (size_t)wanted * 3 / 2 + 1;
- if (v->subs == v->sub10) {
- p = (struct subre **)MALLOC(n * sizeof(struct subre *));
- if (p != NULL)
- memcpy(VS(p), VS(v->subs),
- v->nsubs * sizeof(struct subre *));
- } else
- p = (struct subre **)REALLOC(v->subs, n*sizeof(struct subre *));
- if (p == NULL) {
- ERR(REG_ESPACE);
- return;
+ struct subre **p;
+ size_t n;
+
+ assert(wanted > 0 && (size_t)wanted >= v->nsubs);
+ n = (size_t)wanted * 3 / 2 + 1;
+ if (v->subs == v->sub10) {
+ p = (struct subre **) MALLOC(n * sizeof(struct subre *));
+ if (p != NULL) {
+ memcpy(p, v->subs, v->nsubs * sizeof(struct subre *));
}
- v->subs = p;
- for (p = &v->subs[v->nsubs]; v->nsubs < n; p++, v->nsubs++)
- *p = NULL;
- assert(v->nsubs == n);
- assert((size_t)wanted < v->nsubs);
+ } else {
+ p = (struct subre **) REALLOC(v->subs, n*sizeof(struct subre *));
+ }
+ if (p == NULL) {
+ ERR(REG_ESPACE);
+ return;
+ }
+
+ v->subs = p;
+ for (p = &v->subs[v->nsubs]; v->nsubs < n; p++, v->nsubs++) {
+ *p = NULL;
+ }
+ assert(v->nsubs == n);
+ assert((size_t)wanted < v->nsubs);
}
-
+
/*
- freev - free vars struct's substructures where necessary
- * Optionally does error-number setting, and always returns error code
- * (if any), to make error-handling code terser.
+ * Optionally does error-number setting, and always returns error code (if
+ * any), to make error-handling code terser.
^ static int freev(struct vars *, int);
*/
static int
-freev(v, err)
-struct vars *v;
-int err;
+freev(
+ struct vars *v,
+ int err)
{
- if (v->re != NULL)
- rfree(v->re);
- if (v->subs != v->sub10)
- FREE(v->subs);
- if (v->nfa != NULL)
- freenfa(v->nfa);
- if (v->tree != NULL)
- freesubre(v, v->tree);
- if (v->treechain != NULL)
- cleanst(v);
- if (v->cv != NULL)
- freecvec(v->cv);
- if (v->cv2 != NULL)
- freecvec(v->cv2);
- if (v->mcces != NULL)
- freecvec(v->mcces);
- if (v->lacons != NULL)
- freelacons(v->lacons, v->nlacons);
- ERR(err); /* nop if err==0 */
-
- return v->err;
+ register int ret;
+
+ if (v->re != NULL) {
+ rfree(v->re);
+ }
+ if (v->subs != v->sub10) {
+ FREE(v->subs);
+ }
+ if (v->nfa != NULL) {
+ freenfa(v->nfa);
+ }
+ if (v->tree != NULL) {
+ freesubre(v, v->tree);
+ }
+ if (v->treechain != NULL) {
+ cleanst(v);
+ }
+ if (v->cv != NULL) {
+ freecvec(v->cv);
+ }
+ if (v->cv2 != NULL) {
+ freecvec(v->cv2);
+ }
+ if (v->lacons != NULL) {
+ freelacons(v->lacons, v->nlacons);
+ }
+ ERR(err); /* nop if err==0 */
+
+ ret = v->err;
+ FreeVars(v);
+ return ret;
}
-
+
/*
- makesearch - turn an NFA into a search NFA (implicit prepend of .*?)
* NFA must have been optimize()d already.
- ^ static VOID makesearch(struct vars *, struct nfa *);
+ ^ static void makesearch(struct vars *, struct nfa *);
*/
-static VOID
-makesearch(v, nfa)
-struct vars *v;
-struct nfa *nfa;
+static void
+makesearch(
+ struct vars *v,
+ struct nfa *nfa)
{
- struct arc *a;
- struct arc *b;
- struct state *pre = nfa->pre;
- struct state *s;
- struct state *s2;
- struct state *slist;
-
- /* no loops are needed if it's anchored */
- for (a = pre->outs; a != NULL; a = a->outchain) {
- assert(a->type == PLAIN);
- if (a->co != nfa->bos[0] && a->co != nfa->bos[1])
- break;
- }
- if (a != NULL) {
- /* add implicit .* in front */
- rainbow(nfa, v->cm, PLAIN, COLORLESS, pre, pre);
+ struct arc *a, *b;
+ struct state *pre = nfa->pre;
+ struct state *s, *s2, *slist;
- /* and ^* and \A* too -- not always necessary, but harmless */
- newarc(nfa, PLAIN, nfa->bos[0], pre, pre);
- newarc(nfa, PLAIN, nfa->bos[1], pre, pre);
+ /*
+ * No loops are needed if it's anchored.
+ */
+
+ for (a = pre->outs; a != NULL; a = a->outchain) {
+ assert(a->type == PLAIN);
+ if (a->co != nfa->bos[0] && a->co != nfa->bos[1]) {
+ break;
}
+ }
+ if (a != NULL) {
+ /*
+ * Add implicit .* in front.
+ */
+
+ rainbow(nfa, v->cm, PLAIN, COLORLESS, pre, pre);
/*
- * Now here's the subtle part. Because many REs have no lookback
- * constraints, often knowing when you were in the pre state tells
- * you little; it's the next state(s) that are informative. But
- * some of them may have other inarcs, i.e. it may be possible to
- * make actual progress and then return to one of them. We must
- * de-optimize such cases, splitting each such state into progress
- * and no-progress states.
+ * And ^* and \A* too -- not always necessary, but harmless.
*/
- /* first, make a list of the states */
- slist = NULL;
- for (a = pre->outs; a != NULL; a = a->outchain) {
- s = a->to;
- for (b = s->ins; b != NULL; b = b->inchain)
- if (b->from != pre)
- break;
- if (b != NULL) { /* must be split */
- if (s->tmp == NULL) { /* if not already in the list */
- /* (fixes bugs 505048, 230589, */
- /* 840258, 504785) */
- s->tmp = slist;
- slist = s;
- }
- }
+ newarc(nfa, PLAIN, nfa->bos[0], pre, pre);
+ newarc(nfa, PLAIN, nfa->bos[1], pre, pre);
+ }
+
+ /*
+ * Now here's the subtle part. Because many REs have no lookback
+ * constraints, often knowing when you were in the pre state tells you
+ * little; it's the next state(s) that are informative. But some of them
+ * may have other inarcs, i.e. it may be possible to make actual progress
+ * and then return to one of them. We must de-optimize such cases,
+ * splitting each such state into progress and no-progress states.
+ */
+
+ /*
+ * First, make a list of the states.
+ */
+
+ slist = NULL;
+ for (a=pre->outs ; a!=NULL ; a=a->outchain) {
+ s = a->to;
+ for (b=s->ins ; b!=NULL ; b=b->inchain) {
+ if (b->from != pre) {
+ break;
+ }
+ }
+ if (b != NULL && s->tmp == NULL) {
+ /*
+ * Must be split if not already in the list (fixes bugs 505048,
+ * 230589, 840258, 504785).
+ */
+
+ s->tmp = slist;
+ slist = s;
}
+ }
- /* do the splits */
- for (s = slist; s != NULL; s = s2) {
- s2 = newstate(nfa);
- copyouts(nfa, s, s2);
- for (a = s->ins; a != NULL; a = b) {
- b = a->inchain;
- if (a->from != pre) {
- cparc(nfa, a, a->from, s2);
- freearc(nfa, a);
- }
- }
- s2 = s->tmp;
- s->tmp = NULL; /* clean up while we're at it */
+ /*
+ * Do the splits.
+ */
+
+ for (s=slist ; s!=NULL ; s=s2) {
+ s2 = newstate(nfa);
+
+ copyouts(nfa, s, s2);
+ for (a=s->ins ; a!=NULL ; a=b) {
+ b = a->inchain;
+
+ if (a->from != pre) {
+ cparc(nfa, a, a->from, s2);
+ freearc(nfa, a);
+ }
}
+ s2 = s->tmp;
+ s->tmp = NULL; /* clean up while we're at it */
+ }
}
-
+
/*
- parse - parse an RE
- * This is actually just the top level, which parses a bunch of branches
- * tied together with '|'. They appear in the tree as the left children
- * of a chain of '|' subres.
+ * This is actually just the top level, which parses a bunch of branches tied
+ * together with '|'. They appear in the tree as the left children of a chain
+ * of '|' subres.
^ static struct subre *parse(struct vars *, int, int, struct state *,
^ struct state *);
*/
static struct subre *
-parse(v, stopper, type, init, final)
-struct vars *v;
-int stopper; /* EOS or ')' */
-int type; /* LACON (lookahead subRE) or PLAIN */
-struct state *init; /* initial state */
-struct state *final; /* final state */
+parse(
+ struct vars *v,
+ int stopper, /* EOS or ')' */
+ int type, /* LACON (lookahead subRE) or PLAIN */
+ struct state *init, /* initial state */
+ struct state *final) /* final state */
{
- struct state *left; /* scaffolding for branch */
- struct state *right;
- struct subre *branches; /* top level */
- struct subre *branch; /* current branch */
- struct subre *t; /* temporary */
- int firstbranch; /* is this the first branch? */
-
- assert(stopper == ')' || stopper == EOS);
-
- branches = subre(v, '|', LONGER, init, final);
+ struct state *left, *right; /* scaffolding for branch */
+ struct subre *branches; /* top level */
+ struct subre *branch; /* current branch */
+ struct subre *t; /* temporary */
+ int firstbranch; /* is this the first branch? */
+
+ assert(stopper == ')' || stopper == EOS);
+
+ branches = subre(v, '|', LONGER, init, final);
+ NOERRN();
+ branch = branches;
+ firstbranch = 1;
+ do { /* a branch */
+ if (!firstbranch) {
+ /*
+ * Need a place to hang the branch.
+ */
+
+ branch->right = subre(v, '|', LONGER, init, final);
+ NOERRN();
+ branch = branch->right;
+ }
+ firstbranch = 0;
+ left = newstate(v->nfa);
+ right = newstate(v->nfa);
NOERRN();
- branch = branches;
- firstbranch = 1;
- do { /* a branch */
- if (!firstbranch) {
- /* need a place to hang it */
- branch->right = subre(v, '|', LONGER, init, final);
- NOERRN();
- branch = branch->right;
- }
- firstbranch = 0;
- left = newstate(v->nfa);
- right = newstate(v->nfa);
- NOERRN();
- EMPTYARC(init, left);
- EMPTYARC(right, final);
- NOERRN();
- branch->left = parsebranch(v, stopper, type, left, right, 0);
- NOERRN();
- branch->flags |= UP(branch->flags | branch->left->flags);
- if ((branch->flags &~ branches->flags) != 0) /* new flags */
- for (t = branches; t != branch; t = t->right)
- t->flags |= branch->flags;
- } while (EAT('|'));
- assert(SEE(stopper) || SEE(EOS));
-
- if (!SEE(stopper)) {
- assert(stopper == ')' && SEE(EOS));
- ERR(REG_EPAREN);
+ EMPTYARC(init, left);
+ EMPTYARC(right, final);
+ NOERRN();
+ branch->left = parsebranch(v, stopper, type, left, right, 0);
+ NOERRN();
+ branch->flags |= UP(branch->flags | branch->left->flags);
+ if ((branch->flags &~ branches->flags) != 0) { /* new flags */
+ for (t = branches; t != branch; t = t->right) {
+ t->flags |= branch->flags;
+ }
}
+ } while (EAT('|'));
+ assert(SEE(stopper) || SEE(EOS));
- /* optimize out simple cases */
- if (branch == branches) { /* only one branch */
- assert(branch->right == NULL);
- t = branch->left;
- branch->left = NULL;
- freesubre(v, branches);
- branches = t;
- } else if (!MESSY(branches->flags)) { /* no interesting innards */
- freesubre(v, branches->left);
- branches->left = NULL;
- freesubre(v, branches->right);
- branches->right = NULL;
- branches->op = '=';
- }
+ if (!SEE(stopper)) {
+ assert(stopper == ')' && SEE(EOS));
+ ERR(REG_EPAREN);
+ }
- return branches;
-}
+ /*
+ * Optimize out simple cases.
+ */
+ if (branch == branches) { /* only one branch */
+ assert(branch->right == NULL);
+ t = branch->left;
+ branch->left = NULL;
+ freesubre(v, branches);
+ branches = t;
+ } else if (!MESSY(branches->flags)) { /* no interesting innards */
+ freesubre(v, branches->left);
+ branches->left = NULL;
+ freesubre(v, branches->right);
+ branches->right = NULL;
+ branches->op = '=';
+ }
+
+ return branches;
+}
+
/*
- parsebranch - parse one branch of an RE
* This mostly manages concatenation, working closely with parseqatom().
@@ -649,1458 +712,1446 @@ struct state *final; /* final state */
^ struct state *, int);
*/
static struct subre *
-parsebranch(v, stopper, type, left, right, partial)
-struct vars *v;
-int stopper; /* EOS or ')' */
-int type; /* LACON (lookahead subRE) or PLAIN */
-struct state *left; /* leftmost state */
-struct state *right; /* rightmost state */
-int partial; /* is this only part of a branch? */
+parsebranch(
+ struct vars *v,
+ int stopper, /* EOS or ')' */
+ int type, /* LACON (lookahead subRE) or PLAIN */
+ struct state *left, /* leftmost state */
+ struct state *right, /* rightmost state */
+ int partial) /* is this only part of a branch? */
{
- struct state *lp; /* left end of current construct */
- int seencontent; /* is there anything in this branch yet? */
- struct subre *t;
-
- lp = left;
- seencontent = 0;
- t = subre(v, '=', 0, left, right); /* op '=' is tentative */
- NOERRN();
- while (!SEE('|') && !SEE(stopper) && !SEE(EOS)) {
- if (seencontent) { /* implicit concat operator */
- lp = newstate(v->nfa);
- NOERRN();
- moveins(v->nfa, right, lp);
- }
- seencontent = 1;
-
- /* NB, recursion in parseqatom() may swallow rest of branch */
- parseqatom(v, stopper, type, lp, right, t);
+ struct state *lp; /* left end of current construct */
+ int seencontent; /* is there anything in this branch yet? */
+ struct subre *t;
+
+ lp = left;
+ seencontent = 0;
+ t = subre(v, '=', 0, left, right); /* op '=' is tentative */
+ NOERRN();
+ while (!SEE('|') && !SEE(stopper) && !SEE(EOS)) {
+ if (seencontent) { /* implicit concat operator */
+ lp = newstate(v->nfa);
+ NOERRN();
+ moveins(v->nfa, right, lp);
}
+ seencontent = 1;
- if (!seencontent) { /* empty branch */
- if (!partial)
- NOTE(REG_UUNSPEC);
- assert(lp == left);
- EMPTYARC(left, right);
+ /* NB, recursion in parseqatom() may swallow rest of branch */
+ parseqatom(v, stopper, type, lp, right, t);
+ }
+
+ if (!seencontent) { /* empty branch */
+ if (!partial) {
+ NOTE(REG_UUNSPEC);
}
+ assert(lp == left);
+ EMPTYARC(left, right);
+ }
- return t;
+ return t;
}
-
+
/*
- parseqatom - parse one quantified atom or constraint of an RE
- * The bookkeeping near the end cooperates very closely with parsebranch();
- * in particular, it contains a recursion that can involve parsing the rest
- * of the branch, making this function's name somewhat inaccurate.
- ^ static VOID parseqatom(struct vars *, int, int, struct state *,
+ * The bookkeeping near the end cooperates very closely with parsebranch(); in
+ * particular, it contains a recursion that can involve parsing the rest of
+ * the branch, making this function's name somewhat inaccurate.
+ ^ static void parseqatom(struct vars *, int, int, struct state *,
^ struct state *, struct subre *);
*/
-static VOID
-parseqatom(v, stopper, type, lp, rp, top)
-struct vars *v;
-int stopper; /* EOS or ')' */
-int type; /* LACON (lookahead subRE) or PLAIN */
-struct state *lp; /* left state to hang it on */
-struct state *rp; /* right state to hang it on */
-struct subre *top; /* subtree top */
+static void
+parseqatom(
+ struct vars *v,
+ int stopper, /* EOS or ')' */
+ int type, /* LACON (lookahead subRE) or PLAIN */
+ struct state *lp, /* left state to hang it on */
+ struct state *rp, /* right state to hang it on */
+ struct subre *top) /* subtree top */
{
- struct state *s; /* temporaries for new states */
- struct state *s2;
-# define ARCV(t, val) newarc(v->nfa, t, val, lp, rp)
- int m, n;
- struct subre *atom; /* atom's subtree */
- struct subre *t;
- int cap; /* capturing parens? */
- int pos; /* positive lookahead? */
- int subno; /* capturing-parens or backref number */
- int atomtype;
- int qprefer; /* quantifier short/long preference */
- int f;
- struct subre **atomp; /* where the pointer to atom is */
-
- /* initial bookkeeping */
- atom = NULL;
- assert(lp->nouts == 0); /* must string new code */
- assert(rp->nins == 0); /* between lp and rp */
- subno = 0; /* just to shut lint up */
-
- /* an atom or constraint... */
- atomtype = v->nexttype;
- switch (atomtype) {
+ struct state *s; /* temporaries for new states */
+ struct state *s2;
+#define ARCV(t, val) newarc(v->nfa, t, val, lp, rp)
+ int m, n;
+ struct subre *atom; /* atom's subtree */
+ struct subre *t;
+ int cap; /* capturing parens? */
+ int pos; /* positive lookahead? */
+ int subno; /* capturing-parens or backref number */
+ int atomtype;
+ int qprefer; /* quantifier short/long preference */
+ int f;
+ struct subre **atomp; /* where the pointer to atom is */
+
+ /*
+ * Initial bookkeeping.
+ */
+
+ atom = NULL;
+ assert(lp->nouts == 0); /* must string new code */
+ assert(rp->nins == 0); /* between lp and rp */
+ subno = 0; /* just to shut lint up */
+
+ /*
+ * An atom or constraint...
+ */
+
+ atomtype = v->nexttype;
+ switch (atomtype) {
/* first, constraints, which end by returning */
- case '^':
- ARCV('^', 1);
- if (v->cflags&REG_NLANCH)
- ARCV(BEHIND, v->nlcolor);
- NEXT();
- return;
- break;
- case '$':
- ARCV('$', 1);
- if (v->cflags&REG_NLANCH)
- ARCV(AHEAD, v->nlcolor);
- NEXT();
- return;
- break;
- case SBEGIN:
- ARCV('^', 1); /* BOL */
- ARCV('^', 0); /* or BOS */
- NEXT();
- return;
- break;
- case SEND:
- ARCV('$', 1); /* EOL */
- ARCV('$', 0); /* or EOS */
- NEXT();
- return;
- break;
- case '<':
- wordchrs(v); /* does NEXT() */
- s = newstate(v->nfa);
- NOERR();
- nonword(v, BEHIND, lp, s);
- word(v, AHEAD, s, rp);
- return;
- break;
- case '>':
- wordchrs(v); /* does NEXT() */
- s = newstate(v->nfa);
- NOERR();
- word(v, BEHIND, lp, s);
- nonword(v, AHEAD, s, rp);
- return;
- break;
- case WBDRY:
- wordchrs(v); /* does NEXT() */
- s = newstate(v->nfa);
- NOERR();
- nonword(v, BEHIND, lp, s);
- word(v, AHEAD, s, rp);
- s = newstate(v->nfa);
- NOERR();
- word(v, BEHIND, lp, s);
- nonword(v, AHEAD, s, rp);
- return;
- break;
- case NWBDRY:
- wordchrs(v); /* does NEXT() */
- s = newstate(v->nfa);
- NOERR();
- word(v, BEHIND, lp, s);
- word(v, AHEAD, s, rp);
- s = newstate(v->nfa);
- NOERR();
- nonword(v, BEHIND, lp, s);
- nonword(v, AHEAD, s, rp);
- return;
- break;
- case LACON: /* lookahead constraint */
- pos = v->nextvalue;
- NEXT();
- s = newstate(v->nfa);
- s2 = newstate(v->nfa);
- NOERR();
- t = parse(v, ')', LACON, s, s2);
- freesubre(v, t); /* internal structure irrelevant */
- assert(SEE(')') || ISERR());
- NEXT();
- n = newlacon(v, s, s2, pos);
- NOERR();
- ARCV(LACON, n);
- return;
- break;
- /* then errors, to get them out of the way */
- case '*':
- case '+':
- case '?':
- case '{':
- ERR(REG_BADRPT);
- return;
- break;
- default:
- ERR(REG_ASSERT);
- return;
- break;
- /* then plain characters, and minor variants on that theme */
- case ')': /* unbalanced paren */
- if ((v->cflags&REG_ADVANCED) != REG_EXTENDED) {
- ERR(REG_EPAREN);
- return;
- }
- /* legal in EREs due to specification botch */
- NOTE(REG_UPBOTCH);
- /* fallthrough into case PLAIN */
- case PLAIN:
- onechr(v, v->nextvalue, lp, rp);
- okcolors(v->nfa, v->cm);
- NOERR();
- NEXT();
- break;
- case '[':
- if (v->nextvalue == 1)
- bracket(v, lp, rp);
- else
- cbracket(v, lp, rp);
- assert(SEE(']') || ISERR());
- NEXT();
- break;
- case '.':
- rainbow(v->nfa, v->cm, PLAIN,
- (v->cflags&REG_NLSTOP) ? v->nlcolor : COLORLESS,
- lp, rp);
- NEXT();
- break;
- /* and finally the ugly stuff */
- case '(': /* value flags as capturing or non */
- cap = (type == LACON) ? 0 : v->nextvalue;
- if (cap) {
- v->nsubexp++;
- subno = v->nsubexp;
- if ((size_t)subno >= v->nsubs)
- moresubs(v, subno);
- assert((size_t)subno < v->nsubs);
- } else
- atomtype = PLAIN; /* something that's not '(' */
- NEXT();
- /* need new endpoints because tree will contain pointers */
- s = newstate(v->nfa);
- s2 = newstate(v->nfa);
- NOERR();
- EMPTYARC(lp, s);
- EMPTYARC(s2, rp);
- NOERR();
- atom = parse(v, ')', PLAIN, s, s2);
- assert(SEE(')') || ISERR());
- NEXT();
- NOERR();
- if (cap) {
- v->subs[subno] = atom;
- t = subre(v, '(', atom->flags|CAP, lp, rp);
- NOERR();
- t->subno = subno;
- t->left = atom;
- atom = t;
- }
- /* postpone everything else pending possible {0} */
- break;
- case BACKREF: /* the Feature From The Black Lagoon */
- INSIST(type != LACON, REG_ESUBREG);
- INSIST(v->nextvalue < v->nsubs, REG_ESUBREG);
- INSIST(v->subs[v->nextvalue] != NULL, REG_ESUBREG);
- NOERR();
- assert(v->nextvalue > 0);
- atom = subre(v, 'b', BACKR, lp, rp);
- subno = v->nextvalue;
- atom->subno = subno;
- EMPTYARC(lp, rp); /* temporarily, so there's something */
- NEXT();
- break;
+ case '^':
+ ARCV('^', 1);
+ if (v->cflags&REG_NLANCH) {
+ ARCV(BEHIND, v->nlcolor);
}
-
- /* ...and an atom may be followed by a quantifier */
- switch (v->nexttype) {
- case '*':
- m = 0;
- n = INFINITY;
- qprefer = (v->nextvalue) ? LONGER : SHORTER;
- NEXT();
- break;
- case '+':
- m = 1;
- n = INFINITY;
- qprefer = (v->nextvalue) ? LONGER : SHORTER;
- NEXT();
- break;
- case '?':
- m = 0;
- n = 1;
- qprefer = (v->nextvalue) ? LONGER : SHORTER;
- NEXT();
- break;
- case '{':
- NEXT();
- m = scannum(v);
- if (EAT(',')) {
- if (SEE(DIGIT))
- n = scannum(v);
- else
- n = INFINITY;
- if (m > n) {
- ERR(REG_BADBR);
- return;
- }
- /* {m,n} exercises preference, even if it's {m,m} */
- qprefer = (v->nextvalue) ? LONGER : SHORTER;
- } else {
- n = m;
- /* {m} passes operand's preference through */
- qprefer = 0;
- }
- if (!SEE('}')) { /* catches errors too */
- ERR(REG_BADBR);
- return;
- }
- NEXT();
- break;
- default: /* no quantifier */
- m = n = 1;
- qprefer = 0;
- break;
+ NEXT();
+ return;
+ case '$':
+ ARCV('$', 1);
+ if (v->cflags&REG_NLANCH) {
+ ARCV(AHEAD, v->nlcolor);
}
+ NEXT();
+ return;
+ case SBEGIN:
+ ARCV('^', 1); /* BOL */
+ ARCV('^', 0); /* or BOS */
+ NEXT();
+ return;
+ case SEND:
+ ARCV('$', 1); /* EOL */
+ ARCV('$', 0); /* or EOS */
+ NEXT();
+ return;
+ case '<':
+ wordchrs(v); /* does NEXT() */
+ s = newstate(v->nfa);
+ NOERR();
+ nonword(v, BEHIND, lp, s);
+ word(v, AHEAD, s, rp);
+ return;
+ case '>':
+ wordchrs(v); /* does NEXT() */
+ s = newstate(v->nfa);
+ NOERR();
+ word(v, BEHIND, lp, s);
+ nonword(v, AHEAD, s, rp);
+ return;
+ case WBDRY:
+ wordchrs(v); /* does NEXT() */
+ s = newstate(v->nfa);
+ NOERR();
+ nonword(v, BEHIND, lp, s);
+ word(v, AHEAD, s, rp);
+ s = newstate(v->nfa);
+ NOERR();
+ word(v, BEHIND, lp, s);
+ nonword(v, AHEAD, s, rp);
+ return;
+ case NWBDRY:
+ wordchrs(v); /* does NEXT() */
+ s = newstate(v->nfa);
+ NOERR();
+ word(v, BEHIND, lp, s);
+ word(v, AHEAD, s, rp);
+ s = newstate(v->nfa);
+ NOERR();
+ nonword(v, BEHIND, lp, s);
+ nonword(v, AHEAD, s, rp);
+ return;
+ case LACON: /* lookahead constraint */
+ pos = v->nextvalue;
+ NEXT();
+ s = newstate(v->nfa);
+ s2 = newstate(v->nfa);
+ NOERR();
+ t = parse(v, ')', LACON, s, s2);
+ freesubre(v, t); /* internal structure irrelevant */
+ assert(SEE(')') || ISERR());
+ NEXT();
+ n = newlacon(v, s, s2, pos);
+ NOERR();
+ ARCV(LACON, n);
+ return;
- /* annoying special case: {0} or {0,0} cancels everything */
- if (m == 0 && n == 0) {
- if (atom != NULL)
- freesubre(v, atom);
- if (atomtype == '(')
- v->subs[subno] = NULL;
- delsub(v->nfa, lp, rp);
- EMPTYARC(lp, rp);
- return;
+ /*
+ * Then errors, to get them out of the way.
+ */
+
+ case '*':
+ case '+':
+ case '?':
+ case '{':
+ ERR(REG_BADRPT);
+ return;
+ default:
+ ERR(REG_ASSERT);
+ return;
+
+ /*
+ * Then plain characters, and minor variants on that theme.
+ */
+
+ case ')': /* unbalanced paren */
+ if ((v->cflags&REG_ADVANCED) != REG_EXTENDED) {
+ ERR(REG_EPAREN);
+ return;
}
- /* if not a messy case, avoid hard part */
- assert(!MESSY(top->flags));
- f = top->flags | qprefer | ((atom != NULL) ? atom->flags : 0);
- if (atomtype != '(' && atomtype != BACKREF && !MESSY(UP(f))) {
- if (!(m == 1 && n == 1))
- repeat(v, lp, rp, m, n);
- if (atom != NULL)
- freesubre(v, atom);
- top->flags = f;
- return;
+ /*
+ * Legal in EREs due to specification botch.
+ */
+
+ NOTE(REG_UPBOTCH);
+ /* fallthrough into case PLAIN */
+ case PLAIN:
+ onechr(v, v->nextvalue, lp, rp);
+ okcolors(v->nfa, v->cm);
+ NOERR();
+ NEXT();
+ break;
+ case '[':
+ if (v->nextvalue == 1) {
+ bracket(v, lp, rp);
+ } else {
+ cbracket(v, lp, rp);
}
+ assert(SEE(']') || ISERR());
+ NEXT();
+ break;
+ case '.':
+ rainbow(v->nfa, v->cm, PLAIN,
+ (v->cflags&REG_NLSTOP) ? v->nlcolor : COLORLESS, lp, rp);
+ NEXT();
+ break;
/*
- * hard part: something messy
- * That is, capturing parens, back reference, short/long clash, or
- * an atom with substructure containing one of those.
+ * And finally the ugly stuff.
*/
- /* now we'll need a subre for the contents even if they're boring */
- if (atom == NULL) {
- atom = subre(v, '=', 0, lp, rp);
- NOERR();
+ case '(': /* value flags as capturing or non */
+ cap = (type == LACON) ? 0 : v->nextvalue;
+ if (cap) {
+ v->nsubexp++;
+ subno = v->nsubexp;
+ if ((size_t)subno >= v->nsubs) {
+ moresubs(v, subno);
+ }
+ assert((size_t)subno < v->nsubs);
+ } else {
+ atomtype = PLAIN; /* something that's not '(' */
}
+ NEXT();
/*
- * prepare a general-purpose state skeleton
- *
- * ---> [s] ---prefix---> [begin] ---atom---> [end] ----rest---> [rp]
- * / /
- * [lp] ----> [s2] ----bypass---------------------
- *
- * where bypass is an empty, and prefix is some repetitions of atom
+ * Need new endpoints because tree will contain pointers.
*/
- s = newstate(v->nfa); /* first, new endpoints for the atom */
+
+ s = newstate(v->nfa);
s2 = newstate(v->nfa);
NOERR();
- moveouts(v->nfa, lp, s);
- moveins(v->nfa, rp, s2);
+ EMPTYARC(lp, s);
+ EMPTYARC(s2, rp);
NOERR();
- atom->begin = s;
- atom->end = s2;
- s = newstate(v->nfa); /* and spots for prefix and bypass */
- s2 = newstate(v->nfa);
+ atom = parse(v, ')', PLAIN, s, s2);
+ assert(SEE(')') || ISERR());
+ NEXT();
NOERR();
- EMPTYARC(lp, s);
- EMPTYARC(lp, s2);
+ if (cap) {
+ v->subs[subno] = atom;
+ t = subre(v, '(', atom->flags|CAP, lp, rp);
+ NOERR();
+ t->subno = subno;
+ t->left = atom;
+ atom = t;
+ }
+
+ /*
+ * Postpone everything else pending possible {0}.
+ */
+
+ break;
+ case BACKREF: /* the Feature From The Black Lagoon */
+ INSIST(type != LACON, REG_ESUBREG);
+ INSIST(v->nextvalue < v->nsubs, REG_ESUBREG);
+ INSIST(v->subs[v->nextvalue] != NULL, REG_ESUBREG);
NOERR();
+ assert(v->nextvalue > 0);
+ atom = subre(v, 'b', BACKR, lp, rp);
+ subno = v->nextvalue;
+ atom->subno = subno;
+ EMPTYARC(lp, rp); /* temporarily, so there's something */
+ NEXT();
+ break;
+ }
- /* break remaining subRE into x{...} and what follows */
- t = subre(v, '.', COMBINE(qprefer, atom->flags), lp, rp);
- t->left = atom;
- atomp = &t->left;
- /* here we should recurse... but we must postpone that to the end */
-
- /* split top into prefix and remaining */
- assert(top->op == '=' && top->left == NULL && top->right == NULL);
- top->left = subre(v, '=', top->flags, top->begin, lp);
- top->op = '.';
- top->right = t;
-
- /* if it's a backref, now is the time to replicate the subNFA */
- if (atomtype == BACKREF) {
- assert(atom->begin->nouts == 1); /* just the EMPTY */
- delsub(v->nfa, atom->begin, atom->end);
- assert(v->subs[subno] != NULL);
- /* and here's why the recursion got postponed: it must */
- /* wait until the skeleton is filled in, because it may */
- /* hit a backref that wants to copy the filled-in skeleton */
- dupnfa(v->nfa, v->subs[subno]->begin, v->subs[subno]->end,
- atom->begin, atom->end);
- NOERR();
- }
+ /*
+ * ...and an atom may be followed by a quantifier.
+ */
- /* it's quantifier time; first, turn x{0,...} into x{1,...}|empty */
- if (m == 0) {
- EMPTYARC(s2, atom->end); /* the bypass */
- assert(PREF(qprefer) != 0);
- f = COMBINE(qprefer, atom->flags);
- t = subre(v, '|', f, lp, atom->end);
- NOERR();
- t->left = atom;
- t->right = subre(v, '|', PREF(f), s2, atom->end);
- NOERR();
- t->right->left = subre(v, '=', 0, s2, atom->end);
- NOERR();
- *atomp = t;
- atomp = &t->left;
- m = 1;
- }
+ switch (v->nexttype) {
+ case '*':
+ m = 0;
+ n = INFINITY;
+ qprefer = (v->nextvalue) ? LONGER : SHORTER;
+ NEXT();
+ break;
+ case '+':
+ m = 1;
+ n = INFINITY;
+ qprefer = (v->nextvalue) ? LONGER : SHORTER;
+ NEXT();
+ break;
+ case '?':
+ m = 0;
+ n = 1;
+ qprefer = (v->nextvalue) ? LONGER : SHORTER;
+ NEXT();
+ break;
+ case '{':
+ NEXT();
+ m = scannum(v);
+ if (EAT(',')) {
+ if (SEE(DIGIT)) {
+ n = scannum(v);
+ } else {
+ n = INFINITY;
+ }
+ if (m > n) {
+ ERR(REG_BADBR);
+ return;
+ }
- /* deal with the rest of the quantifier */
- if (atomtype == BACKREF) {
- /* special case: backrefs have internal quantifiers */
- EMPTYARC(s, atom->begin); /* empty prefix */
- /* just stuff everything into atom */
- repeat(v, atom->begin, atom->end, m, n);
- atom->min = (short)m;
- atom->max = (short)n;
- atom->flags |= COMBINE(qprefer, atom->flags);
- } else if (m == 1 && n == 1) {
- /* no/vacuous quantifier: done */
- EMPTYARC(s, atom->begin); /* empty prefix */
+ /*
+ * {m,n} exercises preference, even if it's {m,m}
+ */
+
+ qprefer = (v->nextvalue) ? LONGER : SHORTER;
} else {
- /* turn x{m,n} into x{m-1,n-1}x, with capturing */
- /* parens in only second x */
- dupnfa(v->nfa, atom->begin, atom->end, s, atom->begin);
- assert(m >= 1 && m != INFINITY && n >= 1);
- repeat(v, s, atom->begin, m-1, (n == INFINITY) ? n : n-1);
- f = COMBINE(qprefer, atom->flags);
- t = subre(v, '.', f, s, atom->end); /* prefix and atom */
- NOERR();
- t->left = subre(v, '=', PREF(f), s, atom->begin);
- NOERR();
- t->right = atom;
- *atomp = t;
+ n = m;
+ /*
+ * {m} passes operand's preference through.
+ */
+
+ qprefer = 0;
+ }
+ if (!SEE('}')) { /* catches errors too */
+ ERR(REG_BADBR);
+ return;
+ }
+ NEXT();
+ break;
+ default: /* no quantifier */
+ m = n = 1;
+ qprefer = 0;
+ break;
+ }
+
+ /*
+ * Annoying special case: {0} or {0,0} cancels everything.
+ */
+
+ if (m == 0 && n == 0) {
+ if (atom != NULL) {
+ freesubre(v, atom);
}
+ if (atomtype == '(') {
+ v->subs[subno] = NULL;
+ }
+ delsub(v->nfa, lp, rp);
+ EMPTYARC(lp, rp);
+ return;
+ }
- /* and finally, look after that postponed recursion */
- t = top->right;
- if (!(SEE('|') || SEE(stopper) || SEE(EOS)))
- t->right = parsebranch(v, stopper, type, atom->end, rp, 1);
- else {
- EMPTYARC(atom->end, rp);
- t->right = subre(v, '=', 0, atom->end, rp);
+ /*
+ * If not a messy case, avoid hard part.
+ */
+
+ assert(!MESSY(top->flags));
+ f = top->flags | qprefer | ((atom != NULL) ? atom->flags : 0);
+ if (atomtype != '(' && atomtype != BACKREF && !MESSY(UP(f))) {
+ if (!(m == 1 && n == 1)) {
+ repeat(v, lp, rp, m, n);
}
- assert(SEE('|') || SEE(stopper) || SEE(EOS));
- t->flags |= COMBINE(t->flags, t->right->flags);
- top->flags |= COMBINE(top->flags, t->flags);
-}
+ if (atom != NULL) {
+ freesubre(v, atom);
+ }
+ top->flags = f;
+ return;
+ }
+
+ /*
+ * hard part: something messy
+ * That is, capturing parens, back reference, short/long clash, or an atom
+ * with substructure containing one of those.
+ */
+
+ /*
+ * Now we'll need a subre for the contents even if they're boring.
+ */
+
+ if (atom == NULL) {
+ atom = subre(v, '=', 0, lp, rp);
+ NOERR();
+ }
+
+ /*
+ * Prepare a general-purpose state skeleton.
+ *
+ * ---> [s] ---prefix---> [begin] ---atom---> [end] ----rest---> [rp]
+ * / /
+ * [lp] ----> [s2] ----bypass---------------------
+ *
+ * where bypass is an empty, and prefix is some repetitions of atom
+ */
+
+ s = newstate(v->nfa); /* first, new endpoints for the atom */
+ s2 = newstate(v->nfa);
+ NOERR();
+ moveouts(v->nfa, lp, s);
+ moveins(v->nfa, rp, s2);
+ NOERR();
+ atom->begin = s;
+ atom->end = s2;
+ s = newstate(v->nfa); /* and spots for prefix and bypass */
+ s2 = newstate(v->nfa);
+ NOERR();
+ EMPTYARC(lp, s);
+ EMPTYARC(lp, s2);
+ NOERR();
+
+ /*
+ * Break remaining subRE into x{...} and what follows.
+ */
+
+ t = subre(v, '.', COMBINE(qprefer, atom->flags), lp, rp);
+ t->left = atom;
+ atomp = &t->left;
+
+ /*
+ * Here we should recurse... but we must postpone that to the end.
+ */
+
+ /*
+ * Split top into prefix and remaining.
+ */
+
+ assert(top->op == '=' && top->left == NULL && top->right == NULL);
+ top->left = subre(v, '=', top->flags, top->begin, lp);
+ top->op = '.';
+ top->right = t;
+
+ /*
+ * If it's a backref, now is the time to replicate the subNFA.
+ */
+
+ if (atomtype == BACKREF) {
+ assert(atom->begin->nouts == 1); /* just the EMPTY */
+ delsub(v->nfa, atom->begin, atom->end);
+ assert(v->subs[subno] != NULL);
+
+ /*
+ * And here's why the recursion got postponed: it must wait until the
+ * skeleton is filled in, because it may hit a backref that wants to
+ * copy the filled-in skeleton.
+ */
+
+ dupnfa(v->nfa, v->subs[subno]->begin, v->subs[subno]->end,
+ atom->begin, atom->end);
+ NOERR();
+ }
+
+ /*
+ * It's quantifier time; first, turn x{0,...} into x{1,...}|empty
+ */
+
+ if (m == 0) {
+ EMPTYARC(s2, atom->end);/* the bypass */
+ assert(PREF(qprefer) != 0);
+ f = COMBINE(qprefer, atom->flags);
+ t = subre(v, '|', f, lp, atom->end);
+ NOERR();
+ t->left = atom;
+ t->right = subre(v, '|', PREF(f), s2, atom->end);
+ NOERR();
+ t->right->left = subre(v, '=', 0, s2, atom->end);
+ NOERR();
+ *atomp = t;
+ atomp = &t->left;
+ m = 1;
+ }
+
+ /*
+ * Deal with the rest of the quantifier.
+ */
+
+ if (atomtype == BACKREF) {
+ /*
+ * Special case: backrefs have internal quantifiers.
+ */
+
+ EMPTYARC(s, atom->begin); /* empty prefix */
+
+ /*
+ * Just stuff everything into atom.
+ */
+
+ repeat(v, atom->begin, atom->end, m, n);
+ atom->min = (short) m;
+ atom->max = (short) n;
+ atom->flags |= COMBINE(qprefer, atom->flags);
+ } else if (m == 1 && n == 1) {
+ /*
+ * No/vacuous quantifier: done.
+ */
+
+ EMPTYARC(s, atom->begin); /* empty prefix */
+ } else {
+ /*
+ * Turn x{m,n} into x{m-1,n-1}x, with capturing parens in only second
+ * x
+ */
+ dupnfa(v->nfa, atom->begin, atom->end, s, atom->begin);
+ assert(m >= 1 && m != INFINITY && n >= 1);
+ repeat(v, s, atom->begin, m-1, (n == INFINITY) ? n : n-1);
+ f = COMBINE(qprefer, atom->flags);
+ t = subre(v, '.', f, s, atom->end); /* prefix and atom */
+ NOERR();
+ t->left = subre(v, '=', PREF(f), s, atom->begin);
+ NOERR();
+ t->right = atom;
+ *atomp = t;
+ }
+
+ /*
+ * And finally, look after that postponed recursion.
+ */
+
+ t = top->right;
+ if (!(SEE('|') || SEE(stopper) || SEE(EOS))) {
+ t->right = parsebranch(v, stopper, type, atom->end, rp, 1);
+ } else {
+ EMPTYARC(atom->end, rp);
+ t->right = subre(v, '=', 0, atom->end, rp);
+ }
+ assert(SEE('|') || SEE(stopper) || SEE(EOS));
+ t->flags |= COMBINE(t->flags, t->right->flags);
+ top->flags |= COMBINE(top->flags, t->flags);
+}
+
/*
- nonword - generate arcs for non-word-character ahead or behind
- ^ static VOID nonword(struct vars *, int, struct state *, struct state *);
+ ^ static void nonword(struct vars *, int, struct state *, struct state *);
*/
-static VOID
-nonword(v, dir, lp, rp)
-struct vars *v;
-int dir; /* AHEAD or BEHIND */
-struct state *lp;
-struct state *rp;
+static void
+nonword(
+ struct vars *v,
+ int dir, /* AHEAD or BEHIND */
+ struct state *lp,
+ struct state *rp)
{
- int anchor = (dir == AHEAD) ? '$' : '^';
+ int anchor = (dir == AHEAD) ? '$' : '^';
- assert(dir == AHEAD || dir == BEHIND);
- newarc(v->nfa, anchor, 1, lp, rp);
- newarc(v->nfa, anchor, 0, lp, rp);
- colorcomplement(v->nfa, v->cm, dir, v->wordchrs, lp, rp);
- /* (no need for special attention to \n) */
+ assert(dir == AHEAD || dir == BEHIND);
+ newarc(v->nfa, anchor, 1, lp, rp);
+ newarc(v->nfa, anchor, 0, lp, rp);
+ colorcomplement(v->nfa, v->cm, dir, v->wordchrs, lp, rp);
+ /* (no need for special attention to \n) */
}
-
+
/*
- word - generate arcs for word character ahead or behind
- ^ static VOID word(struct vars *, int, struct state *, struct state *);
+ ^ static void word(struct vars *, int, struct state *, struct state *);
*/
-static VOID
-word(v, dir, lp, rp)
-struct vars *v;
-int dir; /* AHEAD or BEHIND */
-struct state *lp;
-struct state *rp;
+static void
+word(
+ struct vars *v,
+ int dir, /* AHEAD or BEHIND */
+ struct state *lp,
+ struct state *rp)
{
- assert(dir == AHEAD || dir == BEHIND);
- cloneouts(v->nfa, v->wordchrs, lp, rp, dir);
- /* (no need for special attention to \n) */
+ assert(dir == AHEAD || dir == BEHIND);
+ cloneouts(v->nfa, v->wordchrs, lp, rp, dir);
+ /* (no need for special attention to \n) */
}
-
+
/*
- scannum - scan a number
^ static int scannum(struct vars *);
*/
static int /* value, <= DUPMAX */
-scannum(v)
-struct vars *v;
+scannum(
+ struct vars *v)
{
- int n = 0;
+ int n = 0;
- while (SEE(DIGIT) && n < DUPMAX) {
- n = n*10 + v->nextvalue;
- NEXT();
- }
- if (SEE(DIGIT) || n > DUPMAX) {
- ERR(REG_BADBR);
- return 0;
- }
- return n;
+ while (SEE(DIGIT) && n < DUPMAX) {
+ n = n*10 + v->nextvalue;
+ NEXT();
+ }
+ if (SEE(DIGIT) || n > DUPMAX) {
+ ERR(REG_BADBR);
+ return 0;
+ }
+ return n;
}
-
+
/*
- repeat - replicate subNFA for quantifiers
* The duplication sequences used here are chosen carefully so that any
* pointers starting out pointing into the subexpression end up pointing into
- * the last occurrence. (Note that it may not be strung between the same
- * left and right end states, however!) This used to be important for the
- * subRE tree, although the important bits are now handled by the in-line
- * code in parse(), and when this is called, it doesn't matter any more.
- ^ static VOID repeat(struct vars *, struct state *, struct state *, int, int);
+ * the last occurrence. (Note that it may not be strung between the same left
+ * and right end states, however!) This used to be important for the subRE
+ * tree, although the important bits are now handled by the in-line code in
+ * parse(), and when this is called, it doesn't matter any more.
+ ^ static void repeat(struct vars *, struct state *, struct state *, int, int);
*/
-static VOID
-repeat(v, lp, rp, m, n)
-struct vars *v;
-struct state *lp;
-struct state *rp;
-int m;
-int n;
+static void
+repeat(
+ struct vars *v,
+ struct state *lp,
+ struct state *rp,
+ int m,
+ int n)
{
-# define SOME 2
-# define INF 3
-# define PAIR(x, y) ((x)*4 + (y))
-# define REDUCE(x) ( ((x) == INFINITY) ? INF : (((x) > 1) ? SOME : (x)) )
- CONST int rm = REDUCE(m);
- CONST int rn = REDUCE(n);
- struct state *s;
- struct state *s2;
-
- switch (PAIR(rm, rn)) {
- case PAIR(0, 0): /* empty string */
- delsub(v->nfa, lp, rp);
- EMPTYARC(lp, rp);
- break;
- case PAIR(0, 1): /* do as x| */
- EMPTYARC(lp, rp);
- break;
- case PAIR(0, SOME): /* do as x{1,n}| */
- repeat(v, lp, rp, 1, n);
- NOERR();
- EMPTYARC(lp, rp);
- break;
- case PAIR(0, INF): /* loop x around */
- s = newstate(v->nfa);
- NOERR();
- moveouts(v->nfa, lp, s);
- moveins(v->nfa, rp, s);
- EMPTYARC(lp, s);
- EMPTYARC(s, rp);
- break;
- case PAIR(1, 1): /* no action required */
- break;
- case PAIR(1, SOME): /* do as x{0,n-1}x = (x{1,n-1}|)x */
- s = newstate(v->nfa);
- NOERR();
- moveouts(v->nfa, lp, s);
- dupnfa(v->nfa, s, rp, lp, s);
- NOERR();
- repeat(v, lp, s, 1, n-1);
- NOERR();
- EMPTYARC(lp, s);
- break;
- case PAIR(1, INF): /* add loopback arc */
- s = newstate(v->nfa);
- s2 = newstate(v->nfa);
- NOERR();
- moveouts(v->nfa, lp, s);
- moveins(v->nfa, rp, s2);
- EMPTYARC(lp, s);
- EMPTYARC(s2, rp);
- EMPTYARC(s2, s);
- break;
- case PAIR(SOME, SOME): /* do as x{m-1,n-1}x */
- s = newstate(v->nfa);
- NOERR();
- moveouts(v->nfa, lp, s);
- dupnfa(v->nfa, s, rp, lp, s);
- NOERR();
- repeat(v, lp, s, m-1, n-1);
- break;
- case PAIR(SOME, INF): /* do as x{m-1,}x */
- s = newstate(v->nfa);
- NOERR();
- moveouts(v->nfa, lp, s);
- dupnfa(v->nfa, s, rp, lp, s);
- NOERR();
- repeat(v, lp, s, m-1, n);
- break;
- default:
- ERR(REG_ASSERT);
- break;
- }
+#define SOME 2
+#define INF 3
+#define PAIR(x, y) ((x)*4 + (y))
+#define REDUCE(x) ( ((x) == INFINITY) ? INF : (((x) > 1) ? SOME : (x)) )
+ const int rm = REDUCE(m);
+ const int rn = REDUCE(n);
+ struct state *s, *s2;
+
+ switch (PAIR(rm, rn)) {
+ case PAIR(0, 0): /* empty string */
+ delsub(v->nfa, lp, rp);
+ EMPTYARC(lp, rp);
+ break;
+ case PAIR(0, 1): /* do as x| */
+ EMPTYARC(lp, rp);
+ break;
+ case PAIR(0, SOME): /* do as x{1,n}| */
+ repeat(v, lp, rp, 1, n);
+ NOERR();
+ EMPTYARC(lp, rp);
+ break;
+ case PAIR(0, INF): /* loop x around */
+ s = newstate(v->nfa);
+ NOERR();
+ moveouts(v->nfa, lp, s);
+ moveins(v->nfa, rp, s);
+ EMPTYARC(lp, s);
+ EMPTYARC(s, rp);
+ break;
+ case PAIR(1, 1): /* no action required */
+ break;
+ case PAIR(1, SOME): /* do as x{0,n-1}x = (x{1,n-1}|)x */
+ s = newstate(v->nfa);
+ NOERR();
+ moveouts(v->nfa, lp, s);
+ dupnfa(v->nfa, s, rp, lp, s);
+ NOERR();
+ repeat(v, lp, s, 1, n-1);
+ NOERR();
+ EMPTYARC(lp, s);
+ break;
+ case PAIR(1, INF): /* add loopback arc */
+ s = newstate(v->nfa);
+ s2 = newstate(v->nfa);
+ NOERR();
+ moveouts(v->nfa, lp, s);
+ moveins(v->nfa, rp, s2);
+ EMPTYARC(lp, s);
+ EMPTYARC(s2, rp);
+ EMPTYARC(s2, s);
+ break;
+ case PAIR(SOME, SOME): /* do as x{m-1,n-1}x */
+ s = newstate(v->nfa);
+ NOERR();
+ moveouts(v->nfa, lp, s);
+ dupnfa(v->nfa, s, rp, lp, s);
+ NOERR();
+ repeat(v, lp, s, m-1, n-1);
+ break;
+ case PAIR(SOME, INF): /* do as x{m-1,}x */
+ s = newstate(v->nfa);
+ NOERR();
+ moveouts(v->nfa, lp, s);
+ dupnfa(v->nfa, s, rp, lp, s);
+ NOERR();
+ repeat(v, lp, s, m-1, n);
+ break;
+ default:
+ ERR(REG_ASSERT);
+ break;
+ }
}
-
+
/*
- bracket - handle non-complemented bracket expression
* Also called from cbracket for complemented bracket expressions.
- ^ static VOID bracket(struct vars *, struct state *, struct state *);
+ ^ static void bracket(struct vars *, struct state *, struct state *);
*/
-static VOID
-bracket(v, lp, rp)
-struct vars *v;
-struct state *lp;
-struct state *rp;
+static void
+bracket(
+ struct vars *v,
+ struct state *lp,
+ struct state *rp)
{
- assert(SEE('['));
- NEXT();
- while (!SEE(']') && !SEE(EOS))
- brackpart(v, lp, rp);
- assert(SEE(']') || ISERR());
- okcolors(v->nfa, v->cm);
+ assert(SEE('['));
+ NEXT();
+ while (!SEE(']') && !SEE(EOS)) {
+ brackpart(v, lp, rp);
+ }
+ assert(SEE(']') || ISERR());
+ okcolors(v->nfa, v->cm);
}
-
+
/*
- cbracket - handle complemented bracket expression
* We do it by calling bracket() with dummy endpoints, and then complementing
- * the result. The alternative would be to invoke rainbow(), and then delete
+ * the result. The alternative would be to invoke rainbow(), and then delete
* arcs as the b.e. is seen... but that gets messy.
- ^ static VOID cbracket(struct vars *, struct state *, struct state *);
+ ^ static void cbracket(struct vars *, struct state *, struct state *);
*/
-static VOID
-cbracket(v, lp, rp)
-struct vars *v;
-struct state *lp;
-struct state *rp;
+static void
+cbracket(
+ struct vars *v,
+ struct state *lp,
+ struct state *rp)
{
- struct state *left = newstate(v->nfa);
- struct state *right = newstate(v->nfa);
- struct state *s;
- struct arc *a; /* arc from lp */
- struct arc *ba; /* arc from left, from bracket() */
- struct arc *pa; /* MCCE-prototype arc */
- color co;
- chr *p;
- int i;
+ struct state *left = newstate(v->nfa);
+ struct state *right = newstate(v->nfa);
- NOERR();
- bracket(v, left, right);
- if (v->cflags&REG_NLSTOP)
- newarc(v->nfa, PLAIN, v->nlcolor, left, right);
- NOERR();
+ NOERR();
+ bracket(v, left, right);
+ if (v->cflags&REG_NLSTOP) {
+ newarc(v->nfa, PLAIN, v->nlcolor, left, right);
+ }
+ NOERR();
- assert(lp->nouts == 0); /* all outarcs will be ours */
+ assert(lp->nouts == 0); /* all outarcs will be ours */
- /* easy part of complementing */
- colorcomplement(v->nfa, v->cm, PLAIN, left, lp, rp);
- NOERR();
- if (v->mcces == NULL) { /* no MCCEs -- we're done */
- dropstate(v->nfa, left);
- assert(right->nins == 0);
- freestate(v->nfa, right);
- return;
- }
-
- /* but complementing gets messy in the presence of MCCEs... */
- NOTE(REG_ULOCALE);
- for (p = v->mcces->chrs, i = v->mcces->nchrs; i > 0; p++, i--) {
- co = GETCOLOR(v->cm, *p);
- a = findarc(lp, PLAIN, co);
- ba = findarc(left, PLAIN, co);
- if (ba == NULL) {
- assert(a != NULL);
- freearc(v->nfa, a);
- } else {
- assert(a == NULL);
- }
- s = newstate(v->nfa);
- NOERR();
- newarc(v->nfa, PLAIN, co, lp, s);
- NOERR();
- pa = findarc(v->mccepbegin, PLAIN, co);
- assert(pa != NULL);
- if (ba == NULL) { /* easy case, need all of them */
- cloneouts(v->nfa, pa->to, s, rp, PLAIN);
- newarc(v->nfa, '$', 1, s, rp);
- newarc(v->nfa, '$', 0, s, rp);
- colorcomplement(v->nfa, v->cm, AHEAD, pa->to, s, rp);
- } else { /* must be selective */
- if (findarc(ba->to, '$', 1) == NULL) {
- newarc(v->nfa, '$', 1, s, rp);
- newarc(v->nfa, '$', 0, s, rp);
- colorcomplement(v->nfa, v->cm, AHEAD, pa->to,
- s, rp);
- }
- for (pa = pa->to->outs; pa != NULL; pa = pa->outchain)
- if (findarc(ba->to, PLAIN, pa->co) == NULL)
- newarc(v->nfa, PLAIN, pa->co, s, rp);
- if (s->nouts == 0) /* limit of selectivity: none */
- dropstate(v->nfa, s); /* frees arc too */
- }
- NOERR();
- }
+ /*
+ * Easy part of complementing, and all there is to do since the MCCE code
+ * was removed.
+ */
- delsub(v->nfa, left, right);
- assert(left->nouts == 0);
- freestate(v->nfa, left);
- assert(right->nins == 0);
- freestate(v->nfa, right);
+ colorcomplement(v->nfa, v->cm, PLAIN, left, lp, rp);
+ NOERR();
+ dropstate(v->nfa, left);
+ assert(right->nins == 0);
+ freestate(v->nfa, right);
+ return;
}
-
+
/*
- brackpart - handle one item (or range) within a bracket expression
- ^ static VOID brackpart(struct vars *, struct state *, struct state *);
+ ^ static void brackpart(struct vars *, struct state *, struct state *);
*/
-static VOID
-brackpart(v, lp, rp)
-struct vars *v;
-struct state *lp;
-struct state *rp;
+static void
+brackpart(
+ struct vars *v,
+ struct state *lp,
+ struct state *rp)
{
- celt startc;
- celt endc;
- struct cvec *cv;
- chr *startp;
- chr *endp;
- chr c[1];
-
- /* parse something, get rid of special cases, take shortcuts */
+ celt startc, endc;
+ struct cvec *cv;
+ const chr *startp, *endp;
+ chr c[1];
+
+ /*
+ * Parse something, get rid of special cases, take shortcuts.
+ */
+
+ switch (v->nexttype) {
+ case RANGE: /* a-b-c or other botch */
+ ERR(REG_ERANGE);
+ return;
+ break;
+ case PLAIN:
+ c[0] = v->nextvalue;
+ NEXT();
+
+ /*
+ * Shortcut for ordinary chr (not range).
+ */
+
+ if (!SEE(RANGE)) {
+ onechr(v, c[0], lp, rp);
+ return;
+ }
+ startc = element(v, c, c+1);
+ NOERR();
+ break;
+ case COLLEL:
+ startp = v->now;
+ endp = scanplain(v);
+ INSIST(startp < endp, REG_ECOLLATE);
+ NOERR();
+ startc = element(v, startp, endp);
+ NOERR();
+ break;
+ case ECLASS:
+ startp = v->now;
+ endp = scanplain(v);
+ INSIST(startp < endp, REG_ECOLLATE);
+ NOERR();
+ startc = element(v, startp, endp);
+ NOERR();
+ cv = eclass(v, startc, (v->cflags&REG_ICASE));
+ NOERR();
+ dovec(v, cv, lp, rp);
+ return;
+ break;
+ case CCLASS:
+ startp = v->now;
+ endp = scanplain(v);
+ INSIST(startp < endp, REG_ECTYPE);
+ NOERR();
+ cv = cclass(v, startp, endp, (v->cflags&REG_ICASE));
+ NOERR();
+ dovec(v, cv, lp, rp);
+ return;
+ break;
+ default:
+ ERR(REG_ASSERT);
+ return;
+ break;
+ }
+
+ if (SEE(RANGE)) {
+ NEXT();
switch (v->nexttype) {
- case RANGE: /* a-b-c or other botch */
- ERR(REG_ERANGE);
- return;
- break;
case PLAIN:
- c[0] = v->nextvalue;
- NEXT();
- /* shortcut for ordinary chr (not range, not MCCE leader) */
- if (!SEE(RANGE) && !ISCELEADER(v, c[0])) {
- onechr(v, c[0], lp, rp);
- return;
- }
- startc = element(v, c, c+1);
- NOERR();
- break;
+ case RANGE:
+ c[0] = v->nextvalue;
+ NEXT();
+ endc = element(v, c, c+1);
+ NOERR();
+ break;
case COLLEL:
- startp = v->now;
- endp = scanplain(v);
- INSIST(startp < endp, REG_ECOLLATE);
- NOERR();
- startc = element(v, startp, endp);
- NOERR();
- break;
- case ECLASS:
- startp = v->now;
- endp = scanplain(v);
- INSIST(startp < endp, REG_ECOLLATE);
- NOERR();
- startc = element(v, startp, endp);
- NOERR();
- cv = eclass(v, startc, (v->cflags&REG_ICASE));
- NOERR();
- dovec(v, cv, lp, rp);
- return;
- break;
- case CCLASS:
- startp = v->now;
- endp = scanplain(v);
- INSIST(startp < endp, REG_ECTYPE);
- NOERR();
- cv = cclass(v, startp, endp, (v->cflags&REG_ICASE));
- NOERR();
- dovec(v, cv, lp, rp);
- return;
- break;
+ startp = v->now;
+ endp = scanplain(v);
+ INSIST(startp < endp, REG_ECOLLATE);
+ NOERR();
+ endc = element(v, startp, endp);
+ NOERR();
+ break;
default:
- ERR(REG_ASSERT);
- return;
- break;
+ ERR(REG_ERANGE);
+ return;
+ break;
}
+ } else {
+ endc = startc;
+ }
- if (SEE(RANGE)) {
- NEXT();
- switch (v->nexttype) {
- case PLAIN:
- case RANGE:
- c[0] = v->nextvalue;
- NEXT();
- endc = element(v, c, c+1);
- NOERR();
- break;
- case COLLEL:
- startp = v->now;
- endp = scanplain(v);
- INSIST(startp < endp, REG_ECOLLATE);
- NOERR();
- endc = element(v, startp, endp);
- NOERR();
- break;
- default:
- ERR(REG_ERANGE);
- return;
- break;
- }
- } else
- endc = startc;
+ /*
+ * Ranges are unportable. Actually, standard C does guarantee that digits
+ * are contiguous, but making that an exception is just too complicated.
+ */
- /*
- * Ranges are unportable. Actually, standard C does
- * guarantee that digits are contiguous, but making
- * that an exception is just too complicated.
- */
- if (startc != endc)
- NOTE(REG_UUNPORT);
- cv = range(v, startc, endc, (v->cflags&REG_ICASE));
- NOERR();
- dovec(v, cv, lp, rp);
+ if (startc != endc) {
+ NOTE(REG_UUNPORT);
+ }
+ cv = range(v, startc, endc, (v->cflags&REG_ICASE));
+ NOERR();
+ dovec(v, cv, lp, rp);
}
-
+
/*
- scanplain - scan PLAIN contents of [. etc.
- * Certain bits of trickery in lex.c know that this code does not try
- * to look past the final bracket of the [. etc.
- ^ static chr *scanplain(struct vars *);
+ * Certain bits of trickery in lex.c know that this code does not try to look
+ * past the final bracket of the [. etc.
+ ^ static const chr *scanplain(struct vars *);
*/
-static chr * /* just after end of sequence */
-scanplain(v)
-struct vars *v;
+static const chr * /* just after end of sequence */
+scanplain(
+ struct vars *v)
{
- chr *endp;
+ const chr *endp;
- assert(SEE(COLLEL) || SEE(ECLASS) || SEE(CCLASS));
- NEXT();
+ assert(SEE(COLLEL) || SEE(ECLASS) || SEE(CCLASS));
+ NEXT();
+ endp = v->now;
+ while (SEE(PLAIN)) {
endp = v->now;
- while (SEE(PLAIN)) {
- endp = v->now;
- NEXT();
- }
-
- assert(SEE(END) || ISERR());
NEXT();
+ }
- return endp;
-}
+ assert(SEE(END) || ISERR());
+ NEXT();
+ return endp;
+}
+
/*
- onechr - fill in arcs for a plain character, and possible case complements
* This is mostly a shortcut for efficient handling of the common case.
- ^ static VOID onechr(struct vars *, pchr, struct state *, struct state *);
+ ^ static void onechr(struct vars *, pchr, struct state *, struct state *);
*/
-static VOID
-onechr(v, c, lp, rp)
-struct vars *v;
-pchr c;
-struct state *lp;
-struct state *rp;
+static void
+onechr(
+ struct vars *v,
+ pchr c,
+ struct state *lp,
+ struct state *rp)
{
- if (!(v->cflags&REG_ICASE)) {
- newarc(v->nfa, PLAIN, subcolor(v->cm, c), lp, rp);
- return;
- }
+ if (!(v->cflags&REG_ICASE)) {
+ newarc(v->nfa, PLAIN, subcolor(v->cm, c), lp, rp);
+ return;
+ }
- /* rats, need general case anyway... */
- dovec(v, allcases(v, c), lp, rp);
-}
+ /*
+ * Rats, need general case anyway...
+ */
+ dovec(v, allcases(v, c), lp, rp);
+}
+
/*
- dovec - fill in arcs for each element of a cvec
- * This one has to handle the messy cases, like MCCEs and MCCE leaders.
- ^ static VOID dovec(struct vars *, struct cvec *, struct state *,
+ ^ static void dovec(struct vars *, struct cvec *, struct state *,
^ struct state *);
*/
-static VOID
-dovec(v, cv, lp, rp)
-struct vars *v;
-struct cvec *cv;
-struct state *lp;
-struct state *rp;
+static void
+dovec(
+ struct vars *v,
+ struct cvec *cv,
+ struct state *lp,
+ struct state *rp)
{
- chr ch, from, to;
- celt ce;
- chr *p;
- int i;
- color co;
- struct cvec *leads;
- struct arc *a;
- struct arc *pa; /* arc in prototype */
- struct state *s;
- struct state *ps; /* state in prototype */
-
- leads = NULL;
-
- /* first, get the ordinary characters out of the way */
- for (p = cv->chrs, i = cv->nchrs; i > 0; p++, i--) {
- ch = *p;
- if (!ISCELEADER(v, ch))
- newarc(v->nfa, PLAIN, subcolor(v->cm, ch), lp, rp);
- else {
- assert(singleton(v->cm, ch));
- assert(leads != NULL);
- if (!haschr(leads, ch))
- addchr(leads, ch);
- }
- }
-
- /* and the ranges */
- for (p = cv->ranges, i = cv->nranges; i > 0; p += 2, i--) {
- from = *p;
- to = *(p+1);
- while (from <= to && (ce = nextleader(v, from, to)) != NOCELT) {
- if (from < ce)
- subrange(v, from, ce - 1, lp, rp);
- assert(singleton(v->cm, ce));
- assert(leads != NULL);
- if (!haschr(leads, ce))
- addchr(leads, ce);
- from = ce + 1;
- }
- if (from <= to)
- subrange(v, from, to, lp, rp);
+ chr ch, from, to;
+ const chr *p;
+ int i;
+
+ for (p = cv->chrs, i = cv->nchrs; i > 0; p++, i--) {
+ ch = *p;
+ newarc(v->nfa, PLAIN, subcolor(v->cm, ch), lp, rp);
+ }
+
+ for (p = cv->ranges, i = cv->nranges; i > 0; p += 2, i--) {
+ from = *p;
+ to = *(p+1);
+ if (from <= to) {
+ subrange(v, from, to, lp, rp);
}
+ }
- if ((leads == NULL || leads->nchrs == 0) && cv->nmcces == 0)
- return;
-
- /* deal with the MCCE leaders */
- NOTE(REG_ULOCALE);
- for (p = leads->chrs, i = leads->nchrs; i > 0; p++, i--) {
- co = GETCOLOR(v->cm, *p);
- a = findarc(lp, PLAIN, co);
- if (a != NULL)
- s = a->to;
- else {
- s = newstate(v->nfa);
- NOERR();
- newarc(v->nfa, PLAIN, co, lp, s);
- NOERR();
- }
- pa = findarc(v->mccepbegin, PLAIN, co);
- assert(pa != NULL);
- ps = pa->to;
- newarc(v->nfa, '$', 1, s, rp);
- newarc(v->nfa, '$', 0, s, rp);
- colorcomplement(v->nfa, v->cm, AHEAD, ps, s, rp);
- NOERR();
- }
-
- /* and the MCCEs */
- for (i = 0; i < cv->nmcces; i++) {
- p = cv->mcces[i];
- assert(singleton(v->cm, *p));
- if (!singleton(v->cm, *p)) {
- ERR(REG_ASSERT);
- return;
- }
- ch = *p++;
- co = GETCOLOR(v->cm, ch);
- a = findarc(lp, PLAIN, co);
- if (a != NULL)
- s = a->to;
- else {
- s = newstate(v->nfa);
- NOERR();
- newarc(v->nfa, PLAIN, co, lp, s);
- NOERR();
- }
- assert(*p != 0); /* at least two chars */
- assert(singleton(v->cm, *p));
- ch = *p++;
- co = GETCOLOR(v->cm, ch);
- assert(*p == 0); /* and only two, for now */
- newarc(v->nfa, PLAIN, co, s, rp);
- NOERR();
- }
-}
-
-/*
- - nextleader - find next MCCE leader within range
- ^ static celt nextleader(struct vars *, pchr, pchr);
- */
-static celt /* NOCELT means none */
-nextleader(v, from, to)
-struct vars *v;
-pchr from;
-pchr to;
-{
- int i;
- chr *p;
- chr ch;
- celt it = NOCELT;
-
- if (v->mcces == NULL)
- return it;
-
- for (i = v->mcces->nchrs, p = v->mcces->chrs; i > 0; i--, p++) {
- ch = *p;
- if (from <= ch && ch <= to)
- if (it == NOCELT || ch < it)
- it = ch;
- }
- return it;
}
-
+
/*
- wordchrs - set up word-chr list for word-boundary stuff, if needed
- * The list is kept as a bunch of arcs between two dummy states; it's
- * disposed of by the unreachable-states sweep in NFA optimization.
- * Does NEXT(). Must not be called from any unusual lexical context.
- * This should be reconciled with the \w etc. handling in lex.c, and
- * should be cleaned up to reduce dependencies on input scanning.
- ^ static VOID wordchrs(struct vars *);
+ * The list is kept as a bunch of arcs between two dummy states; it's disposed
+ * of by the unreachable-states sweep in NFA optimization. Does NEXT(). Must
+ * not be called from any unusual lexical context. This should be reconciled
+ * with the \w etc. handling in lex.c, and should be cleaned up to reduce
+ * dependencies on input scanning.
+ ^ static void wordchrs(struct vars *);
*/
-static VOID
-wordchrs(v)
-struct vars *v;
+static void
+wordchrs(
+ struct vars *v)
{
- struct state *left;
- struct state *right;
+ struct state *left, *right;
- if (v->wordchrs != NULL) {
- NEXT(); /* for consistency */
- return;
- }
+ if (v->wordchrs != NULL) {
+ NEXT(); /* for consistency */
+ return;
+ }
- left = newstate(v->nfa);
- right = newstate(v->nfa);
- NOERR();
- /* fine point: implemented with [::], and lexer will set REG_ULOCALE */
- lexword(v);
- NEXT();
- assert(v->savenow != NULL && SEE('['));
- bracket(v, left, right);
- assert((v->savenow != NULL && SEE(']')) || ISERR());
- NEXT();
- NOERR();
- v->wordchrs = left;
-}
+ left = newstate(v->nfa);
+ right = newstate(v->nfa);
+ NOERR();
+ /*
+ * Fine point: implemented with [::], and lexer will set REG_ULOCALE.
+ */
+
+ lexword(v);
+ NEXT();
+ assert(v->savenow != NULL && SEE('['));
+ bracket(v, left, right);
+ assert((v->savenow != NULL && SEE(']')) || ISERR());
+ NEXT();
+ NOERR();
+ v->wordchrs = left;
+}
+
/*
- subre - allocate a subre
^ static struct subre *subre(struct vars *, int, int, struct state *,
^ struct state *);
*/
static struct subre *
-subre(v, op, flags, begin, end)
-struct vars *v;
-int op;
-int flags;
-struct state *begin;
-struct state *end;
+subre(
+ struct vars *v,
+ int op,
+ int flags,
+ struct state *begin,
+ struct state *end)
{
- struct subre *ret;
-
- ret = v->treefree;
- if (ret != NULL)
- v->treefree = ret->left;
- else {
- ret = (struct subre *)MALLOC(sizeof(struct subre));
- if (ret == NULL) {
- ERR(REG_ESPACE);
- return NULL;
- }
- ret->chain = v->treechain;
- v->treechain = ret;
+ struct subre *ret = v->treefree;
+
+ if (ret != NULL) {
+ v->treefree = ret->left;
+ } else {
+ ret = (struct subre *) MALLOC(sizeof(struct subre));
+ if (ret == NULL) {
+ ERR(REG_ESPACE);
+ return NULL;
}
-
- assert(strchr("|.b(=", op) != NULL);
-
- ret->op = op;
- ret->flags = flags;
- ret->retry = 0;
- ret->subno = 0;
- ret->min = ret->max = 1;
- ret->left = NULL;
- ret->right = NULL;
- ret->begin = begin;
- ret->end = end;
- ZAPCNFA(ret->cnfa);
-
- return ret;
+ ret->chain = v->treechain;
+ v->treechain = ret;
+ }
+
+ assert(strchr("|.b(=", op) != NULL);
+
+ ret->op = op;
+ ret->flags = flags;
+ ret->retry = 0;
+ ret->subno = 0;
+ ret->min = ret->max = 1;
+ ret->left = NULL;
+ ret->right = NULL;
+ ret->begin = begin;
+ ret->end = end;
+ ZAPCNFA(ret->cnfa);
+
+ return ret;
}
-
+
/*
- freesubre - free a subRE subtree
- ^ static VOID freesubre(struct vars *, struct subre *);
+ ^ static void freesubre(struct vars *, struct subre *);
*/
-static VOID
-freesubre(v, sr)
-struct vars *v; /* might be NULL */
-struct subre *sr;
+static void
+freesubre(
+ struct vars *v, /* might be NULL */
+ struct subre *sr)
{
- if (sr == NULL)
- return;
-
- if (sr->left != NULL)
- freesubre(v, sr->left);
- if (sr->right != NULL)
- freesubre(v, sr->right);
-
- freesrnode(v, sr);
+ if (sr == NULL) {
+ return;
+ }
+
+ if (sr->left != NULL) {
+ freesubre(v, sr->left);
+ }
+ if (sr->right != NULL) {
+ freesubre(v, sr->right);
+ }
+
+ freesrnode(v, sr);
}
-
+
/*
- freesrnode - free one node in a subRE subtree
- ^ static VOID freesrnode(struct vars *, struct subre *);
+ ^ static void freesrnode(struct vars *, struct subre *);
*/
-static VOID
-freesrnode(v, sr)
-struct vars *v; /* might be NULL */
-struct subre *sr;
+static void
+freesrnode(
+ struct vars *v, /* might be NULL */
+ struct subre *sr)
{
- if (sr == NULL)
- return;
-
- if (!NULLCNFA(sr->cnfa))
- freecnfa(&sr->cnfa);
- sr->flags = 0;
-
- if (v != NULL) {
- sr->left = v->treefree;
- v->treefree = sr;
- } else
- FREE(sr);
+ if (sr == NULL) {
+ return;
+ }
+
+ if (!NULLCNFA(sr->cnfa)) {
+ freecnfa(&sr->cnfa);
+ }
+ sr->flags = 0;
+
+ if (v != NULL) {
+ sr->left = v->treefree;
+ v->treefree = sr;
+ } else {
+ FREE(sr);
+ }
}
-
+
/*
- optst - optimize a subRE subtree
- ^ static VOID optst(struct vars *, struct subre *);
+ ^ static void optst(struct vars *, struct subre *);
*/
-static VOID
-optst(v, t)
-struct vars *v;
-struct subre *t;
+static void
+optst(
+ struct vars *v,
+ struct subre *t)
{
/*
* DGP (2007-11-13): I assume it was the programmer's intent to eventually
* come back and add code to optimize subRE trees, but the routine coded
- * just spent effort traversing the tree and doing nothing. We can do
+ * just spends effort traversing the tree and doing nothing. We can do
* nothing with less effort.
*/
return;
}
-
+
/*
- numst - number tree nodes (assigning retry indexes)
^ static int numst(struct subre *, int);
*/
static int /* next number */
-numst(t, start)
-struct subre *t;
-int start; /* starting point for subtree numbers */
+numst(
+ struct subre *t,
+ int start) /* starting point for subtree numbers */
{
- int i;
-
- assert(t != NULL);
-
- i = start;
- t->retry = (short)i++;
- if (t->left != NULL)
- i = numst(t->left, i);
- if (t->right != NULL)
- i = numst(t->right, i);
- return i;
+ int i;
+
+ assert(t != NULL);
+
+ i = start;
+ t->retry = (short) i++;
+ if (t->left != NULL) {
+ i = numst(t->left, i);
+ }
+ if (t->right != NULL) {
+ i = numst(t->right, i);
+ }
+ return i;
}
-
+
/*
- markst - mark tree nodes as INUSE
- ^ static VOID markst(struct subre *);
+ ^ static void markst(struct subre *);
*/
-static VOID
-markst(t)
-struct subre *t;
+static void
+markst(
+ struct subre *t)
{
- assert(t != NULL);
-
- t->flags |= INUSE;
- if (t->left != NULL)
- markst(t->left);
- if (t->right != NULL)
- markst(t->right);
+ assert(t != NULL);
+
+ t->flags |= INUSE;
+ if (t->left != NULL) {
+ markst(t->left);
+ }
+ if (t->right != NULL) {
+ markst(t->right);
+ }
}
-
+
/*
- cleanst - free any tree nodes not marked INUSE
- ^ static VOID cleanst(struct vars *);
+ ^ static void cleanst(struct vars *);
*/
-static VOID
-cleanst(v)
-struct vars *v;
+static void
+cleanst(
+ struct vars *v)
{
- struct subre *t;
- struct subre *next;
+ struct subre *t;
+ struct subre *next;
- for (t = v->treechain; t != NULL; t = next) {
- next = t->chain;
- if (!(t->flags&INUSE))
- FREE(t);
+ for (t = v->treechain; t != NULL; t = next) {
+ next = t->chain;
+ if (!(t->flags&INUSE)) {
+ FREE(t);
}
- v->treechain = NULL;
- v->treefree = NULL; /* just on general principles */
+ }
+ v->treechain = NULL;
+ v->treefree = NULL; /* just on general principles */
}
-
+
/*
- nfatree - turn a subRE subtree into a tree of compacted NFAs
^ static long nfatree(struct vars *, struct subre *, FILE *);
*/
static long /* optimize results from top node */
-nfatree(v, t, f)
-struct vars *v;
-struct subre *t;
-FILE *f; /* for debug output */
+nfatree(
+ struct vars *v,
+ struct subre *t,
+ FILE *f) /* for debug output */
{
- assert(t != NULL && t->begin != NULL);
+ assert(t != NULL && t->begin != NULL);
- if (t->left != NULL)
- (DISCARD)nfatree(v, t->left, f);
- if (t->right != NULL)
- (DISCARD)nfatree(v, t->right, f);
+ if (t->left != NULL) {
+ (DISCARD) nfatree(v, t->left, f);
+ }
+ if (t->right != NULL) {
+ (DISCARD) nfatree(v, t->right, f);
+ }
- return nfanode(v, t, f);
+ return nfanode(v, t, f);
}
-
+
/*
- nfanode - do one NFA for nfatree
^ static long nfanode(struct vars *, struct subre *, FILE *);
*/
static long /* optimize results */
-nfanode(v, t, f)
-struct vars *v;
-struct subre *t;
-FILE *f; /* for debug output */
+nfanode(
+ struct vars *v,
+ struct subre *t,
+ FILE *f) /* for debug output */
{
- struct nfa *nfa;
- long ret = 0;
- char idbuf[50];
-
- assert(t->begin != NULL);
-
- if (f != NULL)
- fprintf(f, "\n\n\n========= TREE NODE %s ==========\n",
- stid(t, idbuf, sizeof(idbuf)));
- nfa = newnfa(v, v->cm, v->nfa);
- NOERRZ();
- dupnfa(nfa, t->begin, t->end, nfa->init, nfa->final);
- if (!ISERR()) {
- specialcolors(nfa);
- ret = optimize(nfa, f);
- }
- if (!ISERR())
- compact(nfa, &t->cnfa);
-
- freenfa(nfa);
- return ret;
+ struct nfa *nfa;
+ long ret = 0;
+ char idbuf[50];
+
+ assert(t->begin != NULL);
+
+ if (f != NULL) {
+ fprintf(f, "\n\n\n========= TREE NODE %s ==========\n",
+ stid(t, idbuf, sizeof(idbuf)));
+ }
+ nfa = newnfa(v, v->cm, v->nfa);
+ NOERRZ();
+ dupnfa(nfa, t->begin, t->end, nfa->init, nfa->final);
+ if (!ISERR()) {
+ specialcolors(nfa);
+ ret = optimize(nfa, f);
+ }
+ if (!ISERR()) {
+ compact(nfa, &t->cnfa);
+ }
+
+ freenfa(nfa);
+ return ret;
}
-
+
/*
- newlacon - allocate a lookahead-constraint subRE
^ static int newlacon(struct vars *, struct state *, struct state *, int);
*/
static int /* lacon number */
-newlacon(v, begin, end, pos)
-struct vars *v;
-struct state *begin;
-struct state *end;
-int pos;
+newlacon(
+ struct vars *v,
+ struct state *begin,
+ struct state *end,
+ int pos)
{
- int n;
- struct subre *sub;
-
- if (v->nlacons == 0) {
- v->lacons = (struct subre *)MALLOC(2 * sizeof(struct subre));
- n = 1; /* skip 0th */
- v->nlacons = 2;
- } else {
- v->lacons = (struct subre *)REALLOC(v->lacons,
- (v->nlacons+1)*sizeof(struct subre));
- n = v->nlacons++;
- }
- if (v->lacons == NULL) {
- ERR(REG_ESPACE);
- return 0;
- }
- sub = &v->lacons[n];
- sub->begin = begin;
- sub->end = end;
- sub->subno = pos;
- ZAPCNFA(sub->cnfa);
- return n;
+ struct subre *sub;
+ int n;
+
+ if (v->nlacons == 0) {
+ v->lacons = (struct subre *) MALLOC(2 * sizeof(struct subre));
+ n = 1; /* skip 0th */
+ v->nlacons = 2;
+ } else {
+ v->lacons = (struct subre *) REALLOC(v->lacons,
+ (v->nlacons+1)*sizeof(struct subre));
+ n = v->nlacons++;
+ }
+
+ if (v->lacons == NULL) {
+ ERR(REG_ESPACE);
+ return 0;
+ }
+
+ sub = &v->lacons[n];
+ sub->begin = begin;
+ sub->end = end;
+ sub->subno = pos;
+ ZAPCNFA(sub->cnfa);
+ return n;
}
-
+
/*
- freelacons - free lookahead-constraint subRE vector
- ^ static VOID freelacons(struct subre *, int);
+ ^ static void freelacons(struct subre *, int);
*/
-static VOID
-freelacons(subs, n)
-struct subre *subs;
-int n;
+static void
+freelacons(
+ struct subre *subs,
+ int n)
{
- struct subre *sub;
- int i;
-
- assert(n > 0);
- for (sub = subs + 1, i = n - 1; i > 0; sub++, i--) /* no 0th */
- if (!NULLCNFA(sub->cnfa))
- freecnfa(&sub->cnfa);
- FREE(subs);
-}
+ struct subre *sub;
+ int i;
+ assert(n > 0);
+ for (sub=subs+1, i=n-1; i>0; sub++, i--) { /* no 0th */
+ if (!NULLCNFA(sub->cnfa)) {
+ freecnfa(&sub->cnfa);
+ }
+ }
+ FREE(subs);
+}
+
/*
- rfree - free a whole RE (insides of regfree)
- ^ static VOID rfree(regex_t *);
+ ^ static void rfree(regex_t *);
*/
-static VOID
-rfree(re)
-regex_t *re;
+static void
+rfree(
+ regex_t *re)
{
- struct guts *g;
-
- if (re == NULL || re->re_magic != REMAGIC)
- return;
-
- re->re_magic = 0; /* invalidate RE */
- g = (struct guts *)re->re_guts;
- re->re_guts = NULL;
- re->re_fns = NULL;
- g->magic = 0;
- freecm(&g->cmap);
- if (g->tree != NULL)
- freesubre((struct vars *)NULL, g->tree);
- if (g->lacons != NULL)
- freelacons(g->lacons, g->nlacons);
- if (!NULLCNFA(g->search))
- freecnfa(&g->search);
- FREE(g);
+ struct guts *g;
+
+ if (re == NULL || re->re_magic != REMAGIC) {
+ return;
+ }
+
+ re->re_magic = 0; /* invalidate RE */
+ g = (struct guts *) re->re_guts;
+ re->re_guts = NULL;
+ re->re_fns = NULL;
+ g->magic = 0;
+ freecm(&g->cmap);
+ if (g->tree != NULL) {
+ freesubre(NULL, g->tree);
+ }
+ if (g->lacons != NULL) {
+ freelacons(g->lacons, g->nlacons);
+ }
+ if (!NULLCNFA(g->search)) {
+ freecnfa(&g->search);
+ }
+ FREE(g);
}
-
+
/*
- dump - dump an RE in human-readable form
- ^ static VOID dump(regex_t *, FILE *);
+ ^ static void dump(regex_t *, FILE *);
*/
-static VOID
-dump(re, f)
-regex_t *re;
-FILE *f;
+static void
+dump(
+ regex_t *re,
+ FILE *f)
{
#ifdef REG_DEBUG
- struct guts *g;
- int i;
-
- if (re->re_magic != REMAGIC)
- fprintf(f, "bad magic number (0x%x not 0x%x)\n", re->re_magic,
- REMAGIC);
- if (re->re_guts == NULL) {
- fprintf(f, "NULL guts!!!\n");
- return;
- }
- g = (struct guts *)re->re_guts;
- if (g->magic != GUTSMAGIC)
- fprintf(f, "bad guts magic number (0x%x not 0x%x)\n", g->magic,
- GUTSMAGIC);
-
- fprintf(f, "\n\n\n========= DUMP ==========\n");
- fprintf(f, "nsub %d, info 0%lo, csize %d, ntree %d\n",
- re->re_nsub, re->re_info, re->re_csize, g->ntree);
-
- dumpcolors(&g->cmap, f);
- if (!NULLCNFA(g->search)) {
- printf("\nsearch:\n");
- dumpcnfa(&g->search, f);
- }
- for (i = 1; i < g->nlacons; i++) {
- fprintf(f, "\nla%d (%s):\n", i,
- (g->lacons[i].subno) ? "positive" : "negative");
- dumpcnfa(&g->lacons[i].cnfa, f);
- }
- fprintf(f, "\n");
- dumpst(g->tree, f, 0);
+ struct guts *g;
+ int i;
+
+ if (re->re_magic != REMAGIC) {
+ fprintf(f, "bad magic number (0x%x not 0x%x)\n",
+ re->re_magic, REMAGIC);
+ }
+ if (re->re_guts == NULL) {
+ fprintf(f, "NULL guts!!!\n");
+ return;
+ }
+ g = (struct guts *) re->re_guts;
+ if (g->magic != GUTSMAGIC) {
+ fprintf(f, "bad guts magic number (0x%x not 0x%x)\n",
+ g->magic, GUTSMAGIC);
+ }
+
+ fprintf(f, "\n\n\n========= DUMP ==========\n");
+ fprintf(f, "nsub %d, info 0%lo, csize %d, ntree %d\n",
+ re->re_nsub, re->re_info, re->re_csize, g->ntree);
+
+ dumpcolors(&g->cmap, f);
+ if (!NULLCNFA(g->search)) {
+ printf("\nsearch:\n");
+ dumpcnfa(&g->search, f);
+ }
+ for (i = 1; i < g->nlacons; i++) {
+ fprintf(f, "\nla%d (%s):\n", i,
+ (g->lacons[i].subno) ? "positive" : "negative");
+ dumpcnfa(&g->lacons[i].cnfa, f);
+ }
+ fprintf(f, "\n");
+ dumpst(g->tree, f, 0);
#endif
}
-
+
/*
- dumpst - dump a subRE tree
- ^ static VOID dumpst(struct subre *, FILE *, int);
+ ^ static void dumpst(struct subre *, FILE *, int);
*/
-static VOID
-dumpst(t, f, nfapresent)
-struct subre *t;
-FILE *f;
-int nfapresent; /* is the original NFA still around? */
+static void
+dumpst(
+ struct subre *t,
+ FILE *f,
+ int nfapresent) /* is the original NFA still around? */
{
- if (t == NULL)
- fprintf(f, "null tree\n");
- else
- stdump(t, f, nfapresent);
- fflush(f);
+ if (t == NULL) {
+ fprintf(f, "null tree\n");
+ } else {
+ stdump(t, f, nfapresent);
+ }
+ fflush(f);
}
-
+
/*
- stdump - recursive guts of dumpst
- ^ static VOID stdump(struct subre *, FILE *, int);
+ ^ static void stdump(struct subre *, FILE *, int);
*/
-static VOID
-stdump(t, f, nfapresent)
-struct subre *t;
-FILE *f;
-int nfapresent; /* is the original NFA still around? */
+static void
+stdump(
+ struct subre *t,
+ FILE *f,
+ int nfapresent) /* is the original NFA still around? */
{
- char idbuf[50];
-
- fprintf(f, "%s. `%c'", stid(t, idbuf, sizeof(idbuf)), t->op);
- if (t->flags&LONGER)
- fprintf(f, " longest");
- if (t->flags&SHORTER)
- fprintf(f, " shortest");
- if (t->flags&MIXED)
- fprintf(f, " hasmixed");
- if (t->flags&CAP)
- fprintf(f, " hascapture");
- if (t->flags&BACKR)
- fprintf(f, " hasbackref");
- if (!(t->flags&INUSE))
- fprintf(f, " UNUSED");
- if (t->subno != 0)
- fprintf(f, " (#%d)", t->subno);
- if (t->min != 1 || t->max != 1) {
- fprintf(f, " {%d,", t->min);
- if (t->max != INFINITY)
- fprintf(f, "%d", t->max);
- fprintf(f, "}");
- }
- if (nfapresent)
- fprintf(f, " %ld-%ld", (long)t->begin->no, (long)t->end->no);
- if (t->left != NULL)
- fprintf(f, " L:%s", stid(t->left, idbuf, sizeof(idbuf)));
- if (t->right != NULL)
- fprintf(f, " R:%s", stid(t->right, idbuf, sizeof(idbuf)));
- if (!NULLCNFA(t->cnfa)) {
- fprintf(f, "\n");
- dumpcnfa(&t->cnfa, f);
+ char idbuf[50];
+
+ fprintf(f, "%s. `%c'", stid(t, idbuf, sizeof(idbuf)), t->op);
+ if (t->flags&LONGER) {
+ fprintf(f, " longest");
+ }
+ if (t->flags&SHORTER) {
+ fprintf(f, " shortest");
+ }
+ if (t->flags&MIXED) {
+ fprintf(f, " hasmixed");
+ }
+ if (t->flags&CAP) {
+ fprintf(f, " hascapture");
+ }
+ if (t->flags&BACKR) {
+ fprintf(f, " hasbackref");
+ }
+ if (!(t->flags&INUSE)) {
+ fprintf(f, " UNUSED");
+ }
+ if (t->subno != 0) {
+ fprintf(f, " (#%d)", t->subno);
+ }
+ if (t->min != 1 || t->max != 1) {
+ fprintf(f, " {%d,", t->min);
+ if (t->max != INFINITY) {
+ fprintf(f, "%d", t->max);
}
+ fprintf(f, "}");
+ }
+ if (nfapresent) {
+ fprintf(f, " %ld-%ld", (long)t->begin->no, (long)t->end->no);
+ }
+ if (t->left != NULL) {
+ fprintf(f, " L:%s", stid(t->left, idbuf, sizeof(idbuf)));
+ }
+ if (t->right != NULL) {
+ fprintf(f, " R:%s", stid(t->right, idbuf, sizeof(idbuf)));
+ }
+ if (!NULLCNFA(t->cnfa)) {
fprintf(f, "\n");
- if (t->left != NULL)
- stdump(t->left, f, nfapresent);
- if (t->right != NULL)
- stdump(t->right, f, nfapresent);
+ dumpcnfa(&t->cnfa, f);
+ }
+ fprintf(f, "\n");
+ if (t->left != NULL) {
+ stdump(t->left, f, nfapresent);
+ }
+ if (t->right != NULL) {
+ stdump(t->right, f, nfapresent);
+ }
}
-
+
/*
- stid - identify a subtree node for dumping
- ^ static char *stid(struct subre *, char *, size_t);
+ ^ static const char *stid(struct subre *, char *, size_t);
*/
-static char * /* points to buf or constant string */
-stid(t, buf, bufsize)
-struct subre *t;
-char *buf;
-size_t bufsize;
+static const char * /* points to buf or constant string */
+stid(
+ struct subre *t,
+ char *buf,
+ size_t bufsize)
{
- /* big enough for hex int or decimal t->retry? */
- if (bufsize < sizeof(void*)*2 + 3 || bufsize < sizeof(t->retry)*3 + 1)
- return "unable";
- if (t->retry != 0)
- sprintf(buf, "%d", t->retry);
- else
- sprintf(buf, "%p", t);
- return buf;
+ /*
+ * Big enough for hex int or decimal t->retry?
+ */
+
+ if (bufsize < sizeof(void*)*2 + 3 || bufsize < sizeof(t->retry)*3 + 1) {
+ return "unable";
+ }
+ if (t->retry != 0) {
+ sprintf(buf, "%d", t->retry);
+ } else {
+ sprintf(buf, "%p", t);
+ }
+ return buf;
}
#include "regc_lex.c"
@@ -2108,3 +2159,11 @@ size_t bufsize;
#include "regc_nfa.c"
#include "regc_cvec.c"
#include "regc_locale.c"
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regcustom.h b/generic/regcustom.h
index 5b6815c..57a2d47 100644
--- a/generic/regcustom.h
+++ b/generic/regcustom.h
@@ -1,22 +1,22 @@
/*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
- *
+ *
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
- * Corporation, none of whom are responsible for the results. The author
- * thanks all of them.
- *
- * Redistribution and use in source and binary forms -- with or without
- * modification -- are permitted for any purpose, provided that
- * redistributions in source form retain this entire copyright notice and
- * indicate the origin and nature of any modifications.
- *
- * I'd appreciate being given credit for this package in the documentation
- * of software which uses it, but that is not a requirement.
- *
+ * Corporation, none of whom are responsible for the results. The author
+ * thanks all of them.
+ *
+ * Redistribution and use in source and binary forms - with or without
+ * modification - are permitted for any purpose, provided that redistributions
+ * in source form retain this entire copyright notice and indicate the origin
+ * and nature of any modifications.
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
@@ -26,23 +26,28 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* headers if any */
+/*
+ * Headers if any.
+ */
+
#include "tclInt.h"
-/* overrides for regguts.h definitions, if any */
-#define FUNCPTR(name, args) (*name) _ANSI_ARGS_(args)
+/*
+ * Overrides for regguts.h definitions, if any.
+ */
+
+#define FUNCPTR(name, args) (*name)args
#define MALLOC(n) ckalloc(n)
#define FREE(p) ckfree(VS(p))
#define REALLOC(p,n) ckrealloc(VS(p),n)
-
-
/*
- * Do not insert extras between the "begin" and "end" lines -- this
- * chunk is automatically extracted to be fitted into regex.h.
+ * Do not insert extras between the "begin" and "end" lines - this chunk is
+ * automatically extracted to be fitted into regex.h.
*/
+
/* --- begin --- */
-/* ensure certain things don't sneak in from system headers */
+/* Ensure certain things don't sneak in from system headers. */
#ifdef __REG_WIDE_T
#undef __REG_WIDE_T
#endif
@@ -67,54 +72,90 @@
#ifdef __REG_NOCHAR
#undef __REG_NOCHAR
#endif
-/* interface types */
+/* Interface types */
#define __REG_WIDE_T Tcl_UniChar
-#define __REG_REGOFF_T long /* not really right, but good enough... */
-#define __REG_VOID_T VOID
-#define __REG_CONST CONST
-/* names and declarations */
+#define __REG_REGOFF_T long /* Not really right, but good enough... */
+#define __REG_VOID_T void
+#define __REG_CONST const
+/* Names and declarations */
#define __REG_WIDE_COMPILE TclReComp
#define __REG_WIDE_EXEC TclReExec
-#define __REG_NOFRONT /* don't want regcomp() and regexec() */
-#define __REG_NOCHAR /* or the char versions */
+#define __REG_NOFRONT /* Don't want regcomp() and regexec() */
+#define __REG_NOCHAR /* Or the char versions */
#define regfree TclReFree
#define regerror TclReError
/* --- end --- */
+/*
+ * Internal character type and related.
+ */
-
-/* internal character type and related */
-typedef Tcl_UniChar chr; /* the type itself */
-typedef int pchr; /* what it promotes to */
-typedef unsigned uchr; /* unsigned type that will hold a chr */
-typedef int celt; /* type to hold chr, MCCE number, or NOCELT */
-#define NOCELT (-1) /* celt value which is not valid chr or MCCE */
-#define CHR(c) (UCHAR(c)) /* turn char literal into chr literal */
-#define DIGITVAL(c) ((c)-'0') /* turn chr digit into its value */
+typedef Tcl_UniChar chr; /* The type itself. */
+typedef int pchr; /* What it promotes to. */
+typedef unsigned uchr; /* Unsigned type that will hold a chr. */
+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 > 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 */
+#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 */
#else
-#define CHRBITS 16 /* bits in a chr; must not use sizeof */
-#define CHR_MIN 0x0000 /* smallest and largest chr; the value */
-#define CHR_MAX 0xffff /* CHR_MAX-CHR_MIN+1 should fit in uchr */
+#define CHRBITS 16 /* Bits in a chr; must not use sizeof */
+#define CHR_MIN 0x0000 /* Smallest and largest chr; the value */
+#define CHR_MAX 0xffff /* CHR_MAX-CHR_MIN+1 should fit in uchr */
#endif
-/* functions operating on chr */
+/*
+ * Functions operating on chr.
+ */
+
#define iscalnum(x) Tcl_UniCharIsAlnum(x)
#define iscalpha(x) Tcl_UniCharIsAlpha(x)
#define iscdigit(x) Tcl_UniCharIsDigit(x)
#define iscspace(x) Tcl_UniCharIsSpace(x)
-/* name the external functions */
+/*
+ * Name the external functions.
+ */
+
#define compile TclReComp
#define exec TclReExec
-/* enable/disable debugging code (by whether REG_DEBUG is defined or not) */
-#if 0 /* no debug unless requested by makefile */
+/*
+& Enable/disable debugging code (by whether REG_DEBUG is defined or not).
+*/
+
+#if 0 /* No debug unless requested by makefile. */
#define REG_DEBUG /* */
#endif
-/* and pick up the standard header */
+/*
+ * Method of allocating a local workspace. We used a thread-specific data
+ * space to store this because the regular expression engine is never
+ * reentered from the same thread; it doesn't make any callbacks.
+ */
+
+#if 1
+#define AllocVars(vPtr) \
+ static Tcl_ThreadDataKey varsKey; \
+ register struct vars *vPtr = (struct vars *) \
+ Tcl_GetThreadData(&varsKey, sizeof(struct vars))
+#else
+/*
+ * This strategy for allocating workspace is "more proper" in some sense, but
+ * quite a bit slower. Using TSD (as above) leads to code that is quite a bit
+ * faster in practice (measured!)
+ */
+#define AllocVars(vPtr) \
+ register struct vars *vPtr = (struct vars *) MALLOC(sizeof(struct vars))
+#define FreeVars(vPtr) \
+ FREE(vPtr)
+#endif
+
+/*
+ * And pick up the standard header.
+ */
+
#include "regex.h"
diff --git a/generic/rege_dfa.c b/generic/rege_dfa.c
index bc391fd..e233680 100644
--- a/generic/rege_dfa.c
+++ b/generic/rege_dfa.c
@@ -3,20 +3,20 @@
* This file is #included by regexec.c.
*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
- *
+ *
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author
- * thanks all of them.
- *
+ * thanks all of them.
+ *
* Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
- *
+ *
* I'd appreciate being given credit for this package in the documentation
* of software which uses it, but that is not a requirement.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -29,521 +29,620 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-
+
/*
- longest - longest-preferred matching engine
^ static chr *longest(struct vars *, struct dfa *, chr *, chr *, int *);
*/
static chr * /* endpoint, or NULL */
-longest(v, d, start, stop, hitstopp)
-struct vars *v; /* used only for debug and exec flags */
-struct dfa *d;
-chr *start; /* where the match should start */
-chr *stop; /* match must end at or before here */
-int *hitstopp; /* record whether hit v->stop, if non-NULL */
+longest(
+ struct vars *v, /* used only for debug and exec flags */
+ struct dfa *d,
+ chr *start, /* where the match should start */
+ chr *stop, /* match must end at or before here */
+ int *hitstopp) /* record whether hit v->stop, if non-NULL */
{
- chr *cp;
- chr *realstop = (stop == v->stop) ? stop : stop + 1;
- color co;
- struct sset *css;
- struct sset *ss;
- chr *post;
- int i;
- struct colormap *cm = d->cm;
-
- /* initialize */
- css = initialize(v, d, start);
- cp = start;
- if (hitstopp != NULL)
- *hitstopp = 0;
-
- /* startup */
- FDEBUG(("+++ startup +++\n"));
- if (cp == v->start) {
- co = d->cnfa->bos[(v->eflags&REG_NOTBOL) ? 0 : 1];
- FDEBUG(("color %ld\n", (long)co));
- } else {
- co = GETCOLOR(cm, *(cp - 1));
- FDEBUG(("char %c, color %ld\n", (char)*(cp-1), (long)co));
- }
- css = miss(v, d, css, co, cp, start);
- if (css == NULL)
- return NULL;
- css->lastseen = cp;
-
- /* main loop */
- if (v->eflags&REG_FTRACE)
- while (cp < realstop) {
- FDEBUG(("+++ at c%d +++\n", css - d->ssets));
- co = GETCOLOR(cm, *cp);
- FDEBUG(("char %c, color %ld\n", (char)*cp, (long)co));
- ss = css->outs[co];
- if (ss == NULL) {
- ss = miss(v, d, css, co, cp+1, start);
- if (ss == NULL)
- break; /* NOTE BREAK OUT */
- }
- cp++;
- ss->lastseen = cp;
- css = ss;
+ chr *cp;
+ chr *realstop = (stop == v->stop) ? stop : stop + 1;
+ color co;
+ struct sset *css;
+ struct sset *ss;
+ chr *post;
+ int i;
+ struct colormap *cm = d->cm;
+
+ /*
+ * Initialize.
+ */
+
+ css = initialize(v, d, start);
+ cp = start;
+ if (hitstopp != NULL) {
+ *hitstopp = 0;
+ }
+
+ /*
+ * Startup.
+ */
+
+ FDEBUG(("+++ startup +++\n"));
+ if (cp == v->start) {
+ co = d->cnfa->bos[(v->eflags&REG_NOTBOL) ? 0 : 1];
+ FDEBUG(("color %ld\n", (long)co));
+ } else {
+ co = GETCOLOR(cm, *(cp - 1));
+ FDEBUG(("char %c, color %ld\n", (char)*(cp-1), (long)co));
+ }
+ css = miss(v, d, css, co, cp, start);
+ if (css == NULL) {
+ return NULL;
+ }
+ css->lastseen = cp;
+
+ /*
+ * Main loop.
+ */
+
+ if (v->eflags&REG_FTRACE) {
+ while (cp < realstop) {
+ FDEBUG(("+++ at c%d +++\n", css - d->ssets));
+ co = GETCOLOR(cm, *cp);
+ FDEBUG(("char %c, color %ld\n", (char)*cp, (long)co));
+ ss = css->outs[co];
+ if (ss == NULL) {
+ ss = miss(v, d, css, co, cp+1, start);
+ if (ss == NULL) {
+ break; /* NOTE BREAK OUT */
}
- else
- while (cp < realstop) {
- co = GETCOLOR(cm, *cp);
- ss = css->outs[co];
- if (ss == NULL) {
- ss = miss(v, d, css, co, cp+1, start);
- if (ss == NULL)
- break; /* NOTE BREAK OUT */
- }
- cp++;
- ss->lastseen = cp;
- css = ss;
+ }
+ cp++;
+ ss->lastseen = cp;
+ css = ss;
+ }
+ } else {
+ while (cp < realstop) {
+ co = GETCOLOR(cm, *cp);
+ ss = css->outs[co];
+ if (ss == NULL) {
+ ss = miss(v, d, css, co, cp+1, start);
+ if (ss == NULL) {
+ break; /* NOTE BREAK OUT */
}
+ }
+ cp++;
+ ss->lastseen = cp;
+ css = ss;
+ }
+ }
- /* shutdown */
- FDEBUG(("+++ shutdown at c%d +++\n", css - d->ssets));
- if (cp == v->stop && stop == v->stop) {
- if (hitstopp != NULL)
- *hitstopp = 1;
- co = d->cnfa->eos[(v->eflags&REG_NOTEOL) ? 0 : 1];
- FDEBUG(("color %ld\n", (long)co));
- ss = miss(v, d, css, co, cp, start);
- /* special case: match ended at eol? */
- if (ss != NULL && (ss->flags&POSTSTATE))
- return cp;
- else if (ss != NULL)
- ss->lastseen = cp; /* to be tidy */
+ /*
+ * Shutdown.
+ */
+
+ FDEBUG(("+++ shutdown at c%d +++\n", css - d->ssets));
+ if (cp == v->stop && stop == v->stop) {
+ if (hitstopp != NULL) {
+ *hitstopp = 1;
+ }
+ co = d->cnfa->eos[(v->eflags&REG_NOTEOL) ? 0 : 1];
+ FDEBUG(("color %ld\n", (long)co));
+ ss = miss(v, d, css, co, cp, start);
+
+ /*
+ * Special case: match ended at eol?
+ */
+
+ if (ss != NULL && (ss->flags&POSTSTATE)) {
+ return cp;
+ } else if (ss != NULL) {
+ ss->lastseen = cp; /* to be tidy */
}
+ }
- /* find last match, if any */
- post = d->lastpost;
- for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--)
- if ((ss->flags&POSTSTATE) && post != ss->lastseen &&
- (post == NULL || post < ss->lastseen))
- post = ss->lastseen;
- if (post != NULL) /* found one */
- return post - 1;
+ /*
+ * Find last match, if any.
+ */
- return NULL;
-}
+ post = d->lastpost;
+ for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--) {
+ if ((ss->flags&POSTSTATE) && (post != ss->lastseen) &&
+ (post == NULL || post < ss->lastseen)) {
+ post = ss->lastseen;
+ }
+ }
+ if (post != NULL) { /* found one */
+ return post - 1;
+ }
+ return NULL;
+}
+
/*
- shortest - shortest-preferred matching engine
^ static chr *shortest(struct vars *, struct dfa *, chr *, chr *, chr *,
^ chr **, int *);
*/
static chr * /* endpoint, or NULL */
-shortest(v, d, start, min, max, coldp, hitstopp)
-struct vars *v;
-struct dfa *d;
-chr *start; /* where the match should start */
-chr *min; /* match must end at or after here */
-chr *max; /* match must end at or before here */
-chr **coldp; /* store coldstart pointer here, if nonNULL */
-int *hitstopp; /* record whether hit v->stop, if non-NULL */
+shortest(
+ struct vars *v,
+ struct dfa *d,
+ chr *start, /* where the match should start */
+ chr *min, /* match must end at or after here */
+ chr *max, /* match must end at or before here */
+ chr **coldp, /* store coldstart pointer here, if nonNULL */
+ int *hitstopp) /* record whether hit v->stop, if non-NULL */
{
- chr *cp;
- chr *realmin = (min == v->stop) ? min : min + 1;
- chr *realmax = (max == v->stop) ? max : max + 1;
- color co;
- struct sset *css;
- struct sset *ss;
- struct colormap *cm = d->cm;
-
- /* initialize */
- css = initialize(v, d, start);
- cp = start;
- if (hitstopp != NULL)
- *hitstopp = 0;
-
- /* startup */
- FDEBUG(("--- startup ---\n"));
- if (cp == v->start) {
- co = d->cnfa->bos[(v->eflags&REG_NOTBOL) ? 0 : 1];
- FDEBUG(("color %ld\n", (long)co));
- } else {
- co = GETCOLOR(cm, *(cp - 1));
- FDEBUG(("char %c, color %ld\n", (char)*(cp-1), (long)co));
- }
- css = miss(v, d, css, co, cp, start);
- if (css == NULL)
- return NULL;
- css->lastseen = cp;
- ss = css;
-
- /* main loop */
- if (v->eflags&REG_FTRACE)
- while (cp < realmax) {
- FDEBUG(("--- at c%d ---\n", css - d->ssets));
- co = GETCOLOR(cm, *cp);
- FDEBUG(("char %c, color %ld\n", (char)*cp, (long)co));
- ss = css->outs[co];
- if (ss == NULL) {
- ss = miss(v, d, css, co, cp+1, start);
- if (ss == NULL)
- break; /* NOTE BREAK OUT */
- }
- cp++;
- ss->lastseen = cp;
- css = ss;
- if ((ss->flags&POSTSTATE) && cp >= realmin)
- break; /* NOTE BREAK OUT */
+ chr *cp;
+ chr *realmin = (min == v->stop) ? min : min + 1;
+ chr *realmax = (max == v->stop) ? max : max + 1;
+ color co;
+ struct sset *css;
+ struct sset *ss;
+ struct colormap *cm = d->cm;
+
+ /*
+ * Initialize.
+ */
+
+ css = initialize(v, d, start);
+ cp = start;
+ if (hitstopp != NULL) {
+ *hitstopp = 0;
+ }
+
+ /*
+ * Startup.
+ */
+
+ FDEBUG(("--- startup ---\n"));
+ if (cp == v->start) {
+ co = d->cnfa->bos[(v->eflags&REG_NOTBOL) ? 0 : 1];
+ FDEBUG(("color %ld\n", (long)co));
+ } else {
+ co = GETCOLOR(cm, *(cp - 1));
+ FDEBUG(("char %c, color %ld\n", (char)*(cp-1), (long)co));
+ }
+ css = miss(v, d, css, co, cp, start);
+ if (css == NULL) {
+ return NULL;
+ }
+ css->lastseen = cp;
+ ss = css;
+
+ /*
+ * Main loop.
+ */
+
+ if (v->eflags&REG_FTRACE) {
+ while (cp < realmax) {
+ FDEBUG(("--- at c%d ---\n", css - d->ssets));
+ co = GETCOLOR(cm, *cp);
+ FDEBUG(("char %c, color %ld\n", (char)*cp, (long)co));
+ ss = css->outs[co];
+ if (ss == NULL) {
+ ss = miss(v, d, css, co, cp+1, start);
+ if (ss == NULL) {
+ break; /* NOTE BREAK OUT */
}
- else
- while (cp < realmax) {
- co = GETCOLOR(cm, *cp);
- ss = css->outs[co];
- if (ss == NULL) {
- ss = miss(v, d, css, co, cp+1, start);
- if (ss == NULL)
- break; /* NOTE BREAK OUT */
- }
- cp++;
- ss->lastseen = cp;
- css = ss;
- if ((ss->flags&POSTSTATE) && cp >= realmin)
- break; /* NOTE BREAK OUT */
+ }
+ cp++;
+ ss->lastseen = cp;
+ css = ss;
+ if ((ss->flags&POSTSTATE) && cp >= realmin) {
+ break; /* NOTE BREAK OUT */
+ }
+ }
+ } else {
+ while (cp < realmax) {
+ co = GETCOLOR(cm, *cp);
+ ss = css->outs[co];
+ if (ss == NULL) {
+ ss = miss(v, d, css, co, cp+1, start);
+ if (ss == NULL) {
+ break; /* NOTE BREAK OUT */
}
+ }
+ cp++;
+ ss->lastseen = cp;
+ css = ss;
+ if ((ss->flags&POSTSTATE) && cp >= realmin) {
+ break; /* NOTE BREAK OUT */
+ }
+ }
+ }
- if (ss == NULL)
- return NULL;
-
- if (coldp != NULL) /* report last no-progress state set, if any */
- *coldp = lastcold(v, d);
-
- if ((ss->flags&POSTSTATE) && cp > min) {
- assert(cp >= realmin);
- cp--;
- } else if (cp == v->stop && max == v->stop) {
- co = d->cnfa->eos[(v->eflags&REG_NOTEOL) ? 0 : 1];
- FDEBUG(("color %ld\n", (long)co));
- ss = miss(v, d, css, co, cp, start);
- /* match might have ended at eol */
- if ((ss == NULL || !(ss->flags&POSTSTATE)) && hitstopp != NULL)
- *hitstopp = 1;
+ if (ss == NULL) {
+ return NULL;
+ }
+
+ if (coldp != NULL) { /* report last no-progress state set, if any */
+ *coldp = lastcold(v, d);
+ }
+
+ if ((ss->flags&POSTSTATE) && cp > min) {
+ assert(cp >= realmin);
+ cp--;
+ } else if (cp == v->stop && max == v->stop) {
+ co = d->cnfa->eos[(v->eflags&REG_NOTEOL) ? 0 : 1];
+ FDEBUG(("color %ld\n", (long)co));
+ ss = miss(v, d, css, co, cp, start);
+
+ /*
+ * Match might have ended at eol.
+ */
+
+ if ((ss == NULL || !(ss->flags&POSTSTATE)) && hitstopp != NULL) {
+ *hitstopp = 1;
}
+ }
- if (ss == NULL || !(ss->flags&POSTSTATE))
- return NULL;
+ if (ss == NULL || !(ss->flags&POSTSTATE)) {
+ return NULL;
+ }
- return cp;
+ return cp;
}
-
+
/*
- lastcold - determine last point at which no progress had been made
^ static chr *lastcold(struct vars *, struct dfa *);
*/
static chr * /* endpoint, or NULL */
-lastcold(v, d)
-struct vars *v;
-struct dfa *d;
+lastcold(
+ struct vars *v,
+ struct dfa *d)
{
- struct sset *ss;
- chr *nopr;
- int i;
-
- nopr = d->lastnopr;
- if (nopr == NULL)
- nopr = v->start;
- for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--)
- if ((ss->flags&NOPROGRESS) && nopr < ss->lastseen)
- nopr = ss->lastseen;
- return nopr;
+ struct sset *ss;
+ chr *nopr;
+ int i;
+
+ nopr = d->lastnopr;
+ if (nopr == NULL) {
+ nopr = v->start;
+ }
+ for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--) {
+ if ((ss->flags&NOPROGRESS) && nopr < ss->lastseen) {
+ nopr = ss->lastseen;
+ }
+ }
+ return nopr;
}
-
+
/*
- newdfa - set up a fresh DFA
^ static struct dfa *newdfa(struct vars *, struct cnfa *,
^ struct colormap *, struct smalldfa *);
*/
static struct dfa *
-newdfa(v, cnfa, cm, small)
-struct vars *v;
-struct cnfa *cnfa;
-struct colormap *cm;
-struct smalldfa *small; /* preallocated space, may be NULL */
+newdfa(
+ struct vars *v,
+ struct cnfa *cnfa,
+ struct colormap *cm,
+ struct smalldfa *sml) /* preallocated space, may be NULL */
{
- struct dfa *d;
- size_t nss = cnfa->nstates * 2;
- int wordsper = (cnfa->nstates + UBITS - 1) / UBITS;
- struct smalldfa *smallwas = small;
-
- assert(cnfa != NULL && cnfa->nstates != 0);
-
- if (nss <= FEWSTATES && cnfa->ncolors <= FEWCOLORS) {
- assert(wordsper == 1);
- if (small == NULL) {
- small = (struct smalldfa *)MALLOC(
- sizeof(struct smalldfa));
- if (small == NULL) {
- ERR(REG_ESPACE);
- return NULL;
- }
- }
- d = &small->dfa;
- d->ssets = small->ssets;
- d->statesarea = small->statesarea;
- d->work = &d->statesarea[nss];
- d->outsarea = small->outsarea;
- d->incarea = small->incarea;
- d->cptsmalloced = 0;
- d->mallocarea = (smallwas == NULL) ? (char *)small : NULL;
- } else {
- d = (struct dfa *)MALLOC(sizeof(struct dfa));
- if (d == NULL) {
- ERR(REG_ESPACE);
- return NULL;
- }
- d->ssets = (struct sset *)MALLOC(nss * sizeof(struct sset));
- d->statesarea = (unsigned *)MALLOC((nss+WORK) * wordsper *
- sizeof(unsigned));
- d->work = &d->statesarea[nss * wordsper];
- d->outsarea = (struct sset **)MALLOC(nss * cnfa->ncolors *
- sizeof(struct sset *));
- d->incarea = (struct arcp *)MALLOC(nss * cnfa->ncolors *
- sizeof(struct arcp));
- d->cptsmalloced = 1;
- d->mallocarea = (char *)d;
- if (d->ssets == NULL || d->statesarea == NULL ||
- d->outsarea == NULL || d->incarea == NULL) {
- freedfa(d);
- ERR(REG_ESPACE);
- return NULL;
- }
+ struct dfa *d;
+ size_t nss = cnfa->nstates * 2;
+ int wordsper = (cnfa->nstates + UBITS - 1) / UBITS;
+ struct smalldfa *smallwas = sml;
+
+ assert(cnfa != NULL && cnfa->nstates != 0);
+
+ if (nss <= FEWSTATES && cnfa->ncolors <= FEWCOLORS) {
+ assert(wordsper == 1);
+ if (sml == NULL) {
+ sml = (struct smalldfa *) MALLOC(sizeof(struct smalldfa));
+ if (sml == NULL) {
+ ERR(REG_ESPACE);
+ return NULL;
+ }
}
-
- d->nssets = (v->eflags&REG_SMALL) ? 7 : nss;
- d->nssused = 0;
- d->nstates = cnfa->nstates;
- d->ncolors = cnfa->ncolors;
- d->wordsper = wordsper;
- d->cnfa = cnfa;
- d->cm = cm;
- d->lastpost = NULL;
- d->lastnopr = NULL;
- d->search = d->ssets;
-
- /* initialization of sset fields is done as needed */
-
- return d;
+ d = &sml->dfa;
+ d->ssets = sml->ssets;
+ d->statesarea = sml->statesarea;
+ d->work = &d->statesarea[nss];
+ d->outsarea = sml->outsarea;
+ d->incarea = sml->incarea;
+ d->cptsmalloced = 0;
+ d->mallocarea = (smallwas == NULL) ? (char *)sml : NULL;
+ } else {
+ d = (struct dfa *)MALLOC(sizeof(struct dfa));
+ if (d == NULL) {
+ ERR(REG_ESPACE);
+ return NULL;
+ }
+ d->ssets = (struct sset *)MALLOC(nss * sizeof(struct sset));
+ d->statesarea = (unsigned *)
+ MALLOC((nss+WORK) * wordsper * sizeof(unsigned));
+ d->work = &d->statesarea[nss * wordsper];
+ d->outsarea = (struct sset **)
+ MALLOC(nss * cnfa->ncolors * sizeof(struct sset *));
+ d->incarea = (struct arcp *)
+ MALLOC(nss * cnfa->ncolors * sizeof(struct arcp));
+ d->cptsmalloced = 1;
+ d->mallocarea = (char *)d;
+ if (d->ssets == NULL || d->statesarea == NULL ||
+ d->outsarea == NULL || d->incarea == NULL) {
+ freedfa(d);
+ ERR(REG_ESPACE);
+ return NULL;
+ }
+ }
+
+ d->nssets = (v->eflags&REG_SMALL) ? 7 : nss;
+ d->nssused = 0;
+ d->nstates = cnfa->nstates;
+ d->ncolors = cnfa->ncolors;
+ d->wordsper = wordsper;
+ d->cnfa = cnfa;
+ d->cm = cm;
+ d->lastpost = NULL;
+ d->lastnopr = NULL;
+ d->search = d->ssets;
+
+ /*
+ * Initialization of sset fields is done as needed.
+ */
+
+ return d;
}
-
+
/*
- freedfa - free a DFA
- ^ static VOID freedfa(struct dfa *);
+ ^ static void freedfa(struct dfa *);
*/
-static VOID
-freedfa(d)
-struct dfa *d;
+static void
+freedfa(
+ struct dfa *d)
{
- if (d->cptsmalloced) {
- if (d->ssets != NULL)
- FREE(d->ssets);
- if (d->statesarea != NULL)
- FREE(d->statesarea);
- if (d->outsarea != NULL)
- FREE(d->outsarea);
- if (d->incarea != NULL)
- FREE(d->incarea);
+ if (d->cptsmalloced) {
+ if (d->ssets != NULL) {
+ FREE(d->ssets);
+ }
+ if (d->statesarea != NULL) {
+ FREE(d->statesarea);
+ }
+ if (d->outsarea != NULL) {
+ FREE(d->outsarea);
}
+ if (d->incarea != NULL) {
+ FREE(d->incarea);
+ }
+ }
- if (d->mallocarea != NULL)
- FREE(d->mallocarea);
+ if (d->mallocarea != NULL) {
+ FREE(d->mallocarea);
+ }
}
-
+
/*
- hash - construct a hash code for a bitvector
* There are probably better ways, but they're more expensive.
^ static unsigned hash(unsigned *, int);
*/
static unsigned
-hash(uv, n)
-unsigned *uv;
-int n;
+hash(
+ unsigned *uv,
+ int n)
{
- int i;
- unsigned h;
-
- h = 0;
- for (i = 0; i < n; i++)
- h ^= uv[i];
- return h;
+ int i;
+ unsigned h;
+
+ h = 0;
+ for (i = 0; i < n; i++) {
+ h ^= uv[i];
+ }
+ return h;
}
-
+
/*
- initialize - hand-craft a cache entry for startup, otherwise get ready
^ static struct sset *initialize(struct vars *, struct dfa *, chr *);
*/
static struct sset *
-initialize(v, d, start)
-struct vars *v; /* used only for debug flags */
-struct dfa *d;
-chr *start;
+initialize(
+ struct vars *v, /* used only for debug flags */
+ struct dfa *d,
+ chr *start)
{
- struct sset *ss;
- int i;
-
- /* is previous one still there? */
- if (d->nssused > 0 && (d->ssets[0].flags&STARTER))
- ss = &d->ssets[0];
- else { /* no, must (re)build it */
- ss = getvacant(v, d, start, start);
- for (i = 0; i < d->wordsper; i++)
- ss->states[i] = 0;
- BSET(ss->states, d->cnfa->pre);
- ss->hash = HASH(ss->states, d->wordsper);
- assert(d->cnfa->pre != d->cnfa->post);
- ss->flags = STARTER|LOCKED|NOPROGRESS;
- /* lastseen dealt with below */
+ struct sset *ss;
+ int i;
+
+ /*
+ * Is previous one still there?
+ */
+
+ if (d->nssused > 0 && (d->ssets[0].flags&STARTER)) {
+ ss = &d->ssets[0];
+ } else { /* no, must (re)build it */
+ ss = getvacant(v, d, start, start);
+ for (i = 0; i < d->wordsper; i++) {
+ ss->states[i] = 0;
}
-
- for (i = 0; i < d->nssused; i++)
- d->ssets[i].lastseen = NULL;
- ss->lastseen = start; /* maybe untrue, but harmless */
- d->lastpost = NULL;
- d->lastnopr = NULL;
- return ss;
+ BSET(ss->states, d->cnfa->pre);
+ ss->hash = HASH(ss->states, d->wordsper);
+ assert(d->cnfa->pre != d->cnfa->post);
+ ss->flags = STARTER|LOCKED|NOPROGRESS;
+
+ /*
+ * lastseen dealt with below
+ */
+ }
+
+ for (i = 0; i < d->nssused; i++) {
+ d->ssets[i].lastseen = NULL;
+ }
+ ss->lastseen = start; /* maybe untrue, but harmless */
+ d->lastpost = NULL;
+ d->lastnopr = NULL;
+ return ss;
}
-
+
/*
- miss - handle a cache miss
^ static struct sset *miss(struct vars *, struct dfa *, struct sset *,
^ pcolor, chr *, chr *);
*/
static struct sset * /* NULL if goes to empty set */
-miss(v, d, css, co, cp, start)
-struct vars *v; /* used only for debug flags */
-struct dfa *d;
-struct sset *css;
-pcolor co;
-chr *cp; /* next chr */
-chr *start; /* where the attempt got started */
+miss(
+ struct vars *v, /* used only for debug flags */
+ struct dfa *d,
+ struct sset *css,
+ pcolor co,
+ chr *cp, /* next chr */
+ chr *start) /* where the attempt got started */
{
- struct cnfa *cnfa = d->cnfa;
- int i;
- unsigned h;
- struct carc *ca;
- struct sset *p;
- int ispost;
- int noprogress;
- int gotstate;
- int dolacons;
- int sawlacons;
-
- /* for convenience, we can be called even if it might not be a miss */
- if (css->outs[co] != NULL) {
- FDEBUG(("hit\n"));
- return css->outs[co];
- }
- FDEBUG(("miss\n"));
-
- /* first, what set of states would we end up in? */
- for (i = 0; i < d->wordsper; i++)
- d->work[i] = 0;
- ispost = 0;
- noprogress = 1;
- gotstate = 0;
- for (i = 0; i < d->nstates; i++)
- if (ISBSET(css->states, i))
- for (ca = cnfa->states[i]+1; ca->co != COLORLESS; ca++)
- if (ca->co == co) {
- BSET(d->work, ca->to);
- gotstate = 1;
- if (ca->to == cnfa->post)
- ispost = 1;
- if (!cnfa->states[ca->to]->co)
- noprogress = 0;
- FDEBUG(("%d -> %d\n", i, ca->to));
- }
- dolacons = (gotstate) ? (cnfa->flags&HASLACONS) : 0;
- sawlacons = 0;
- while (dolacons) { /* transitive closure */
- dolacons = 0;
- for (i = 0; i < d->nstates; i++)
- if (ISBSET(d->work, i))
- for (ca = cnfa->states[i]+1; ca->co != COLORLESS;
- ca++) {
- if (ca->co <= cnfa->ncolors)
- continue; /* NOTE CONTINUE */
- sawlacons = 1;
- if (ISBSET(d->work, ca->to))
- continue; /* NOTE CONTINUE */
- if (!lacon(v, cnfa, cp, ca->co))
- continue; /* NOTE CONTINUE */
- BSET(d->work, ca->to);
- dolacons = 1;
- if (ca->to == cnfa->post)
- ispost = 1;
- if (!cnfa->states[ca->to]->co)
- noprogress = 0;
- FDEBUG(("%d :> %d\n", i, ca->to));
- }
+ struct cnfa *cnfa = d->cnfa;
+ int i;
+ unsigned h;
+ struct carc *ca;
+ struct sset *p;
+ int ispost;
+ int noprogress;
+ int gotstate;
+ int dolacons;
+ int sawlacons;
+
+ /*
+ * For convenience, we can be called even if it might not be a miss.
+ */
+
+ if (css->outs[co] != NULL) {
+ FDEBUG(("hit\n"));
+ return css->outs[co];
+ }
+ FDEBUG(("miss\n"));
+
+ /*
+ * First, what set of states would we end up in?
+ */
+
+ for (i = 0; i < d->wordsper; i++) {
+ d->work[i] = 0;
+ }
+ ispost = 0;
+ noprogress = 1;
+ gotstate = 0;
+ for (i = 0; i < d->nstates; i++) {
+ if (ISBSET(css->states, i)) {
+ for (ca = cnfa->states[i]+1; ca->co != COLORLESS; ca++) {
+ if (ca->co == co) {
+ BSET(d->work, ca->to);
+ gotstate = 1;
+ if (ca->to == cnfa->post) {
+ ispost = 1;
+ }
+ if (!cnfa->states[ca->to]->co) {
+ noprogress = 0;
+ }
+ FDEBUG(("%d -> %d\n", i, ca->to));
+ }
+ }
}
- if (!gotstate)
- return NULL;
- h = HASH(d->work, d->wordsper);
-
- /* next, is that in the cache? */
- for (p = d->ssets, i = d->nssused; i > 0; p++, i--)
- if (HIT(h, d->work, p, d->wordsper)) {
- FDEBUG(("cached c%d\n", p - d->ssets));
- break; /* NOTE BREAK OUT */
+ }
+ dolacons = (gotstate) ? (cnfa->flags&HASLACONS) : 0;
+ sawlacons = 0;
+ while (dolacons) { /* transitive closure */
+ dolacons = 0;
+ for (i = 0; i < d->nstates; i++) {
+ if (ISBSET(d->work, i)) {
+ for (ca = cnfa->states[i]+1; ca->co != COLORLESS; ca++) {
+ if (ca->co <= cnfa->ncolors) {
+ continue; /* NOTE CONTINUE */
+ }
+ sawlacons = 1;
+ if (ISBSET(d->work, ca->to)) {
+ continue; /* NOTE CONTINUE */
+ }
+ if (!lacon(v, cnfa, cp, ca->co)) {
+ continue; /* NOTE CONTINUE */
+ }
+ BSET(d->work, ca->to);
+ dolacons = 1;
+ if (ca->to == cnfa->post) {
+ ispost = 1;
+ }
+ if (!cnfa->states[ca->to]->co) {
+ noprogress = 0;
+ }
+ FDEBUG(("%d :> %d\n", i, ca->to));
}
- if (i == 0) { /* nope, need a new cache entry */
- p = getvacant(v, d, cp, start);
- assert(p != css);
- for (i = 0; i < d->wordsper; i++)
- p->states[i] = d->work[i];
- p->hash = h;
- p->flags = (ispost) ? POSTSTATE : 0;
- if (noprogress)
- p->flags |= NOPROGRESS;
- /* lastseen to be dealt with by caller */
+ }
}
-
- if (!sawlacons) { /* lookahead conds. always cache miss */
- FDEBUG(("c%d[%d]->c%d\n", css - d->ssets, co, p - d->ssets));
- css->outs[co] = p;
- css->inchain[co] = p->ins;
- p->ins.ss = css;
- p->ins.co = (color)co;
+ }
+ if (!gotstate) {
+ return NULL;
+ }
+ h = HASH(d->work, d->wordsper);
+
+ /*
+ * Next, is that in the cache?
+ */
+
+ for (p = d->ssets, i = d->nssused; i > 0; p++, i--) {
+ if (HIT(h, d->work, p, d->wordsper)) {
+ FDEBUG(("cached c%d\n", p - d->ssets));
+ break; /* NOTE BREAK OUT */
+ }
+ }
+ if (i == 0) { /* nope, need a new cache entry */
+ p = getvacant(v, d, cp, start);
+ assert(p != css);
+ for (i = 0; i < d->wordsper; i++) {
+ p->states[i] = d->work[i];
+ }
+ p->hash = h;
+ p->flags = (ispost) ? POSTSTATE : 0;
+ if (noprogress) {
+ p->flags |= NOPROGRESS;
}
- return p;
-}
+ /*
+ * lastseen to be dealt with by caller
+ */
+ }
+
+ if (!sawlacons) { /* lookahead conds. always cache miss */
+ FDEBUG(("c%d[%d]->c%d\n", css - d->ssets, co, p - d->ssets));
+ css->outs[co] = p;
+ css->inchain[co] = p->ins;
+ p->ins.ss = css;
+ p->ins.co = (color)co;
+ }
+ return p;
+}
+
/*
- lacon - lookahead-constraint checker for miss()
^ static int lacon(struct vars *, struct cnfa *, chr *, pcolor);
*/
static int /* predicate: constraint satisfied? */
-lacon(v, pcnfa, cp, co)
-struct vars *v;
-struct cnfa *pcnfa; /* parent cnfa */
-chr *cp;
-pcolor co; /* "color" of the lookahead constraint */
+lacon(
+ struct vars *v,
+ struct cnfa *pcnfa, /* parent cnfa */
+ chr *cp,
+ pcolor co) /* "color" of the lookahead constraint */
{
- int n;
- struct subre *sub;
- struct dfa *d;
- struct smalldfa sd;
- chr *end;
-
- n = co - pcnfa->ncolors;
- assert(n < v->g->nlacons && v->g->lacons != NULL);
- FDEBUG(("=== testing lacon %d\n", n));
- sub = &v->g->lacons[n];
- d = newdfa(v, &sub->cnfa, &v->g->cmap, &sd);
- if (d == NULL) {
- ERR(REG_ESPACE);
- return 0;
- }
- end = longest(v, d, cp, v->stop, (int *)NULL);
- freedfa(d);
- FDEBUG(("=== lacon %d match %d\n", n, (end != NULL)));
- return (sub->subno) ? (end != NULL) : (end == NULL);
+ int n;
+ struct subre *sub;
+ struct dfa *d;
+ struct smalldfa sd;
+ chr *end;
+
+ n = co - pcnfa->ncolors;
+ assert(n < v->g->nlacons && v->g->lacons != NULL);
+ FDEBUG(("=== testing lacon %d\n", n));
+ sub = &v->g->lacons[n];
+ d = newdfa(v, &sub->cnfa, &v->g->cmap, &sd);
+ if (d == NULL) {
+ ERR(REG_ESPACE);
+ return 0;
+ }
+ end = longest(v, d, cp, v->stop, (int *)NULL);
+ freedfa(d);
+ FDEBUG(("=== lacon %d match %d\n", n, (end != NULL)));
+ return (sub->subno) ? (end != NULL) : (end == NULL);
}
-
+
/*
- getvacant - get a vacant state set
* This routine clears out the inarcs and outarcs, but does not otherwise
@@ -551,127 +650,167 @@ pcolor co; /* "color" of the lookahead constraint */
^ static struct sset *getvacant(struct vars *, struct dfa *, chr *, chr *);
*/
static struct sset *
-getvacant(v, d, cp, start)
-struct vars *v; /* used only for debug flags */
-struct dfa *d;
-chr *cp;
-chr *start;
+getvacant(
+ struct vars *v, /* used only for debug flags */
+ struct dfa *d,
+ chr *cp,
+ chr *start)
{
- int i;
- struct sset *ss;
- struct sset *p;
- struct arcp ap;
- struct arcp lastap = {NULL, 0}; /* silence gcc 4 warning */
- color co;
-
- ss = pickss(v, d, cp, start);
- assert(!(ss->flags&LOCKED));
-
- /* clear out its inarcs, including self-referential ones */
- ap = ss->ins;
- while ((p = ap.ss) != NULL) {
- co = ap.co;
- FDEBUG(("zapping c%d's %ld outarc\n", p - d->ssets, (long)co));
- p->outs[co] = NULL;
- ap = p->inchain[co];
- p->inchain[co].ss = NULL; /* paranoia */
+ int i;
+ struct sset *ss;
+ struct sset *p;
+ struct arcp ap;
+ struct arcp lastap = {NULL, 0}; /* silence gcc 4 warning */
+ color co;
+
+ ss = pickss(v, d, cp, start);
+ assert(!(ss->flags&LOCKED));
+
+ /*
+ * Clear out its inarcs, including self-referential ones.
+ */
+
+ ap = ss->ins;
+ while ((p = ap.ss) != NULL) {
+ co = ap.co;
+ FDEBUG(("zapping c%d's %ld outarc\n", p - d->ssets, (long)co));
+ p->outs[co] = NULL;
+ ap = p->inchain[co];
+ p->inchain[co].ss = NULL; /* paranoia */
+ }
+ ss->ins.ss = NULL;
+
+ /*
+ * Take it off the inarc chains of the ssets reached by its outarcs.
+ */
+
+ for (i = 0; i < d->ncolors; i++) {
+ p = ss->outs[i];
+ assert(p != ss); /* not self-referential */
+ if (p == NULL) {
+ continue; /* NOTE CONTINUE */
}
- ss->ins.ss = NULL;
-
- /* take it off the inarc chains of the ssets reached by its outarcs */
- for (i = 0; i < d->ncolors; i++) {
- p = ss->outs[i];
- assert(p != ss); /* not self-referential */
- if (p == NULL)
- continue; /* NOTE CONTINUE */
- FDEBUG(("del outarc %d from c%d's in chn\n", i, p - d->ssets));
- if (p->ins.ss == ss && p->ins.co == i)
- p->ins = ss->inchain[i];
- else {
- assert(p->ins.ss != NULL);
- for (ap = p->ins; ap.ss != NULL &&
- !(ap.ss == ss && ap.co == i);
- ap = ap.ss->inchain[ap.co])
- lastap = ap;
- assert(ap.ss != NULL);
- lastap.ss->inchain[lastap.co] = ss->inchain[i];
- }
- ss->outs[i] = NULL;
- ss->inchain[i].ss = NULL;
+ FDEBUG(("del outarc %d from c%d's in chn\n", i, p - d->ssets));
+ if (p->ins.ss == ss && p->ins.co == i) {
+ p->ins = ss->inchain[i];
+ } else {
+ assert(p->ins.ss != NULL);
+ for (ap = p->ins; ap.ss != NULL &&
+ !(ap.ss == ss && ap.co == i);
+ ap = ap.ss->inchain[ap.co]) {
+ lastap = ap;
+ }
+ assert(ap.ss != NULL);
+ lastap.ss->inchain[lastap.co] = ss->inchain[i];
}
+ ss->outs[i] = NULL;
+ ss->inchain[i].ss = NULL;
+ }
- /* if ss was a success state, may need to remember location */
- if ((ss->flags&POSTSTATE) && ss->lastseen != d->lastpost &&
- (d->lastpost == NULL || d->lastpost < ss->lastseen))
- d->lastpost = ss->lastseen;
+ /*
+ * If ss was a success state, may need to remember location.
+ */
- /* likewise for a no-progress state */
- if ((ss->flags&NOPROGRESS) && ss->lastseen != d->lastnopr &&
- (d->lastnopr == NULL || d->lastnopr < ss->lastseen))
- d->lastnopr = ss->lastseen;
+ if ((ss->flags&POSTSTATE) && ss->lastseen != d->lastpost &&
+ (d->lastpost == NULL || d->lastpost < ss->lastseen)) {
+ d->lastpost = ss->lastseen;
+ }
- return ss;
-}
+ /*
+ * Likewise for a no-progress state.
+ */
+ if ((ss->flags&NOPROGRESS) && ss->lastseen != d->lastnopr &&
+ (d->lastnopr == NULL || d->lastnopr < ss->lastseen)) {
+ d->lastnopr = ss->lastseen;
+ }
+
+ return ss;
+}
+
/*
- pickss - pick the next stateset to be used
^ static struct sset *pickss(struct vars *, struct dfa *, chr *, chr *);
*/
static struct sset *
-pickss(v, d, cp, start)
-struct vars *v; /* used only for debug flags */
-struct dfa *d;
-chr *cp;
-chr *start;
+pickss(
+ struct vars *v, /* used only for debug flags */
+ struct dfa *d,
+ chr *cp,
+ chr *start)
{
- int i;
- struct sset *ss;
- struct sset *end;
- chr *ancient;
-
- /* shortcut for cases where cache isn't full */
- if (d->nssused < d->nssets) {
- i = d->nssused;
- d->nssused++;
- ss = &d->ssets[i];
- FDEBUG(("new c%d\n", i));
- /* set up innards */
- ss->states = &d->statesarea[i * d->wordsper];
- ss->flags = 0;
- ss->ins.ss = NULL;
- ss->ins.co = WHITE; /* give it some value */
- ss->outs = &d->outsarea[i * d->ncolors];
- ss->inchain = &d->incarea[i * d->ncolors];
- for (i = 0; i < d->ncolors; i++) {
- ss->outs[i] = NULL;
- ss->inchain[i].ss = NULL;
- }
- return ss;
+ int i;
+ struct sset *ss;
+ struct sset *end;
+ chr *ancient;
+
+ /*
+ * Shortcut for cases where cache isn't full.
+ */
+
+ if (d->nssused < d->nssets) {
+ i = d->nssused;
+ d->nssused++;
+ ss = &d->ssets[i];
+ FDEBUG(("new c%d\n", i));
+
+ /*
+ * Set up innards.
+ */
+
+ ss->states = &d->statesarea[i * d->wordsper];
+ ss->flags = 0;
+ ss->ins.ss = NULL;
+ ss->ins.co = WHITE; /* give it some value */
+ ss->outs = &d->outsarea[i * d->ncolors];
+ ss->inchain = &d->incarea[i * d->ncolors];
+ for (i = 0; i < d->ncolors; i++) {
+ ss->outs[i] = NULL;
+ ss->inchain[i].ss = NULL;
+ }
+ return ss;
+ }
+
+ /*
+ * Look for oldest, or old enough anyway.
+ */
+
+ if (cp - start > d->nssets*2/3) { /* oldest 33% are expendable */
+ ancient = cp - d->nssets*2/3;
+ } else {
+ ancient = start;
+ }
+ for (ss = d->search, end = &d->ssets[d->nssets]; ss < end; ss++) {
+ if ((ss->lastseen == NULL || ss->lastseen < ancient)
+ && !(ss->flags&LOCKED)) {
+ d->search = ss + 1;
+ FDEBUG(("replacing c%d\n", ss - d->ssets));
+ return ss;
}
+ }
+ for (ss = d->ssets, end = d->search; ss < end; ss++) {
+ if ((ss->lastseen == NULL || ss->lastseen < ancient)
+ && !(ss->flags&LOCKED)) {
+ d->search = ss + 1;
+ FDEBUG(("replacing c%d\n", ss - d->ssets));
+ return ss;
+ }
+ }
- /* look for oldest, or old enough anyway */
- if (cp - start > d->nssets*2/3) /* oldest 33% are expendable */
- ancient = cp - d->nssets*2/3;
- else
- ancient = start;
- for (ss = d->search, end = &d->ssets[d->nssets]; ss < end; ss++)
- if ((ss->lastseen == NULL || ss->lastseen < ancient) &&
- !(ss->flags&LOCKED)) {
- d->search = ss + 1;
- FDEBUG(("replacing c%d\n", ss - d->ssets));
- return ss;
- }
- for (ss = d->ssets, end = d->search; ss < end; ss++)
- if ((ss->lastseen == NULL || ss->lastseen < ancient) &&
- !(ss->flags&LOCKED)) {
- d->search = ss + 1;
- FDEBUG(("replacing c%d\n", ss - d->ssets));
- return ss;
- }
+ /*
+ * Nobody's old enough?!? -- something's really wrong.
+ */
- /* nobody's old enough?!? -- something's really wrong */
- FDEBUG(("can't find victim to replace!\n"));
- assert(NOTREACHED);
- ERR(REG_ASSERT);
- return d->ssets;
+ FDEBUG(("can't find victim to replace!\n"));
+ assert(NOTREACHED);
+ ERR(REG_ASSERT);
+ return d->ssets;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regerror.c b/generic/regerror.c
index 182830d..49b6f3e 100644
--- a/generic/regerror.c
+++ b/generic/regerror.c
@@ -2,20 +2,20 @@
* regerror - error-code expansion
*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
- *
+ *
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author
- * thanks all of them.
- *
+ * thanks all of them.
+ *
* Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
- *
- * I'd appreciate being given credit for this package in the documentation
- * of software which uses it, but that is not a requirement.
- *
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -31,79 +31,99 @@
#include "regguts.h"
-/* unknown-error explanation */
+/*
+ * Unknown-error explanation.
+ */
+
static char unk[] = "*** unknown regex error code 0x%x ***";
-/* struct to map among codes, code names, and explanations */
+/*
+ * Struct to map among codes, code names, and explanations.
+ */
+
static struct rerr {
- int code;
- char *name;
- char *explain;
+ int code;
+ const char *name;
+ const char *explain;
} rerrs[] = {
- /* the actual table is built from regex.h */
-# include "regerrs.h"
- { -1, "", "oops" }, /* explanation special-cased in code */
+ /* The actual table is built from regex.h */
+#include "regerrs.h"
+ { -1, "", "oops" }, /* explanation special-cased in code */
};
-
+
/*
- regerror - the interface to error numbers
*/
/* ARGSUSED */
-size_t /* actual space needed (including NUL) */
-regerror(code, preg, errbuf, errbuf_size)
-int code; /* error code, or REG_ATOI or REG_ITOA */
-CONST regex_t *preg; /* associated regex_t (unused at present) */
-char *errbuf; /* result buffer (unless errbuf_size==0) */
-size_t errbuf_size; /* available space in errbuf, can be 0 */
+size_t /* Actual space needed (including NUL) */
+regerror(
+ int code, /* Error code, or REG_ATOI or REG_ITOA */
+ const regex_t *preg, /* Associated regex_t (unused at present) */
+ char *errbuf, /* Result buffer (unless errbuf_size==0) */
+ size_t errbuf_size) /* Available space in errbuf, can be 0 */
{
- struct rerr *r;
- char *msg;
- char convbuf[sizeof(unk)+50]; /* 50 = plenty for int */
- size_t len;
- int icode;
+ struct rerr *r;
+ const char *msg;
+ char convbuf[sizeof(unk)+50]; /* 50 = plenty for int */
+ size_t len;
+ int icode;
- switch (code) {
- case REG_ATOI: /* convert name to number */
- for (r = rerrs; r->code >= 0; r++)
- if (strcmp(r->name, errbuf) == 0)
- break;
- sprintf(convbuf, "%d", r->code); /* -1 for unknown */
- msg = convbuf;
+ switch (code) {
+ case REG_ATOI: /* Convert name to number */
+ for (r = rerrs; r->code >= 0; r++) {
+ if (strcmp(r->name, errbuf) == 0) {
break;
- case REG_ITOA: /* convert number to name */
- icode = atoi(errbuf); /* not our problem if this fails */
- for (r = rerrs; r->code >= 0; r++)
- if (r->code == icode)
- break;
- if (r->code >= 0)
- msg = r->name;
- else { /* unknown; tell him the number */
- sprintf(convbuf, "REG_%u", (unsigned)icode);
- msg = convbuf;
- }
+ }
+ }
+ sprintf(convbuf, "%d", r->code); /* -1 for unknown */
+ msg = convbuf;
+ break;
+ case REG_ITOA: /* Convert number to name */
+ icode = atoi(errbuf); /* Not our problem if this fails */
+ for (r = rerrs; r->code >= 0; r++) {
+ if (r->code == icode) {
break;
- default: /* a real, normal error code */
- for (r = rerrs; r->code >= 0; r++)
- if (r->code == code)
- break;
- if (r->code >= 0)
- msg = r->explain;
- else { /* unknown; say so */
- sprintf(convbuf, unk, code);
- msg = convbuf;
- }
+ }
+ }
+ if (r->code >= 0) {
+ msg = r->name;
+ } else { /* Unknown; tell him the number */
+ sprintf(convbuf, "REG_%u", (unsigned)icode);
+ msg = convbuf;
+ }
+ break;
+ default: /* A real, normal error code */
+ for (r = rerrs; r->code >= 0; r++) {
+ if (r->code == code) {
break;
+ }
+ }
+ if (r->code >= 0) {
+ msg = r->explain;
+ } else { /* Unknown; say so */
+ sprintf(convbuf, unk, code);
+ msg = convbuf;
}
+ break;
+ }
- len = strlen(msg) + 1; /* space needed, including NUL */
- if (errbuf_size > 0) {
- if (errbuf_size > len)
- strcpy(errbuf, msg);
- else { /* truncate to fit */
- strncpy(errbuf, msg, errbuf_size-1);
- errbuf[errbuf_size-1] = '\0';
- }
+ len = strlen(msg) + 1; /* Space needed, including NUL */
+ if (errbuf_size > 0) {
+ if (errbuf_size > len) {
+ strcpy(errbuf, msg);
+ } else { /* Truncate to fit */
+ strncpy(errbuf, msg, errbuf_size-1);
+ errbuf[errbuf_size-1] = '\0';
}
+ }
- return len;
+ return len;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regex.h b/generic/regex.h
index a35925a..fa86092 100644
--- a/generic/regex.h
+++ b/generic/regex.h
@@ -4,20 +4,20 @@
* regular expressions
*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
- *
+ *
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
- * Corporation, none of whom are responsible for the results. The author
- * thanks all of them.
- *
+ * Corporation, none of whom are responsible for the results. The author
+ * thanks all of them.
+ *
* Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
*
- * I'd appreciate being given credit for this package in the documentation
- * of software which uses it, but that is not a requirement.
- *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -30,38 +30,35 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
- *
* Prototypes etc. marked with "^" within comments get gathered up (and
- * possibly edited) by the regfwd program and inserted near the bottom of
- * this file.
+ * possibly edited) by the regfwd program and inserted near the bottom of this
+ * file.
*
- * We offer the option of declaring one wide-character version of the
- * RE functions as well as the char versions. To do that, define
- * __REG_WIDE_T to the type of wide characters (unfortunately, there
- * is no consensus that wchar_t is suitable) and __REG_WIDE_COMPILE and
- * __REG_WIDE_EXEC to the names to be used for the compile and execute
- * functions (suggestion: re_Xcomp and re_Xexec, where X is a letter
- * suggestive of the wide type, e.g. re_ucomp and re_uexec for Unicode).
- * For cranky old compilers, it may be necessary to do something like:
+ * We offer the option of declaring one wide-character version of the RE
+ * functions as well as the char versions. To do that, define __REG_WIDE_T to
+ * the type of wide characters (unfortunately, there is no consensus that
+ * wchar_t is suitable) and __REG_WIDE_COMPILE and __REG_WIDE_EXEC to the
+ * names to be used for the compile and execute functions (suggestion:
+ * re_Xcomp and re_Xexec, where X is a letter suggestive of the wide type,
+ * e.g. re_ucomp and re_uexec for Unicode). For cranky old compilers, it may
+ * be necessary to do something like:
* #define __REG_WIDE_COMPILE(a,b,c,d) re_Xcomp(a,b,c,d)
* #define __REG_WIDE_EXEC(a,b,c,d,e,f,g) re_Xexec(a,b,c,d,e,f,g)
* rather than just #defining the names as parameterless macros.
*
* For some specialized purposes, it may be desirable to suppress the
- * declarations of the "front end" functions, regcomp() and regexec(),
- * or of the char versions of the compile and execute functions. To
- * suppress the front-end functions, define __REG_NOFRONT. To suppress
- * the char versions, define __REG_NOCHAR.
+ * declarations of the "front end" functions, regcomp() and regexec(), or of
+ * the char versions of the compile and execute functions. To suppress the
+ * front-end functions, define __REG_NOFRONT. To suppress the char versions,
+ * define __REG_NOCHAR.
*
* The right place to do those defines (and some others you may want, see
- * below) would be <sys/types.h>. If you don't have control of that file,
- * the right place to add your own defines to this file is marked below.
- * This is normally done automatically, by the makefile and regmkhdr, based
- * on the contents of regcustom.h.
+ * below) would be <sys/types.h>. If you don't have control of that file, the
+ * right place to add your own defines to this file is marked below. This is
+ * normally done automatically, by the makefile and regmkhdr, based on the
+ * contents of regcustom.h.
*/
-
-
/*
* voodoo for C++
*/
@@ -69,18 +66,15 @@
extern "C" {
#endif
-
-
/*
* Add your own defines, if needed, here.
*/
-
-
/*
- * Location where a chunk of regcustom.h is automatically spliced into
- * this file (working from its prototype, regproto.h).
+ * Location where a chunk of regcustom.h is automatically spliced into this
+ * file (working from its prototype, regproto.h).
*/
+
/* --- begin --- */
/* ensure certain things don't sneak in from system headers */
#ifdef __REG_WIDE_T
@@ -121,15 +115,14 @@ extern "C" {
#define regerror TclReError
/* --- end --- */
-
/*
* interface types etc.
*/
/*
- * regoff_t has to be large enough to hold either off_t or ssize_t,
- * and must be signed; it's only a guess that long is suitable, so we
- * offer <sys/types.h> an override.
+ * regoff_t has to be large enough to hold either off_t or ssize_t, and must
+ * be signed; it's only a guess that long is suitable, so we offer
+ * <sys/types.h> an override.
*/
#ifdef __REG_REGOFF_T
typedef __REG_REGOFF_T regoff_t;
@@ -148,8 +141,8 @@ typedef void re_void;
#endif
/*
- * Also for benefit of old compilers, <sys/types.h> can supply a macro
- * which expands to a substitute for `const'.
+ * Also for benefit of old compilers, <sys/types.h> can supply a macro which
+ * expands to a substitute for `const'.
*/
#ifndef __REG_CONST
#define __REG_CONST const
@@ -163,43 +156,41 @@ typedef void re_void;
/* the biggie, a compiled RE (or rather, a front end to same) */
typedef struct {
- int re_magic; /* magic number */
- size_t re_nsub; /* number of subexpressions */
- long re_info; /* information about RE */
-# define REG_UBACKREF 000001
-# define REG_ULOOKAHEAD 000002
-# define REG_UBOUNDS 000004
-# define REG_UBRACES 000010
-# define REG_UBSALNUM 000020
-# define REG_UPBOTCH 000040
-# define REG_UBBS 000100
-# define REG_UNONPOSIX 000200
-# define REG_UUNSPEC 000400
-# define REG_UUNPORT 001000
-# define REG_ULOCALE 002000
-# define REG_UEMPTYMATCH 004000
-# define REG_UIMPOSSIBLE 010000
-# define REG_USHORTEST 020000
- int re_csize; /* sizeof(character) */
- char *re_endp; /* backward compatibility kludge */
- /* the rest is opaque pointers to hidden innards */
- char *re_guts; /* `char *' is more portable than `void *' */
- char *re_fns;
+ int re_magic; /* magic number */
+ size_t re_nsub; /* number of subexpressions */
+ long re_info; /* information about RE */
+#define REG_UBACKREF 000001
+#define REG_ULOOKAHEAD 000002
+#define REG_UBOUNDS 000004
+#define REG_UBRACES 000010
+#define REG_UBSALNUM 000020
+#define REG_UPBOTCH 000040
+#define REG_UBBS 000100
+#define REG_UNONPOSIX 000200
+#define REG_UUNSPEC 000400
+#define REG_UUNPORT 001000
+#define REG_ULOCALE 002000
+#define REG_UEMPTYMATCH 004000
+#define REG_UIMPOSSIBLE 010000
+#define REG_USHORTEST 020000
+ int re_csize; /* sizeof(character) */
+ char *re_endp; /* backward compatibility kludge */
+ /* the rest is opaque pointers to hidden innards */
+ char *re_guts; /* `char *' is more portable than `void *' */
+ char *re_fns;
} regex_t;
/* result reporting (may acquire more fields later) */
typedef struct {
- regoff_t rm_so; /* start of substring */
- regoff_t rm_eo; /* end of substring */
+ regoff_t rm_so; /* start of substring */
+ regoff_t rm_eo; /* end of substring */
} regmatch_t;
/* supplementary control and reporting */
typedef struct {
- regmatch_t rm_extend; /* see REG_EXPECT */
+ regmatch_t rm_extend; /* see REG_EXPECT */
} rm_detail_t;
-
-
/*
* compilation
^ #ifndef __REG_NOCHAR
@@ -231,8 +222,6 @@ typedef struct {
#define REG_FAKE 010000 /* none of your business :-) */
#define REG_PROGRESS 020000 /* none of your business :-) */
-
-
/*
* execution
^ #ifndef __REG_NOCHAR
@@ -254,23 +243,19 @@ typedef struct {
#define REG_MTRACE 0020 /* none of your business */
#define REG_SMALL 0040 /* none of your business */
-
-
/*
* misc generics (may be more functions here eventually)
^ re_void regfree(regex_t *);
*/
-
-
/*
* error reporting
* Be careful if modifying the list of error codes -- the table used by
* regerror() is generated automatically from this file!
*
- * Note that there is no wide-char variant of regerror at this time; what
- * kind of character is used for error reports is independent of what kind
- * is used in matching.
+ * Note that there is no wide-char variant of regerror at this time; what kind
+ * of character is used for error reports is independent of what kind is used
+ * in matching.
*
^ extern size_t regerror(int, __REG_CONST regex_t *, char *, size_t);
*/
@@ -297,8 +282,6 @@ typedef struct {
#define REG_ATOI 101 /* convert error-code name to number */
#define REG_ITOA 102 /* convert error-code number to name */
-
-
/*
* the prototypes, as possibly munched by regfwd
*/
@@ -306,30 +289,28 @@ typedef struct {
/* automatically gathered by fwd; do not hand-edit */
/* === regproto.h === */
#ifndef __REG_NOCHAR
-int re_comp _ANSI_ARGS_((regex_t *, __REG_CONST char *, size_t, int));
+int re_comp(regex_t *, __REG_CONST char *, size_t, int);
#endif
#ifndef __REG_NOFRONT
-int regcomp _ANSI_ARGS_((regex_t *, __REG_CONST char *, int));
+int regcomp(regex_t *, __REG_CONST char *, int);
#endif
#ifdef __REG_WIDE_T
-int __REG_WIDE_COMPILE _ANSI_ARGS_((regex_t *, __REG_CONST __REG_WIDE_T *, size_t, int));
+MODULE_SCOPE int __REG_WIDE_COMPILE(regex_t *, __REG_CONST __REG_WIDE_T *, size_t, int);
#endif
#ifndef __REG_NOCHAR
-int re_exec _ANSI_ARGS_((regex_t *, __REG_CONST char *, size_t, rm_detail_t *, size_t, regmatch_t [], int));
+int re_exec(regex_t *, __REG_CONST char *, size_t, rm_detail_t *, size_t, regmatch_t [], int);
#endif
#ifndef __REG_NOFRONT
-int regexec _ANSI_ARGS_((regex_t *, __REG_CONST char *, size_t, regmatch_t [], int));
+int regexec(regex_t *, __REG_CONST char *, size_t, regmatch_t [], int);
#endif
#ifdef __REG_WIDE_T
-int __REG_WIDE_EXEC _ANSI_ARGS_((regex_t *, __REG_CONST __REG_WIDE_T *, size_t, rm_detail_t *, size_t, regmatch_t [], int));
+MODULE_SCOPE int __REG_WIDE_EXEC(regex_t *, __REG_CONST __REG_WIDE_T *, size_t, rm_detail_t *, size_t, regmatch_t [], int);
#endif
-re_void regfree _ANSI_ARGS_((regex_t *));
-extern size_t regerror _ANSI_ARGS_((int, __REG_CONST regex_t *, char *, size_t));
+MODULE_SCOPE re_void regfree(regex_t *);
+MODULE_SCOPE size_t regerror(int, __REG_CONST regex_t *, char *, size_t);
/* automatically gathered by fwd; do not hand-edit */
/* =====^!^===== end forwards =====^!^===== */
-
-
/*
* more C++ voodoo
*/
@@ -337,6 +318,4 @@ extern size_t regerror _ANSI_ARGS_((int, __REG_CONST regex_t *, char *, size_t))
}
#endif
-
-
#endif
diff --git a/generic/regexec.c b/generic/regexec.c
index be459d3..c902209 100644
--- a/generic/regexec.c
+++ b/generic/regexec.c
@@ -2,20 +2,20 @@
* re_*exec and friends - match REs
*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
- *
+ *
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author
- * thanks all of them.
- *
+ * thanks all of them.
+ *
* Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
- *
- * I'd appreciate being given credit for this package in the documentation
- * of software which uses it, but that is not a requirement.
- *
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -26,1015 +26,1181 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
*/
#include "regguts.h"
+/*
+ * Lazy-DFA representation.
+ */
-
-/* lazy-DFA representation */
struct arcp { /* "pointer" to an outarc */
- struct sset *ss;
- color co;
+ struct sset *ss;
+ color co;
};
struct sset { /* state set */
- unsigned *states; /* pointer to bitvector */
- unsigned hash; /* hash of bitvector */
-# define HASH(bv, nw) (((nw) == 1) ? *(bv) : hash(bv, nw))
-# define HIT(h,bv,ss,nw) ((ss)->hash == (h) && ((nw) == 1 || \
- memcmp(VS(bv), VS((ss)->states), (nw)*sizeof(unsigned)) == 0))
- int flags;
-# define STARTER 01 /* the initial state set */
-# define POSTSTATE 02 /* includes the goal state */
-# define LOCKED 04 /* locked in cache */
-# define NOPROGRESS 010 /* zero-progress state set */
- struct arcp ins; /* chain of inarcs pointing here */
- chr *lastseen; /* last entered on arrival here */
- struct sset **outs; /* outarc vector indexed by color */
- struct arcp *inchain; /* chain-pointer vector for outarcs */
+ unsigned *states; /* pointer to bitvector */
+ unsigned hash; /* hash of bitvector */
+#define HASH(bv, nw) (((nw) == 1) ? *(bv) : hash(bv, nw))
+#define HIT(h,bv,ss,nw) ((ss)->hash == (h) && ((nw) == 1 || \
+ memcmp(VS(bv), VS((ss)->states), (nw)*sizeof(unsigned)) == 0))
+ int flags;
+#define STARTER 01 /* the initial state set */
+#define POSTSTATE 02 /* includes the goal state */
+#define LOCKED 04 /* locked in cache */
+#define NOPROGRESS 010 /* zero-progress state set */
+ struct arcp ins; /* chain of inarcs pointing here */
+ chr *lastseen; /* last entered on arrival here */
+ struct sset **outs; /* outarc vector indexed by color */
+ struct arcp *inchain; /* chain-pointer vector for outarcs */
};
struct dfa {
- int nssets; /* size of cache */
- int nssused; /* how many entries occupied yet */
- int nstates; /* number of states */
- int ncolors; /* length of outarc and inchain vectors */
- int wordsper; /* length of state-set bitvectors */
- struct sset *ssets; /* state-set cache */
- unsigned *statesarea; /* bitvector storage */
- unsigned *work; /* pointer to work area within statesarea */
- struct sset **outsarea; /* outarc-vector storage */
- struct arcp *incarea; /* inchain storage */
- struct cnfa *cnfa;
- struct colormap *cm;
- chr *lastpost; /* location of last cache-flushed success */
- chr *lastnopr; /* location of last cache-flushed NOPROGRESS */
- struct sset *search; /* replacement-search-pointer memory */
- int cptsmalloced; /* were the areas individually malloced? */
- char *mallocarea; /* self, or master malloced area, or NULL */
+ int nssets; /* size of cache */
+ int nssused; /* how many entries occupied yet */
+ int nstates; /* number of states */
+ int ncolors; /* length of outarc and inchain vectors */
+ int wordsper; /* length of state-set bitvectors */
+ struct sset *ssets; /* state-set cache */
+ unsigned *statesarea; /* bitvector storage */
+ unsigned *work; /* pointer to work area within statesarea */
+ struct sset **outsarea; /* outarc-vector storage */
+ struct arcp *incarea; /* inchain storage */
+ struct cnfa *cnfa;
+ struct colormap *cm;
+ chr *lastpost; /* location of last cache-flushed success */
+ chr *lastnopr; /* location of last cache-flushed NOPROGRESS */
+ struct sset *search; /* replacement-search-pointer memory */
+ int cptsmalloced; /* were the areas individually malloced? */
+ char *mallocarea; /* self, or master malloced area, or NULL */
};
#define WORK 1 /* number of work bitvectors needed */
-/* setup for non-malloc allocation for small cases */
+/*
+ * Setup for non-malloc allocation for small cases.
+ */
+
#define FEWSTATES 20 /* must be less than UBITS */
#define FEWCOLORS 15
struct smalldfa {
- struct dfa dfa;
- struct sset ssets[FEWSTATES*2];
- unsigned statesarea[FEWSTATES*2 + WORK];
- struct sset *outsarea[FEWSTATES*2 * FEWCOLORS];
- struct arcp incarea[FEWSTATES*2 * FEWCOLORS];
+ struct dfa dfa;
+ struct sset ssets[FEWSTATES*2];
+ unsigned statesarea[FEWSTATES*2 + WORK];
+ struct sset *outsarea[FEWSTATES*2 * FEWCOLORS];
+ struct arcp incarea[FEWSTATES*2 * FEWCOLORS];
};
#define DOMALLOC ((struct smalldfa *)NULL) /* force malloc */
+/*
+ * Internal variables, bundled for easy passing around.
+ */
-
-/* internal variables, bundled for easy passing around */
struct vars {
- regex_t *re;
- struct guts *g;
- int eflags; /* copies of arguments */
- size_t nmatch;
- regmatch_t *pmatch;
- rm_detail_t *details;
- chr *start; /* start of string */
- chr *stop; /* just past end of string */
- int err; /* error code if any (0 none) */
- regoff_t *mem; /* memory vector for backtracking */
- struct smalldfa dfa1;
- struct smalldfa dfa2;
+ regex_t *re;
+ struct guts *g;
+ int eflags; /* copies of arguments */
+ size_t nmatch;
+ regmatch_t *pmatch;
+ rm_detail_t *details;
+ chr *start; /* start of string */
+ chr *stop; /* just past end of string */
+ int err; /* error code if any (0 none) */
+ regoff_t *mem; /* memory vector for backtracking */
+ struct smalldfa dfa1;
+ struct smalldfa dfa2;
};
-#define VISERR(vv) ((vv)->err != 0) /* have we seen an error yet? */
+#define VISERR(vv) ((vv)->err != 0) /* have we seen an error yet? */
#define ISERR() VISERR(v)
-#define VERR(vv,e) (((vv)->err) ? (vv)->err : ((vv)->err = (e)))
-#define ERR(e) VERR(v, e) /* record an error */
+#define VERR(vv,e) (((vv)->err) ? (vv)->err : ((vv)->err = (e)))
+#define ERR(e) VERR(v, e) /* record an error */
#define NOERR() {if (ISERR()) return v->err;} /* if error seen, return it */
#define OFF(p) ((p) - v->start)
#define LOFF(p) ((long)OFF(p))
-
-
-
+
/*
* forward declarations
*/
/* =====^!^===== begin forwards =====^!^===== */
/* automatically gathered by fwd; do not hand-edit */
/* === regexec.c === */
-int exec _ANSI_ARGS_((regex_t *, CONST chr *, size_t, rm_detail_t *, size_t, regmatch_t [], int));
-static int find _ANSI_ARGS_((struct vars *, struct cnfa *, struct colormap *));
-static int cfind _ANSI_ARGS_((struct vars *, struct cnfa *, struct colormap *));
-static int cfindloop _ANSI_ARGS_((struct vars *, struct cnfa *, struct colormap *, struct dfa *, struct dfa *, chr **));
-static VOID zapsubs _ANSI_ARGS_((regmatch_t *, size_t));
-static VOID zapmem _ANSI_ARGS_((struct vars *, struct subre *));
-static VOID subset _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
-static int dissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
-static int condissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
-static int altdissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
-static int cdissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
-static int ccondissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
-static int crevdissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
-static int cbrdissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
-static int caltdissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
+int exec(regex_t *, CONST chr *, size_t, rm_detail_t *, size_t, regmatch_t [], int);
+static int find(struct vars *, struct cnfa *, struct colormap *);
+static int cfind(struct vars *, struct cnfa *, struct colormap *);
+static int cfindloop(struct vars *, struct cnfa *, struct colormap *, struct dfa *, struct dfa *, chr **);
+static VOID zapsubs(regmatch_t *, size_t);
+static VOID zapmem(struct vars *, struct subre *);
+static VOID subset(struct vars *, struct subre *, chr *, chr *);
+static int dissect(struct vars *, struct subre *, chr *, chr *);
+static int condissect(struct vars *, struct subre *, chr *, chr *);
+static int altdissect(struct vars *, struct subre *, chr *, chr *);
+static int cdissect(struct vars *, struct subre *, chr *, chr *);
+static int ccondissect(struct vars *, struct subre *, chr *, chr *);
+static int crevdissect(struct vars *, struct subre *, chr *, chr *);
+static int cbrdissect(struct vars *, struct subre *, chr *, chr *);
+static int caltdissect(struct vars *, struct subre *, chr *, chr *);
/* === rege_dfa.c === */
-static chr *longest _ANSI_ARGS_((struct vars *, struct dfa *, chr *, chr *, int *));
-static chr *shortest _ANSI_ARGS_((struct vars *, struct dfa *, chr *, chr *, chr *, chr **, int *));
-static chr *lastcold _ANSI_ARGS_((struct vars *, struct dfa *));
-static struct dfa *newdfa _ANSI_ARGS_((struct vars *, struct cnfa *, struct colormap *, struct smalldfa *));
-static VOID freedfa _ANSI_ARGS_((struct dfa *));
-static unsigned hash _ANSI_ARGS_((unsigned *, int));
-static struct sset *initialize _ANSI_ARGS_((struct vars *, struct dfa *, chr *));
-static struct sset *miss _ANSI_ARGS_((struct vars *, struct dfa *, struct sset *, pcolor, chr *, chr *));
-static int lacon _ANSI_ARGS_((struct vars *, struct cnfa *, chr *, pcolor));
-static struct sset *getvacant _ANSI_ARGS_((struct vars *, struct dfa *, chr *, chr *));
-static struct sset *pickss _ANSI_ARGS_((struct vars *, struct dfa *, chr *, chr *));
+static chr *longest(struct vars *, struct dfa *, chr *, chr *, int *);
+static chr *shortest(struct vars *, struct dfa *, chr *, chr *, chr *, chr **, int *);
+static chr *lastcold(struct vars *, struct dfa *);
+static struct dfa *newdfa(struct vars *, struct cnfa *, struct colormap *, struct smalldfa *);
+static VOID freedfa(struct dfa *);
+static unsigned hash(unsigned *, int);
+static struct sset *initialize(struct vars *, struct dfa *, chr *);
+static struct sset *miss(struct vars *, struct dfa *, struct sset *, pcolor, chr *, chr *);
+static int lacon(struct vars *, struct cnfa *, chr *, pcolor);
+static struct sset *getvacant(struct vars *, struct dfa *, chr *, chr *);
+static struct sset *pickss(struct vars *, struct dfa *, chr *, chr *);
/* automatically gathered by fwd; do not hand-edit */
/* =====^!^===== end forwards =====^!^===== */
-
-
-
+
/*
- exec - match regular expression
^ int exec(regex_t *, CONST chr *, size_t, rm_detail_t *,
^ size_t, regmatch_t [], int);
*/
int
-exec(re, string, len, details, nmatch, pmatch, flags)
-regex_t *re;
-CONST chr *string;
-size_t len;
-rm_detail_t *details;
-size_t nmatch;
-regmatch_t pmatch[];
-int flags;
+exec(
+ regex_t *re,
+ CONST chr *string,
+ size_t len,
+ rm_detail_t *details,
+ size_t nmatch,
+ regmatch_t pmatch[],
+ int flags)
{
- struct vars var;
- register struct vars *v = &var;
- int st;
- size_t n;
- int backref;
-# define LOCALMAT 20
- regmatch_t mat[LOCALMAT];
-# define LOCALMEM 40
- regoff_t mem[LOCALMEM];
-
- /* sanity checks */
- if (re == NULL || string == NULL || re->re_magic != REMAGIC)
- return REG_INVARG;
- if (re->re_csize != sizeof(chr))
- return REG_MIXED;
-
- /* setup */
- v->re = re;
- v->g = (struct guts *)re->re_guts;
- if ((v->g->cflags&REG_EXPECT) && details == NULL)
- return REG_INVARG;
- if (v->g->info&REG_UIMPOSSIBLE)
- return REG_NOMATCH;
- backref = (v->g->info&REG_UBACKREF) ? 1 : 0;
- v->eflags = flags;
- if (v->g->cflags&REG_NOSUB)
- nmatch = 0; /* override client */
- v->nmatch = nmatch;
- if (backref) {
- /* need work area */
- if (v->g->nsub + 1 <= LOCALMAT)
- v->pmatch = mat;
- else
- v->pmatch = (regmatch_t *)MALLOC((v->g->nsub + 1) *
- sizeof(regmatch_t));
- if (v->pmatch == NULL)
- return REG_ESPACE;
- v->nmatch = v->g->nsub + 1;
- } else
- v->pmatch = pmatch;
- v->details = details;
- v->start = (chr *)string;
- v->stop = (chr *)string + len;
- v->err = 0;
- if (backref) {
- /* need retry memory */
- assert(v->g->ntree >= 0);
- n = (size_t)v->g->ntree;
- if (n <= LOCALMEM)
- v->mem = mem;
- else
- v->mem = (regoff_t *)MALLOC(n*sizeof(regoff_t));
- if (v->mem == NULL) {
- if (v->pmatch != pmatch && v->pmatch != mat)
- FREE(v->pmatch);
- return REG_ESPACE;
- }
- } else
- v->mem = NULL;
-
- /* do it */
- assert(v->g->tree != NULL);
- if (backref)
- st = cfind(v, &v->g->tree->cnfa, &v->g->cmap);
- else
- st = find(v, &v->g->tree->cnfa, &v->g->cmap);
-
- /* copy (portion of) match vector over if necessary */
- if (st == REG_OKAY && v->pmatch != pmatch && nmatch > 0) {
- zapsubs(pmatch, nmatch);
- n = (nmatch < v->nmatch) ? nmatch : v->nmatch;
- memcpy(VS(pmatch), VS(v->pmatch), n*sizeof(regmatch_t));
+ AllocVars(v);
+ int st;
+ size_t n;
+ int backref;
+#define LOCALMAT 20
+ regmatch_t mat[LOCALMAT];
+#define LOCALMEM 40
+ regoff_t mem[LOCALMEM];
+
+ /*
+ * Sanity checks.
+ */
+
+ if (re == NULL || string == NULL || re->re_magic != REMAGIC) {
+ FreeVars(v);
+ return REG_INVARG;
+ }
+ if (re->re_csize != sizeof(chr)) {
+ FreeVars(v);
+ return REG_MIXED;
+ }
+
+ /*
+ * Setup.
+ */
+
+ v->re = re;
+ v->g = (struct guts *)re->re_guts;
+ if ((v->g->cflags&REG_EXPECT) && details == NULL) {
+ FreeVars(v);
+ return REG_INVARG;
+ }
+ if (v->g->info&REG_UIMPOSSIBLE) {
+ FreeVars(v);
+ return REG_NOMATCH;
+ }
+ backref = (v->g->info&REG_UBACKREF) ? 1 : 0;
+ v->eflags = flags;
+ if (v->g->cflags&REG_NOSUB) {
+ nmatch = 0; /* override client */
+ }
+ v->nmatch = nmatch;
+ if (backref) {
+ /*
+ * Need work area.
+ */
+
+ if (v->g->nsub + 1 <= LOCALMAT) {
+ v->pmatch = mat;
+ } else {
+ v->pmatch = (regmatch_t *)
+ MALLOC((v->g->nsub + 1) * sizeof(regmatch_t));
}
-
- /* clean up */
- if (v->pmatch != pmatch && v->pmatch != mat)
+ if (v->pmatch == NULL) {
+ FreeVars(v);
+ return REG_ESPACE;
+ }
+ v->nmatch = v->g->nsub + 1;
+ } else {
+ v->pmatch = pmatch;
+ }
+ v->details = details;
+ v->start = (chr *)string;
+ v->stop = (chr *)string + len;
+ v->err = 0;
+ if (backref) {
+ /*
+ * Need retry memory.
+ */
+
+ assert(v->g->ntree >= 0);
+ n = (size_t)v->g->ntree;
+ if (n <= LOCALMEM) {
+ v->mem = mem;
+ } else {
+ v->mem = (regoff_t *) MALLOC(n*sizeof(regoff_t));
+ }
+ if (v->mem == NULL) {
+ if (v->pmatch != pmatch && v->pmatch != mat) {
FREE(v->pmatch);
- if (v->mem != NULL && v->mem != mem)
- FREE(v->mem);
- return st;
+ }
+ FreeVars(v);
+ return REG_ESPACE;
+ }
+ } else {
+ v->mem = NULL;
+ }
+
+ /*
+ * Do it.
+ */
+
+ assert(v->g->tree != NULL);
+ if (backref) {
+ st = cfind(v, &v->g->tree->cnfa, &v->g->cmap);
+ } else {
+ st = find(v, &v->g->tree->cnfa, &v->g->cmap);
+ }
+
+ /*
+ * Copy (portion of) match vector over if necessary.
+ */
+
+ if (st == REG_OKAY && v->pmatch != pmatch && nmatch > 0) {
+ zapsubs(pmatch, nmatch);
+ n = (nmatch < v->nmatch) ? nmatch : v->nmatch;
+ memcpy(VS(pmatch), VS(v->pmatch), n*sizeof(regmatch_t));
+ }
+
+ /*
+ * Clean up.
+ */
+
+ if (v->pmatch != pmatch && v->pmatch != mat) {
+ FREE(v->pmatch);
+ }
+ if (v->mem != NULL && v->mem != mem) {
+ FREE(v->mem);
+ }
+ FreeVars(v);
+ return st;
}
-
+
/*
- find - find a match for the main NFA (no-complications case)
^ static int find(struct vars *, struct cnfa *, struct colormap *);
*/
static int
-find(v, cnfa, cm)
-struct vars *v;
-struct cnfa *cnfa;
-struct colormap *cm;
+find(
+ struct vars *v,
+ struct cnfa *cnfa,
+ struct colormap *cm)
{
- struct dfa *s;
- struct dfa *d;
- chr *begin;
- chr *end = NULL;
- chr *cold;
- chr *open; /* open and close of range of possible starts */
- chr *close;
- int hitend;
- int shorter = (v->g->tree->flags&SHORTER) ? 1 : 0;
-
- /* first, a shot with the search RE */
- s = newdfa(v, &v->g->search, cm, &v->dfa1);
- assert(!(ISERR() && s != NULL));
- NOERR();
- MDEBUG(("\nsearch at %ld\n", LOFF(v->start)));
- cold = NULL;
- close = shortest(v, s, v->start, v->start, v->stop, &cold, (int *)NULL);
- freedfa(s);
- NOERR();
- if (v->g->cflags&REG_EXPECT) {
- assert(v->details != NULL);
- if (cold != NULL)
- v->details->rm_extend.rm_so = OFF(cold);
- else
- v->details->rm_extend.rm_so = OFF(v->stop);
- v->details->rm_extend.rm_eo = OFF(v->stop); /* unknown */
+ struct dfa *s;
+ struct dfa *d;
+ chr *begin;
+ chr *end = NULL;
+ chr *cold;
+ chr *open; /* Open and close of range of possible
+ * starts */
+ chr *close;
+ int hitend;
+ int shorter = (v->g->tree->flags&SHORTER) ? 1 : 0;
+
+ /*
+ * First, a shot with the search RE.
+ */
+
+ s = newdfa(v, &v->g->search, cm, &v->dfa1);
+ assert(!(ISERR() && s != NULL));
+ NOERR();
+ MDEBUG(("\nsearch at %ld\n", LOFF(v->start)));
+ cold = NULL;
+ close = shortest(v, s, v->start, v->start, v->stop, &cold, NULL);
+ freedfa(s);
+ NOERR();
+ if (v->g->cflags&REG_EXPECT) {
+ assert(v->details != NULL);
+ if (cold != NULL) {
+ v->details->rm_extend.rm_so = OFF(cold);
+ } else {
+ v->details->rm_extend.rm_so = OFF(v->stop);
+ }
+ v->details->rm_extend.rm_eo = OFF(v->stop); /* unknown */
+ }
+ if (close == NULL) { /* not found */
+ return REG_NOMATCH;
+ }
+ if (v->nmatch == 0) { /* found, don't need exact location */
+ return REG_OKAY;
+ }
+
+ /*
+ * Find starting point and match.
+ */
+
+ assert(cold != NULL);
+ open = cold;
+ cold = NULL;
+ MDEBUG(("between %ld and %ld\n", LOFF(open), LOFF(close)));
+ d = newdfa(v, cnfa, cm, &v->dfa1);
+ assert(!(ISERR() && d != NULL));
+ NOERR();
+ for (begin = open; begin <= close; begin++) {
+ MDEBUG(("\nfind trying at %ld\n", LOFF(begin)));
+ if (shorter) {
+ end = shortest(v, d, begin, begin, v->stop, NULL, &hitend);
+ } else {
+ end = longest(v, d, begin, v->stop, &hitend);
}
- if (close == NULL) /* not found */
- return REG_NOMATCH;
- if (v->nmatch == 0) /* found, don't need exact location */
- return REG_OKAY;
-
- /* find starting point and match */
- assert(cold != NULL);
- open = cold;
- cold = NULL;
- MDEBUG(("between %ld and %ld\n", LOFF(open), LOFF(close)));
- d = newdfa(v, cnfa, cm, &v->dfa1);
- assert(!(ISERR() && d != NULL));
NOERR();
- for (begin = open; begin <= close; begin++) {
- MDEBUG(("\nfind trying at %ld\n", LOFF(begin)));
- if (shorter)
- end = shortest(v, d, begin, begin, v->stop,
- (chr **)NULL, &hitend);
- else
- end = longest(v, d, begin, v->stop, &hitend);
- NOERR();
- if (hitend && cold == NULL)
- cold = begin;
- if (end != NULL)
- break; /* NOTE BREAK OUT */
+ if (hitend && cold == NULL) {
+ cold = begin;
}
- assert(end != NULL); /* search RE succeeded so loop should */
- freedfa(d);
-
- /* and pin down details */
- assert(v->nmatch > 0);
- v->pmatch[0].rm_so = OFF(begin);
- v->pmatch[0].rm_eo = OFF(end);
- if (v->g->cflags&REG_EXPECT) {
- if (cold != NULL)
- v->details->rm_extend.rm_so = OFF(cold);
- else
- v->details->rm_extend.rm_so = OFF(v->stop);
- v->details->rm_extend.rm_eo = OFF(v->stop); /* unknown */
+ if (end != NULL) {
+ break; /* NOTE BREAK OUT */
}
- if (v->nmatch == 1) /* no need for submatches */
- return REG_OKAY;
-
- /* submatches */
- zapsubs(v->pmatch, v->nmatch);
- return dissect(v, v->g->tree, begin, end);
+ }
+ assert(end != NULL); /* search RE succeeded so loop should */
+ freedfa(d);
+
+ /*
+ * And pin down details.
+ */
+
+ assert(v->nmatch > 0);
+ v->pmatch[0].rm_so = OFF(begin);
+ v->pmatch[0].rm_eo = OFF(end);
+ if (v->g->cflags&REG_EXPECT) {
+ if (cold != NULL) {
+ v->details->rm_extend.rm_so = OFF(cold);
+ } else {
+ v->details->rm_extend.rm_so = OFF(v->stop);
+ }
+ v->details->rm_extend.rm_eo = OFF(v->stop); /* unknown */
+ }
+ if (v->nmatch == 1) { /* no need for submatches */
+ return REG_OKAY;
+ }
+
+ /*
+ * Submatches.
+ */
+
+ zapsubs(v->pmatch, v->nmatch);
+ return dissect(v, v->g->tree, begin, end);
}
-
+
/*
- cfind - find a match for the main NFA (with complications)
^ static int cfind(struct vars *, struct cnfa *, struct colormap *);
*/
static int
-cfind(v, cnfa, cm)
-struct vars *v;
-struct cnfa *cnfa;
-struct colormap *cm;
+cfind(
+ struct vars *v,
+ struct cnfa *cnfa,
+ struct colormap *cm)
{
- struct dfa *s;
- struct dfa *d;
- chr *cold = NULL; /* silence gcc 4 warning */
- int ret;
-
- s = newdfa(v, &v->g->search, cm, &v->dfa1);
- NOERR();
- d = newdfa(v, cnfa, cm, &v->dfa2);
- if (ISERR()) {
- assert(d == NULL);
- freedfa(s);
- return v->err;
- }
-
- ret = cfindloop(v, cnfa, cm, d, s, &cold);
-
- freedfa(d);
+ struct dfa *s;
+ struct dfa *d;
+ chr *cold = NULL; /* silence gcc 4 warning */
+ int ret;
+
+ s = newdfa(v, &v->g->search, cm, &v->dfa1);
+ NOERR();
+ d = newdfa(v, cnfa, cm, &v->dfa2);
+ if (ISERR()) {
+ assert(d == NULL);
freedfa(s);
- NOERR();
- if (v->g->cflags&REG_EXPECT) {
- assert(v->details != NULL);
- if (cold != NULL)
- v->details->rm_extend.rm_so = OFF(cold);
- else
- v->details->rm_extend.rm_so = OFF(v->stop);
- v->details->rm_extend.rm_eo = OFF(v->stop); /* unknown */
+ return v->err;
+ }
+
+ ret = cfindloop(v, cnfa, cm, d, s, &cold);
+
+ freedfa(d);
+ freedfa(s);
+ NOERR();
+ if (v->g->cflags&REG_EXPECT) {
+ assert(v->details != NULL);
+ if (cold != NULL) {
+ v->details->rm_extend.rm_so = OFF(cold);
+ } else {
+ v->details->rm_extend.rm_so = OFF(v->stop);
}
- return ret;
+ v->details->rm_extend.rm_eo = OFF(v->stop); /* unknown */
+ }
+ return ret;
}
-
+
/*
- cfindloop - the heart of cfind
^ static int cfindloop(struct vars *, struct cnfa *, struct colormap *,
^ struct dfa *, struct dfa *, chr **);
*/
static int
-cfindloop(v, cnfa, cm, d, s, coldp)
-struct vars *v;
-struct cnfa *cnfa;
-struct colormap *cm;
-struct dfa *d;
-struct dfa *s;
-chr **coldp; /* where to put coldstart pointer */
+cfindloop(
+ struct vars *v,
+ struct cnfa *cnfa,
+ struct colormap *cm,
+ struct dfa *d,
+ struct dfa *s,
+ chr **coldp) /* where to put coldstart pointer */
{
- chr *begin;
- chr *end;
- chr *cold;
- chr *open; /* open and close of range of possible starts */
- chr *close;
- chr *estart;
- chr *estop;
- int er;
- int shorter = v->g->tree->flags&SHORTER;
- int hitend;
-
- assert(d != NULL && s != NULL);
+ chr *begin;
+ chr *end;
+ chr *cold;
+ chr *open; /* Open and close of range of possible
+ * starts */
+ chr *close;
+ chr *estart;
+ chr *estop;
+ int er;
+ int shorter = v->g->tree->flags&SHORTER;
+ int hitend;
+
+ assert(d != NULL && s != NULL);
+ cold = NULL;
+ close = v->start;
+ do {
+ MDEBUG(("\ncsearch at %ld\n", LOFF(close)));
+ close = shortest(v, s, close, close, v->stop, &cold, NULL);
+ if (close == NULL) {
+ break; /* NOTE BREAK */
+ }
+ assert(cold != NULL);
+ open = cold;
cold = NULL;
- close = v->start;
- do {
- MDEBUG(("\ncsearch at %ld\n", LOFF(close)));
- close = shortest(v, s, close, close, v->stop, &cold, (int *)NULL);
- if (close == NULL)
- break; /* NOTE BREAK */
- assert(cold != NULL);
- open = cold;
- cold = NULL;
- MDEBUG(("cbetween %ld and %ld\n", LOFF(open), LOFF(close)));
- for (begin = open; begin <= close; begin++) {
- MDEBUG(("\ncfind trying at %ld\n", LOFF(begin)));
- estart = begin;
- estop = v->stop;
- for (;;) {
- if (shorter)
- end = shortest(v, d, begin, estart,
- estop, (chr **)NULL, &hitend);
- else
- end = longest(v, d, begin, estop,
- &hitend);
- if (hitend && cold == NULL)
- cold = begin;
- if (end == NULL)
- break; /* NOTE BREAK OUT */
- MDEBUG(("tentative end %ld\n", LOFF(end)));
- zapsubs(v->pmatch, v->nmatch);
- zapmem(v, v->g->tree);
- er = cdissect(v, v->g->tree, begin, end);
- if (er == REG_OKAY) {
- if (v->nmatch > 0) {
- v->pmatch[0].rm_so = OFF(begin);
- v->pmatch[0].rm_eo = OFF(end);
- }
- *coldp = cold;
- return REG_OKAY;
- }
- if (er != REG_NOMATCH) {
- ERR(er);
- return er;
- }
- if ((shorter) ? end == estop : end == begin) {
- /* no point in trying again */
- *coldp = cold;
- return REG_NOMATCH;
- }
- /* go around and try again */
- if (shorter)
- estart = end + 1;
- else
- estop = end - 1;
- }
+ MDEBUG(("cbetween %ld and %ld\n", LOFF(open), LOFF(close)));
+ for (begin = open; begin <= close; begin++) {
+ MDEBUG(("\ncfind trying at %ld\n", LOFF(begin)));
+ estart = begin;
+ estop = v->stop;
+ for (;;) {
+ if (shorter) {
+ end = shortest(v, d, begin, estart, estop, NULL, &hitend);
+ } else {
+ end = longest(v, d, begin, estop, &hitend);
+ }
+ if (hitend && cold == NULL) {
+ cold = begin;
+ }
+ if (end == NULL) {
+ break; /* NOTE BREAK OUT */
}
- } while (close < v->stop);
- *coldp = cold;
- return REG_NOMATCH;
-}
+ MDEBUG(("tentative end %ld\n", LOFF(end)));
+ zapsubs(v->pmatch, v->nmatch);
+ zapmem(v, v->g->tree);
+ er = cdissect(v, v->g->tree, begin, end);
+ if (er == REG_OKAY) {
+ if (v->nmatch > 0) {
+ v->pmatch[0].rm_so = OFF(begin);
+ v->pmatch[0].rm_eo = OFF(end);
+ }
+ *coldp = cold;
+ return REG_OKAY;
+ }
+ if (er != REG_NOMATCH) {
+ ERR(er);
+ return er;
+ }
+ if ((shorter) ? end == estop : end == begin) {
+ /*
+ * No point in trying again.
+ */
+
+ *coldp = cold;
+ return REG_NOMATCH;
+ }
+
+ /*
+ * Go around and try again
+ */
+
+ if (shorter) {
+ estart = end + 1;
+ } else {
+ estop = end - 1;
+ }
+ }
+ }
+ } while (close < v->stop);
+ *coldp = cold;
+ return REG_NOMATCH;
+}
+
/*
- zapsubs - initialize the subexpression matches to "no match"
^ static VOID zapsubs(regmatch_t *, size_t);
*/
-static VOID
-zapsubs(p, n)
-regmatch_t *p;
-size_t n;
+static void
+zapsubs(
+ regmatch_t *p,
+ size_t n)
{
- size_t i;
+ size_t i;
- for (i = n-1; i > 0; i--) {
- p[i].rm_so = -1;
- p[i].rm_eo = -1;
- }
+ for (i = n-1; i > 0; i--) {
+ p[i].rm_so = -1;
+ p[i].rm_eo = -1;
+ }
}
-
+
/*
- zapmem - initialize the retry memory of a subtree to zeros
^ static VOID zapmem(struct vars *, struct subre *);
*/
-static VOID
-zapmem(v, t)
-struct vars *v;
-struct subre *t;
+static void
+zapmem(
+ struct vars *v,
+ struct subre *t)
{
- if (t == NULL)
- return;
-
- assert(v->mem != NULL);
- v->mem[t->retry] = 0;
- if (t->op == '(') {
- assert(t->subno > 0);
- v->pmatch[t->subno].rm_so = -1;
+ if (t == NULL) {
+ return;
+ }
+
+ assert(v->mem != NULL);
+ v->mem[t->retry] = 0;
+ if (t->op == '(') {
+ assert(t->subno > 0);
+ v->pmatch[t->subno].rm_so = -1;
v->pmatch[t->subno].rm_eo = -1;
- }
-
- if (t->left != NULL)
- zapmem(v, t->left);
- if (t->right != NULL)
- zapmem(v, t->right);
+ }
+
+ if (t->left != NULL) {
+ zapmem(v, t->left);
+ }
+ if (t->right != NULL) {
+ zapmem(v, t->right);
+ }
}
-
+
/*
- subset - set any subexpression relevant to a successful subre
^ static VOID subset(struct vars *, struct subre *, chr *, chr *);
*/
-static VOID
-subset(v, sub, begin, end)
-struct vars *v;
-struct subre *sub;
-chr *begin;
-chr *end;
+static void
+subset(
+ struct vars *v,
+ struct subre *sub,
+ chr *begin,
+ chr *end)
{
- int n = sub->subno;
+ int n = sub->subno;
- assert(n > 0);
- if ((size_t)n >= v->nmatch)
- return;
+ assert(n > 0);
+ if ((size_t)n >= v->nmatch) {
+ return;
+ }
- MDEBUG(("setting %d\n", n));
- v->pmatch[n].rm_so = OFF(begin);
- v->pmatch[n].rm_eo = OFF(end);
+ MDEBUG(("setting %d\n", n));
+ v->pmatch[n].rm_so = OFF(begin);
+ v->pmatch[n].rm_eo = OFF(end);
}
-
+
/*
- dissect - determine subexpression matches (uncomplicated case)
^ static int dissect(struct vars *, struct subre *, chr *, chr *);
*/
static int /* regexec return code */
-dissect(v, t, begin, end)
-struct vars *v;
-struct subre *t;
-chr *begin; /* beginning of relevant substring */
-chr *end; /* end of same */
+dissect(
+ struct vars *v,
+ struct subre *t,
+ chr *begin, /* beginning of relevant substring */
+ chr *end) /* end of same */
{
- assert(t != NULL);
- MDEBUG(("dissect %ld-%ld\n", LOFF(begin), LOFF(end)));
-
- switch (t->op) {
- case '=': /* terminal node */
- assert(t->left == NULL && t->right == NULL);
- return REG_OKAY; /* no action, parent did the work */
- break;
- case '|': /* alternation */
- assert(t->left != NULL);
- return altdissect(v, t, begin, end);
- break;
- case 'b': /* back ref -- shouldn't be calling us! */
- return REG_ASSERT;
- break;
- case '.': /* concatenation */
- assert(t->left != NULL && t->right != NULL);
- return condissect(v, t, begin, end);
- break;
- case '(': /* capturing */
- assert(t->left != NULL && t->right == NULL);
- assert(t->subno > 0);
- subset(v, t, begin, end);
- return dissect(v, t->left, begin, end);
- break;
- default:
- return REG_ASSERT;
- break;
- }
+ assert(t != NULL);
+ MDEBUG(("dissect %ld-%ld\n", LOFF(begin), LOFF(end)));
+
+ switch (t->op) {
+ case '=': /* terminal node */
+ assert(t->left == NULL && t->right == NULL);
+ return REG_OKAY; /* no action, parent did the work */
+ case '|': /* alternation */
+ assert(t->left != NULL);
+ return altdissect(v, t, begin, end);
+ case 'b': /* back ref -- shouldn't be calling us! */
+ return REG_ASSERT;
+ case '.': /* concatenation */
+ assert(t->left != NULL && t->right != NULL);
+ return condissect(v, t, begin, end);
+ case '(': /* capturing */
+ assert(t->left != NULL && t->right == NULL);
+ assert(t->subno > 0);
+ subset(v, t, begin, end);
+ return dissect(v, t->left, begin, end);
+ default:
+ return REG_ASSERT;
+ }
}
-
+
/*
- condissect - determine concatenation subexpression matches (uncomplicated)
^ static int condissect(struct vars *, struct subre *, chr *, chr *);
*/
static int /* regexec return code */
-condissect(v, t, begin, end)
-struct vars *v;
-struct subre *t;
-chr *begin; /* beginning of relevant substring */
-chr *end; /* end of same */
+condissect(
+ struct vars *v,
+ struct subre *t,
+ chr *begin, /* beginning of relevant substring */
+ chr *end) /* end of same */
{
- struct dfa *d;
- struct dfa *d2;
- chr *mid;
- int i;
- int shorter = (t->left->flags&SHORTER) ? 1 : 0;
- chr *stop = (shorter) ? end : begin;
-
- assert(t->op == '.');
- assert(t->left != NULL && t->left->cnfa.nstates > 0);
- assert(t->right != NULL && t->right->cnfa.nstates > 0);
-
- d = newdfa(v, &t->left->cnfa, &v->g->cmap, &v->dfa1);
- NOERR();
- d2 = newdfa(v, &t->right->cnfa, &v->g->cmap, &v->dfa2);
- if (ISERR()) {
- assert(d2 == NULL);
- freedfa(d);
- return v->err;
+ struct dfa *d;
+ struct dfa *d2;
+ chr *mid;
+ int i;
+ int shorter = (t->left->flags&SHORTER) ? 1 : 0;
+ chr *stop = (shorter) ? end : begin;
+
+ assert(t->op == '.');
+ assert(t->left != NULL && t->left->cnfa.nstates > 0);
+ assert(t->right != NULL && t->right->cnfa.nstates > 0);
+
+ d = newdfa(v, &t->left->cnfa, &v->g->cmap, &v->dfa1);
+ NOERR();
+ d2 = newdfa(v, &t->right->cnfa, &v->g->cmap, &v->dfa2);
+ if (ISERR()) {
+ assert(d2 == NULL);
+ freedfa(d);
+ return v->err;
+ }
+
+ /*
+ * Pick a tentative midpoint.
+ */
+
+ if (shorter) {
+ mid = shortest(v, d, begin, begin, end, NULL, NULL);
+ } else {
+ mid = longest(v, d, begin, end, NULL);
+ }
+ if (mid == NULL) {
+ freedfa(d);
+ freedfa(d2);
+ return REG_ASSERT;
+ }
+ MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
+
+ /*
+ * Iterate until satisfaction or failure.
+ */
+
+ while (longest(v, d2, mid, end, NULL) != end) {
+ /*
+ * That midpoint didn't work, find a new one.
+ */
+
+ if (mid == stop) {
+ /*
+ * All possibilities exhausted!
+ */
+
+ MDEBUG(("no midpoint!\n"));
+ freedfa(d);
+ freedfa(d2);
+ return REG_ASSERT;
}
-
- /* pick a tentative midpoint */
- if (shorter)
- mid = shortest(v, d, begin, begin, end, (chr **)NULL,
- (int *)NULL);
- else
- mid = longest(v, d, begin, end, (int *)NULL);
- if (mid == NULL) {
- freedfa(d);
- freedfa(d2);
- return REG_ASSERT;
+ if (shorter) {
+ mid = shortest(v, d, begin, mid+1, end, NULL, NULL);
+ } else {
+ mid = longest(v, d, begin, mid-1, NULL);
}
- MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
-
- /* iterate until satisfaction or failure */
- while (longest(v, d2, mid, end, (int *)NULL) != end) {
- /* that midpoint didn't work, find a new one */
- if (mid == stop) {
- /* all possibilities exhausted! */
- MDEBUG(("no midpoint!\n"));
- freedfa(d);
- freedfa(d2);
- return REG_ASSERT;
- }
- if (shorter)
- mid = shortest(v, d, begin, mid+1, end, (chr **)NULL,
- (int *)NULL);
- else
- mid = longest(v, d, begin, mid-1, (int *)NULL);
- if (mid == NULL) {
- /* failed to find a new one! */
- MDEBUG(("failed midpoint!\n"));
- freedfa(d);
- freedfa(d2);
- return REG_ASSERT;
- }
- MDEBUG(("new midpoint %ld\n", LOFF(mid)));
+ if (mid == NULL) {
+ /*
+ * Failed to find a new one!
+ */
+
+ MDEBUG(("failed midpoint!\n"));
+ freedfa(d);
+ freedfa(d2);
+ return REG_ASSERT;
}
-
- /* satisfaction */
- MDEBUG(("successful\n"));
- freedfa(d);
- freedfa(d2);
- i = dissect(v, t->left, begin, mid);
- if (i != REG_OKAY)
- return i;
- return dissect(v, t->right, mid, end);
+ MDEBUG(("new midpoint %ld\n", LOFF(mid)));
+ }
+
+ /*
+ * Satisfaction.
+ */
+
+ MDEBUG(("successful\n"));
+ freedfa(d);
+ freedfa(d2);
+ i = dissect(v, t->left, begin, mid);
+ if (i != REG_OKAY) {
+ return i;
+ }
+ return dissect(v, t->right, mid, end);
}
-
+
/*
- altdissect - determine alternative subexpression matches (uncomplicated)
^ static int altdissect(struct vars *, struct subre *, chr *, chr *);
*/
static int /* regexec return code */
-altdissect(v, t, begin, end)
-struct vars *v;
-struct subre *t;
-chr *begin; /* beginning of relevant substring */
-chr *end; /* end of same */
+altdissect(
+ struct vars *v,
+ struct subre *t,
+ chr *begin, /* beginning of relevant substring */
+ chr *end) /* end of same */
{
- struct dfa *d;
- int i;
-
- assert(t != NULL);
- assert(t->op == '|');
-
- for (i = 0; t != NULL; t = t->right, i++) {
- MDEBUG(("trying %dth\n", i));
- assert(t->left != NULL && t->left->cnfa.nstates > 0);
- d = newdfa(v, &t->left->cnfa, &v->g->cmap, &v->dfa1);
- if (ISERR())
- return v->err;
- if (longest(v, d, begin, end, (int *)NULL) == end) {
- MDEBUG(("success\n"));
- freedfa(d);
- return dissect(v, t->left, begin, end);
- }
- freedfa(d);
+ struct dfa *d;
+ int i;
+
+ assert(t != NULL);
+ assert(t->op == '|');
+
+ for (i = 0; t != NULL; t = t->right, i++) {
+ MDEBUG(("trying %dth\n", i));
+ assert(t->left != NULL && t->left->cnfa.nstates > 0);
+ d = newdfa(v, &t->left->cnfa, &v->g->cmap, &v->dfa1);
+ if (ISERR()) {
+ return v->err;
+ }
+ if (longest(v, d, begin, end, NULL) == end) {
+ MDEBUG(("success\n"));
+ freedfa(d);
+ return dissect(v, t->left, begin, end);
}
- return REG_ASSERT; /* none of them matched?!? */
+ freedfa(d);
+ }
+ return REG_ASSERT; /* none of them matched?!? */
}
-
+
/*
- cdissect - determine subexpression matches (with complications)
- * The retry memory stores the offset of the trial midpoint from begin,
- * plus 1 so that 0 uniquely means "clean slate".
+ * The retry memory stores the offset of the trial midpoint from begin, plus 1
+ * so that 0 uniquely means "clean slate".
^ static int cdissect(struct vars *, struct subre *, chr *, chr *);
*/
static int /* regexec return code */
-cdissect(v, t, begin, end)
-struct vars *v;
-struct subre *t;
-chr *begin; /* beginning of relevant substring */
-chr *end; /* end of same */
+cdissect(
+ struct vars *v,
+ struct subre *t,
+ chr *begin, /* beginning of relevant substring */
+ chr *end) /* end of same */
{
- int er;
-
- assert(t != NULL);
- MDEBUG(("cdissect %ld-%ld %c\n", LOFF(begin), LOFF(end), t->op));
-
- switch (t->op) {
- case '=': /* terminal node */
- assert(t->left == NULL && t->right == NULL);
- return REG_OKAY; /* no action, parent did the work */
- break;
- case '|': /* alternation */
- assert(t->left != NULL);
- return caltdissect(v, t, begin, end);
- break;
- case 'b': /* back ref -- shouldn't be calling us! */
- assert(t->left == NULL && t->right == NULL);
- return cbrdissect(v, t, begin, end);
- break;
- case '.': /* concatenation */
- assert(t->left != NULL && t->right != NULL);
- return ccondissect(v, t, begin, end);
- break;
- case '(': /* capturing */
- assert(t->left != NULL && t->right == NULL);
- assert(t->subno > 0);
- er = cdissect(v, t->left, begin, end);
- if (er == REG_OKAY)
- subset(v, t, begin, end);
- return er;
- break;
- default:
- return REG_ASSERT;
- break;
+ int er;
+
+ assert(t != NULL);
+ MDEBUG(("cdissect %ld-%ld %c\n", LOFF(begin), LOFF(end), t->op));
+
+ switch (t->op) {
+ case '=': /* terminal node */
+ assert(t->left == NULL && t->right == NULL);
+ return REG_OKAY; /* no action, parent did the work */
+ case '|': /* alternation */
+ assert(t->left != NULL);
+ return caltdissect(v, t, begin, end);
+ case 'b': /* back ref -- shouldn't be calling us! */
+ assert(t->left == NULL && t->right == NULL);
+ return cbrdissect(v, t, begin, end);
+ case '.': /* concatenation */
+ assert(t->left != NULL && t->right != NULL);
+ return ccondissect(v, t, begin, end);
+ case '(': /* capturing */
+ assert(t->left != NULL && t->right == NULL);
+ assert(t->subno > 0);
+ er = cdissect(v, t->left, begin, end);
+ if (er == REG_OKAY) {
+ subset(v, t, begin, end);
}
+ return er;
+ default:
+ return REG_ASSERT;
+ }
}
-
+
/*
- ccondissect - concatenation subexpression matches (with complications)
- * The retry memory stores the offset of the trial midpoint from begin,
- * plus 1 so that 0 uniquely means "clean slate".
+ * The retry memory stores the offset of the trial midpoint from begin, plus 1
+ * so that 0 uniquely means "clean slate".
^ static int ccondissect(struct vars *, struct subre *, chr *, chr *);
*/
static int /* regexec return code */
-ccondissect(v, t, begin, end)
-struct vars *v;
-struct subre *t;
-chr *begin; /* beginning of relevant substring */
-chr *end; /* end of same */
+ccondissect(
+ struct vars *v,
+ struct subre *t,
+ chr *begin, /* beginning of relevant substring */
+ chr *end) /* end of same */
{
- struct dfa *d;
- struct dfa *d2;
- chr *mid;
- int er;
-
- assert(t->op == '.');
- assert(t->left != NULL && t->left->cnfa.nstates > 0);
- assert(t->right != NULL && t->right->cnfa.nstates > 0);
+ struct dfa *d, *d2;
+ chr *mid;
+ int er;
+
+ assert(t->op == '.');
+ assert(t->left != NULL && t->left->cnfa.nstates > 0);
+ assert(t->right != NULL && t->right->cnfa.nstates > 0);
+
+ if (t->left->flags&SHORTER) { /* reverse scan */
+ return crevdissect(v, t, begin, end);
+ }
+
+ d = newdfa(v, &t->left->cnfa, &v->g->cmap, DOMALLOC);
+ if (ISERR()) {
+ return v->err;
+ }
+ d2 = newdfa(v, &t->right->cnfa, &v->g->cmap, DOMALLOC);
+ if (ISERR()) {
+ freedfa(d);
+ return v->err;
+ }
+ MDEBUG(("cconcat %d\n", t->retry));
- if (t->left->flags&SHORTER) /* reverse scan */
- return crevdissect(v, t, begin, end);
+ /*
+ * Pick a tentative midpoint.
+ */
- d = newdfa(v, &t->left->cnfa, &v->g->cmap, DOMALLOC);
- if (ISERR())
- return v->err;
- d2 = newdfa(v, &t->right->cnfa, &v->g->cmap, DOMALLOC);
- if (ISERR()) {
- freedfa(d);
- return v->err;
+ if (v->mem[t->retry] == 0) {
+ mid = longest(v, d, begin, end, NULL);
+ if (mid == NULL) {
+ freedfa(d);
+ freedfa(d2);
+ return REG_NOMATCH;
}
- MDEBUG(("cconcat %d\n", t->retry));
-
- /* pick a tentative midpoint */
- if (v->mem[t->retry] == 0) {
- mid = longest(v, d, begin, end, (int *)NULL);
- if (mid == NULL) {
- freedfa(d);
- freedfa(d2);
- return REG_NOMATCH;
+ MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
+ v->mem[t->retry] = (mid - begin) + 1;
+ } else {
+ mid = begin + (v->mem[t->retry] - 1);
+ MDEBUG(("working midpoint %ld\n", LOFF(mid)));
+ }
+
+ /*
+ * Iterate until satisfaction or failure.
+ */
+
+ for (;;) {
+ /*
+ * Try this midpoint on for size.
+ */
+
+ if (longest(v, d2, mid, end, NULL) == end) {
+ er = cdissect(v, t->left, begin, mid);
+ if (er == REG_OKAY) {
+ er = cdissect(v, t->right, mid, end);
+ if (er == REG_OKAY) {
+ /*
+ * Satisfaction.
+ */
+
+ MDEBUG(("successful\n"));
+ freedfa(d);
+ freedfa(d2);
+ return REG_OKAY;
}
- MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
- v->mem[t->retry] = (mid - begin) + 1;
- } else {
- mid = begin + (v->mem[t->retry] - 1);
- MDEBUG(("working midpoint %ld\n", LOFF(mid)));
+ }
+ if ((er != REG_OKAY) && (er != REG_NOMATCH)) {
+ freedfa(d);
+ freedfa(d2);
+ return er;
+ }
}
- /* iterate until satisfaction or failure */
- for (;;) {
- /* try this midpoint on for size */
- if (longest(v, d2, mid, end, NULL) == end) {
- er = cdissect(v, t->left, begin, mid);
- if (er == REG_OKAY) {
- er = cdissect(v, t->right, mid, end);
- if (er == REG_OKAY) {
- /* satisfaction */
- MDEBUG(("successful\n"));
- freedfa(d);
- freedfa(d2);
- return REG_OKAY;
- }
- }
- if ((er != REG_OKAY) && (er != REG_NOMATCH)) {
- freedfa(d);
- freedfa(d2);
- return er;
- }
- }
+ /*
+ * That midpoint didn't work, find a new one.
+ */
- /* that midpoint didn't work, find a new one */
- if (mid == begin) {
- /* all possibilities exhausted */
- MDEBUG(("%d no midpoint\n", t->retry));
- freedfa(d);
- freedfa(d2);
- return REG_NOMATCH;
- }
- mid = longest(v, d, begin, mid-1, (int *)NULL);
- if (mid == NULL) {
- /* failed to find a new one */
- MDEBUG(("%d failed midpoint\n", t->retry));
- freedfa(d);
- freedfa(d2);
- return REG_NOMATCH;
- }
- MDEBUG(("%d: new midpoint %ld\n", t->retry, LOFF(mid)));
- v->mem[t->retry] = (mid - begin) + 1;
- zapmem(v, t->left);
- zapmem(v, t->right);
+ if (mid == begin) {
+ /*
+ * All possibilities exhausted.
+ */
+
+ MDEBUG(("%d no midpoint\n", t->retry));
+ freedfa(d);
+ freedfa(d2);
+ return REG_NOMATCH;
}
+ mid = longest(v, d, begin, mid-1, NULL);
+ if (mid == NULL) {
+ /*
+ * Failed to find a new one.
+ */
+
+ MDEBUG(("%d failed midpoint\n", t->retry));
+ freedfa(d);
+ freedfa(d2);
+ return REG_NOMATCH;
+ }
+ MDEBUG(("%d: new midpoint %ld\n", t->retry, LOFF(mid)));
+ v->mem[t->retry] = (mid - begin) + 1;
+ zapmem(v, t->left);
+ zapmem(v, t->right);
+ }
}
-
+
/*
- crevdissect - determine backref shortest-first subexpression matches
- * The retry memory stores the offset of the trial midpoint from begin,
- * plus 1 so that 0 uniquely means "clean slate".
+ * The retry memory stores the offset of the trial midpoint from begin, plus 1
+ * so that 0 uniquely means "clean slate".
^ static int crevdissect(struct vars *, struct subre *, chr *, chr *);
*/
static int /* regexec return code */
-crevdissect(v, t, begin, end)
-struct vars *v;
-struct subre *t;
-chr *begin; /* beginning of relevant substring */
-chr *end; /* end of same */
+crevdissect(
+ struct vars *v,
+ struct subre *t,
+ chr *begin, /* beginning of relevant substring */
+ chr *end) /* end of same */
{
- struct dfa *d;
- struct dfa *d2;
- chr *mid;
- int er;
+ struct dfa *d;
+ struct dfa *d2;
+ chr *mid;
+ int er;
+
+ assert(t->op == '.');
+ assert(t->left != NULL && t->left->cnfa.nstates > 0);
+ assert(t->right != NULL && t->right->cnfa.nstates > 0);
+ assert(t->left->flags&SHORTER);
+
+ /*
+ * Concatenation -- need to split the substring between parts.
+ */
+
+ d = newdfa(v, &t->left->cnfa, &v->g->cmap, DOMALLOC);
+ if (ISERR()) {
+ return v->err;
+ }
+ d2 = newdfa(v, &t->right->cnfa, &v->g->cmap, DOMALLOC);
+ if (ISERR()) {
+ freedfa(d);
+ return v->err;
+ }
+ MDEBUG(("crev %d\n", t->retry));
- assert(t->op == '.');
- assert(t->left != NULL && t->left->cnfa.nstates > 0);
- assert(t->right != NULL && t->right->cnfa.nstates > 0);
- assert(t->left->flags&SHORTER);
+ /*
+ * Pick a tentative midpoint.
+ */
- /* concatenation -- need to split the substring between parts */
- d = newdfa(v, &t->left->cnfa, &v->g->cmap, DOMALLOC);
- if (ISERR())
- return v->err;
- d2 = newdfa(v, &t->right->cnfa, &v->g->cmap, DOMALLOC);
- if (ISERR()) {
- freedfa(d);
- return v->err;
+ if (v->mem[t->retry] == 0) {
+ mid = shortest(v, d, begin, begin, end, NULL, NULL);
+ if (mid == NULL) {
+ freedfa(d);
+ freedfa(d2);
+ return REG_NOMATCH;
}
- MDEBUG(("crev %d\n", t->retry));
-
- /* pick a tentative midpoint */
- if (v->mem[t->retry] == 0) {
- mid = shortest(v, d, begin, begin, end, (chr **)NULL, (int *)NULL);
- if (mid == NULL) {
- freedfa(d);
- freedfa(d2);
- return REG_NOMATCH;
+ MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
+ v->mem[t->retry] = (mid - begin) + 1;
+ } else {
+ mid = begin + (v->mem[t->retry] - 1);
+ MDEBUG(("working midpoint %ld\n", LOFF(mid)));
+ }
+
+ /*
+ * Iterate until satisfaction or failure.
+ */
+
+ for (;;) {
+ /*
+ * Try this midpoint on for size.
+ */
+
+ if (longest(v, d2, mid, end, NULL) == end) {
+ er = cdissect(v, t->left, begin, mid);
+ if (er == REG_OKAY) {
+ er = cdissect(v, t->right, mid, end);
+ if (er == REG_OKAY) {
+ /*
+ * Satisfaction.
+ */
+
+ MDEBUG(("successful\n"));
+ freedfa(d);
+ freedfa(d2);
+ return REG_OKAY;
}
- MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
- v->mem[t->retry] = (mid - begin) + 1;
- } else {
- mid = begin + (v->mem[t->retry] - 1);
- MDEBUG(("working midpoint %ld\n", LOFF(mid)));
+ }
+ if (er != REG_OKAY && er != REG_NOMATCH) {
+ freedfa(d);
+ freedfa(d2);
+ return er;
+ }
}
- /* iterate until satisfaction or failure */
- for (;;) {
- /* try this midpoint on for size */
- if (longest(v, d2, mid, end, NULL) == end) {
- er = cdissect(v, t->left, begin, mid);
- if (er == REG_OKAY) {
- er = cdissect(v, t->right, mid, end);
- if (er == REG_OKAY) {
- /* satisfaction */
- MDEBUG(("successful\n"));
- freedfa(d);
- freedfa(d2);
- return REG_OKAY;
- }
- }
- if (er != REG_OKAY && er != REG_NOMATCH) {
- freedfa(d);
- freedfa(d2);
- return er;
- }
- }
+ /*
+ * That midpoint didn't work, find a new one.
+ */
- /* that midpoint didn't work, find a new one */
- if (mid == end) {
- /* all possibilities exhausted */
- MDEBUG(("%d no midpoint\n", t->retry));
- freedfa(d);
- freedfa(d2);
- return REG_NOMATCH;
- }
- mid = shortest(v, d, begin, mid+1, end, (chr **)NULL, (int *)NULL);
- if (mid == NULL) {
- /* failed to find a new one */
- MDEBUG(("%d failed midpoint\n", t->retry));
- freedfa(d);
- freedfa(d2);
- return REG_NOMATCH;
- }
- MDEBUG(("%d: new midpoint %ld\n", t->retry, LOFF(mid)));
- v->mem[t->retry] = (mid - begin) + 1;
- zapmem(v, t->left);
- zapmem(v, t->right);
+ if (mid == end) {
+ /*
+ * All possibilities exhausted.
+ */
+
+ MDEBUG(("%d no midpoint\n", t->retry));
+ freedfa(d);
+ freedfa(d2);
+ return REG_NOMATCH;
}
+ mid = shortest(v, d, begin, mid+1, end, NULL, NULL);
+ if (mid == NULL) {
+ /*
+ * Failed to find a new one.
+ */
+
+ MDEBUG(("%d failed midpoint\n", t->retry));
+ freedfa(d);
+ freedfa(d2);
+ return REG_NOMATCH;
+ }
+ MDEBUG(("%d: new midpoint %ld\n", t->retry, LOFF(mid)));
+ v->mem[t->retry] = (mid - begin) + 1;
+ zapmem(v, t->left);
+ zapmem(v, t->right);
+ }
}
-
+
/*
- cbrdissect - determine backref subexpression matches
^ static int cbrdissect(struct vars *, struct subre *, chr *, chr *);
*/
static int /* regexec return code */
-cbrdissect(v, t, begin, end)
-struct vars *v;
-struct subre *t;
-chr *begin; /* beginning of relevant substring */
-chr *end; /* end of same */
+cbrdissect(
+ struct vars *v,
+ struct subre *t,
+ chr *begin, /* beginning of relevant substring */
+ chr *end) /* end of same */
{
- int i;
- int n = t->subno;
- size_t len;
- chr *paren;
- chr *p;
- chr *stop;
- int min = t->min;
- int max = t->max;
-
- assert(t != NULL);
- assert(t->op == 'b');
- assert(n >= 0);
- assert((size_t)n < v->nmatch);
-
- MDEBUG(("cbackref n%d %d{%d-%d}\n", t->retry, n, min, max));
-
- if (v->pmatch[n].rm_so == -1)
- return REG_NOMATCH;
- paren = v->start + v->pmatch[n].rm_so;
- len = v->pmatch[n].rm_eo - v->pmatch[n].rm_so;
-
- /* no room to maneuver -- retries are pointless */
- if (v->mem[t->retry])
- return REG_NOMATCH;
- v->mem[t->retry] = 1;
-
- /* special-case zero-length string */
- if (len == 0) {
- if (begin == end)
- return REG_OKAY;
- return REG_NOMATCH;
+ int i;
+ int n = t->subno;
+ size_t len;
+ chr *paren;
+ chr *p;
+ chr *stop;
+ int min = t->min;
+ int max = t->max;
+
+ assert(t != NULL);
+ assert(t->op == 'b');
+ assert(n >= 0);
+ assert((size_t)n < v->nmatch);
+
+ MDEBUG(("cbackref n%d %d{%d-%d}\n", t->retry, n, min, max));
+
+ if (v->pmatch[n].rm_so == -1) {
+ return REG_NOMATCH;
+ }
+ paren = v->start + v->pmatch[n].rm_so;
+ len = v->pmatch[n].rm_eo - v->pmatch[n].rm_so;
+
+ /*
+ * No room to maneuver -- retries are pointless.
+ */
+
+ if (v->mem[t->retry]) {
+ return REG_NOMATCH;
+ }
+ v->mem[t->retry] = 1;
+
+ /*
+ * Special-case zero-length string.
+ */
+
+ if (len == 0) {
+ if (begin == end) {
+ return REG_OKAY;
}
+ return REG_NOMATCH;
+ }
+
+ /*
+ * And too-short string.
+ */
+
+ assert(end >= begin);
+ if ((size_t)(end - begin) < len) {
+ return REG_NOMATCH;
+ }
+ stop = end - len;
+
+ /*
+ * Count occurrences.
+ */
- /* and too-short string */
- assert(end >= begin);
- if ((size_t)(end - begin) < len)
- return REG_NOMATCH;
- stop = end - len;
-
- /* count occurrences */
- i = 0;
- for (p = begin; p <= stop && (i < max || max == INFINITY); p += len) {
- if ((*v->g->compare)(paren, p, len) != 0)
- break;
- i++;
+ i = 0;
+ for (p = begin; p <= stop && (i < max || max == INFINITY); p += len) {
+ if ((*v->g->compare)(paren, p, len) != 0) {
+ break;
}
- MDEBUG(("cbackref found %d\n", i));
-
- /* and sort it out */
- if (p != end) /* didn't consume all of it */
- return REG_NOMATCH;
- if (min <= i && (i <= max || max == INFINITY))
- return REG_OKAY;
- return REG_NOMATCH; /* out of range */
-}
+ i++;
+ }
+ MDEBUG(("cbackref found %d\n", i));
+ /*
+ * And sort it out.
+ */
+
+ if (p != end) { /* didn't consume all of it */
+ return REG_NOMATCH;
+ }
+ if (min <= i && (i <= max || max == INFINITY)) {
+ return REG_OKAY;
+ }
+ return REG_NOMATCH; /* out of range */
+}
+
/*
- caltdissect - determine alternative subexpression matches (w. complications)
^ static int caltdissect(struct vars *, struct subre *, chr *, chr *);
*/
static int /* regexec return code */
-caltdissect(v, t, begin, end)
-struct vars *v;
-struct subre *t;
-chr *begin; /* beginning of relevant substring */
-chr *end; /* end of same */
+caltdissect(
+ struct vars *v,
+ struct subre *t,
+ chr *begin, /* beginning of relevant substring */
+ chr *end) /* end of same */
{
- struct dfa *d;
- int er;
-# define UNTRIED 0 /* not yet tried at all */
-# define TRYING 1 /* top matched, trying submatches */
-# define TRIED 2 /* top didn't match or submatches exhausted */
-
- if (t == NULL)
- return REG_NOMATCH;
- assert(t->op == '|');
- if (v->mem[t->retry] == TRIED)
- return caltdissect(v, t->right, begin, end);
-
- MDEBUG(("calt n%d\n", t->retry));
- assert(t->left != NULL);
+ struct dfa *d;
+ int er;
+#define UNTRIED 0 /* not yet tried at all */
+#define TRYING 1 /* top matched, trying submatches */
+#define TRIED 2 /* top didn't match or submatches exhausted */
- if (v->mem[t->retry] == UNTRIED) {
- d = newdfa(v, &t->left->cnfa, &v->g->cmap, DOMALLOC);
- if (ISERR())
- return v->err;
- if (longest(v, d, begin, end, (int *)NULL) != end) {
- freedfa(d);
- v->mem[t->retry] = TRIED;
- return caltdissect(v, t->right, begin, end);
- }
- freedfa(d);
- MDEBUG(("calt matched\n"));
- v->mem[t->retry] = TRYING;
- }
+ if (t == NULL) {
+ return REG_NOMATCH;
+ }
+ assert(t->op == '|');
+ if (v->mem[t->retry] == TRIED) {
+ return caltdissect(v, t->right, begin, end);
+ }
- er = cdissect(v, t->left, begin, end);
- if (er != REG_NOMATCH)
- return er;
+ MDEBUG(("calt n%d\n", t->retry));
+ assert(t->left != NULL);
- v->mem[t->retry] = TRIED;
- return caltdissect(v, t->right, begin, end);
-}
+ if (v->mem[t->retry] == UNTRIED) {
+ d = newdfa(v, &t->left->cnfa, &v->g->cmap, DOMALLOC);
+ if (ISERR()) {
+ return v->err;
+ }
+ if (longest(v, d, begin, end, NULL) != end) {
+ freedfa(d);
+ v->mem[t->retry] = TRIED;
+ return caltdissect(v, t->right, begin, end);
+ }
+ freedfa(d);
+ MDEBUG(("calt matched\n"));
+ v->mem[t->retry] = TRYING;
+ }
+ er = cdissect(v, t->left, begin, end);
+ if (er != REG_NOMATCH) {
+ return er;
+ }
+ v->mem[t->retry] = TRIED;
+ return caltdissect(v, t->right, begin, end);
+}
#include "rege_dfa.c"
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regfree.c b/generic/regfree.c
index 17a7389..b0aaa70 100644
--- a/generic/regfree.c
+++ b/generic/regfree.c
@@ -2,20 +2,20 @@
* regfree - free an RE
*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
- *
+ *
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author
- * thanks all of them.
- *
+ * thanks all of them.
+ *
* Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
- *
- * I'd appreciate being given credit for this package in the documentation
- * of software which uses it, but that is not a requirement.
- *
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -27,13 +27,11 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- *
- *
- * You might think that this could be incorporated into regcomp.c, and
- * that would be a reasonable idea... except that this is a generic
- * function (with a generic name), applicable to all compiled REs
- * regardless of the size of their characters, whereas the stuff in
- * regcomp.c gets compiled once per character size.
+ * You might think that this could be incorporated into regcomp.c, and that
+ * would be a reasonable idea... except that this is a generic function (with
+ * a generic name), applicable to all compiled REs regardless of the size of
+ * their characters, whereas the stuff in regcomp.c gets compiled once per
+ * character size.
*/
#include "regguts.h"
@@ -43,11 +41,20 @@
*
* Ignoring invocation with NULL is a convenience.
*/
-VOID
-regfree(re)
-regex_t *re;
+void
+regfree(
+ regex_t *re)
{
- if (re == NULL)
- return;
- (*((struct fns *)re->re_fns)->free)(re);
+ if (re == NULL) {
+ return;
+ }
+ (*((struct fns *)re->re_fns)->free)(re);
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regfronts.c b/generic/regfronts.c
index 82f48e2..5003297 100644
--- a/generic/regfronts.c
+++ b/generic/regfronts.c
@@ -1,24 +1,24 @@
/*
* regcomp and regexec - front ends to re_ routines
*
- * Mostly for implementation of backward-compatibility kludges. Note
- * that these routines exist ONLY in char versions.
+ * Mostly for implementation of backward-compatibility kludges. Note that
+ * these routines exist ONLY in char versions.
*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
- *
+ *
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author
- * thanks all of them.
- *
+ * thanks all of them.
+ *
* Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
- *
- * I'd appreciate being given credit for this package in the documentation
- * of software which uses it, but that is not a requirement.
- *
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -29,55 +29,63 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
*/
#include "regguts.h"
-
+
/*
- regcomp - compile regular expression
*/
int
-regcomp(re, str, flags)
-regex_t *re;
-CONST char *str;
-int flags;
+regcomp(
+ regex_t *re,
+ CONST char *str,
+ int flags)
{
- size_t len;
- int f = flags;
+ size_t len;
+ int f = flags;
- if (f&REG_PEND) {
- len = re->re_endp - str;
- f &= ~REG_PEND;
- } else
- len = strlen(str);
+ if (f&REG_PEND) {
+ len = re->re_endp - str;
+ f &= ~REG_PEND;
+ } else {
+ len = strlen(str);
+ }
- return re_comp(re, str, len, f);
+ return re_comp(re, str, len, f);
}
-
+
/*
- regexec - execute regular expression
*/
int
-regexec(re, str, nmatch, pmatch, flags)
-regex_t *re;
-CONST char *str;
-size_t nmatch;
-regmatch_t pmatch[];
-int flags;
+regexec(
+ regex_t *re,
+ CONST char *str,
+ size_t nmatch,
+ regmatch_t pmatch[],
+ int flags)
{
- CONST char *start;
- size_t len;
- int f = flags;
+ CONST char *start;
+ size_t len;
+ int f = flags;
- if (f&REG_STARTEND) {
- start = str + pmatch[0].rm_so;
- len = pmatch[0].rm_eo - pmatch[0].rm_so;
- f &= ~REG_STARTEND;
- } else {
- start = str;
- len = strlen(str);
- }
+ if (f & REG_STARTEND) {
+ start = str + pmatch[0].rm_so;
+ len = pmatch[0].rm_eo - pmatch[0].rm_so;
+ f &= ~REG_STARTEND;
+ } else {
+ start = str;
+ len = strlen(str);
+ }
- return re_exec(re, start, len, nmatch, pmatch, f);
+ return re_exec(re, start, len, nmatch, pmatch, f);
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regguts.h b/generic/regguts.h
index c77a8fc..67e3d03 100644
--- a/generic/regguts.h
+++ b/generic/regguts.h
@@ -2,20 +2,20 @@
* Internal interface definitions, etc., for the reg package
*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
- *
+ *
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author
- * thanks all of them.
- *
+ * thanks all of them.
+ *
* Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
- *
- * I'd appreciate being given credit for this package in the documentation
- * of software which uses it, but that is not a requirement.
- *
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -28,17 +28,13 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
-
/*
- * Environmental customization. It should not (I hope) be necessary to
- * alter the file you are now reading -- regcustom.h should handle it all,
- * given care here and elsewhere.
+ * Environmental customization. It should not (I hope) be necessary to alter
+ * the file you are now reading -- regcustom.h should handle it all, given
+ * care here and elsewhere.
*/
#include "regcustom.h"
-
-
/*
* Things that regcustom.h might override.
*/
@@ -54,34 +50,34 @@
/* assertions */
#ifndef assert
-# ifndef REG_DEBUG
-# ifndef NDEBUG
-# define NDEBUG /* no assertions */
-# endif
-# endif
+#ifndef REG_DEBUG
+#ifndef NDEBUG
+#define NDEBUG /* no assertions */
+#endif
+#endif /* !REG_DEBUG */
#include <assert.h>
#endif
/* voids */
#ifndef VOID
-#define VOID void /* for function return values */
+#define VOID void /* for function return values */
#endif
#ifndef DISCARD
-#define DISCARD VOID /* for throwing values away */
+#define DISCARD void /* for throwing values away */
#endif
#ifndef PVOID
-#define PVOID VOID * /* generic pointer */
+#define PVOID void * /* generic pointer */
#endif
#ifndef VS
-#define VS(x) ((PVOID)(x)) /* cast something to generic ptr */
+#define VS(x) ((void*)(x)) /* cast something to generic ptr */
#endif
#ifndef NOPARMS
-#define NOPARMS VOID /* for empty parm lists */
+#define NOPARMS void /* for empty parm lists */
#endif
/* const */
#ifndef CONST
-#define CONST const /* for old compilers, might be empty */
+#define CONST const /* for old compilers, might be empty */
#endif
/* function-pointer declarator */
@@ -109,11 +105,9 @@
#include <limits.h>
#endif
#ifndef _POSIX2_RE_DUP_MAX
-#define _POSIX2_RE_DUP_MAX 255 /* normally from <limits.h> */
+#define _POSIX2_RE_DUP_MAX 255 /* normally from <limits.h> */
#endif
-
-
/*
* misc
*/
@@ -126,8 +120,6 @@
#define REMAGIC 0xfed7 /* magic number for main struct */
-
-
/*
* debugging facilities
*/
@@ -141,8 +133,6 @@
#define MDEBUG(arglist) {}
#endif
-
-
/*
* bitmap manipulation
*/
@@ -150,14 +140,13 @@
#define BSET(uv, sn) ((uv)[(sn)/UBITS] |= (unsigned)1 << ((sn)%UBITS))
#define ISBSET(uv, sn) ((uv)[(sn)/UBITS] & ((unsigned)1 << ((sn)%UBITS)))
-
-
/*
- * We dissect a chr into byts for colormap table indexing. Here we define
- * a byt, which will be the same as a byte on most machines... The exact
- * size of a byt is not critical, but about 8 bits is good, and extraction
- * of 8-bit chunks is sometimes especially fast.
+ * We dissect a chr into byts for colormap table indexing. Here we define a
+ * byt, which will be the same as a byte on most machines... The exact size of
+ * a byt is not critical, but about 8 bits is good, and extraction of 8-bit
+ * chunks is sometimes especially fast.
*/
+
#ifndef BYTBITS
#define BYTBITS 8 /* bits in a byt */
#endif
@@ -166,69 +155,66 @@
#define NBYTS ((CHRBITS+BYTBITS-1)/BYTBITS)
/* the definition of GETCOLOR(), below, assumes NBYTS <= 4 */
-
-
/*
* As soon as possible, we map chrs into equivalence classes -- "colors" --
* which are of much more manageable number.
*/
+
typedef short color; /* colors of characters */
typedef int pcolor; /* what color promotes to */
#define COLORLESS (-1) /* impossible color */
#define WHITE 0 /* default color, parent of all others */
-
-
/*
- * A colormap is a tree -- more precisely, a DAG -- indexed at each level
- * by a byt of the chr, to map the chr to a color efficiently. Because
- * lower sections of the tree can be shared, it can exploit the usual
- * sparseness of such a mapping table. The tree is always NBYTS levels
- * deep (in the past it was shallower during construction but was "filled"
- * to full depth at the end of that); areas that are unaltered as yet point
- * to "fill blocks" which are entirely WHITE in color.
+ * A colormap is a tree -- more precisely, a DAG -- indexed at each level by a
+ * byt of the chr, to map the chr to a color efficiently. Because lower
+ * sections of the tree can be shared, it can exploit the usual sparseness of
+ * such a mapping table. The tree is always NBYTS levels deep (in the past it
+ * was shallower during construction but was "filled" to full depth at the end
+ * of that); areas that are unaltered as yet point to "fill blocks" which are
+ * entirely WHITE in color.
*/
/* the tree itself */
struct colors {
- color ccolor[BYTTAB];
+ color ccolor[BYTTAB];
};
struct ptrs {
- union tree *pptr[BYTTAB];
+ union tree *pptr[BYTTAB];
};
union tree {
- struct colors colors;
- struct ptrs ptrs;
+ struct colors colors;
+ struct ptrs ptrs;
};
#define tcolor colors.ccolor
#define tptr ptrs.pptr
-/* internal per-color structure for the color machinery */
+/* Internal per-color descriptor structure for the color machinery */
struct colordesc {
- uchr nchrs; /* number of chars of this color */
- color sub; /* open subcolor (if any); free chain ptr */
-# define NOSUB COLORLESS
- struct arc *arcs; /* color chain */
- int flags;
-# define FREECOL 01 /* currently free */
-# define PSEUDO 02 /* pseudocolor, no real chars */
-# define UNUSEDCOLOR(cd) ((cd)->flags&FREECOL)
- union tree *block; /* block of solid color, if any */
+ uchr nchrs; /* number of chars of this color */
+ color sub; /* open subcolor (if any); free chain ptr */
+#define NOSUB COLORLESS
+ struct arc *arcs; /* color chain */
+ int flags;
+#define FREECOL 01 /* currently free */
+#define PSEUDO 02 /* pseudocolor, no real chars */
+#define UNUSEDCOLOR(cd) ((cd)->flags&FREECOL)
+ union tree *block; /* block of solid color, if any */
};
/* the color map itself */
struct colormap {
- int magic;
-# define CMMAGIC 0x876
- struct vars *v; /* for compile error reporting */
- size_t ncds; /* number of colordescs */
- size_t max; /* highest in use */
- color free; /* beginning of free chain (if non-0) */
- struct colordesc *cd;
-# define CDEND(cm) (&(cm)->cd[(cm)->max + 1])
-# define NINLINECDS ((size_t)10)
- struct colordesc cdspace[NINLINECDS];
- union tree tree[NBYTS]; /* tree top, plus fill blocks */
+ int magic;
+#define CMMAGIC 0x876
+ struct vars *v; /* for compile error reporting */
+ size_t ncds; /* number of colordescs */
+ size_t max; /* highest in use */
+ color free; /* beginning of free chain (if non-0) */
+ struct colordesc *cd;
+#define CDEND(cm) (&(cm)->cd[(cm)->max + 1])
+#define NINLINECDS ((size_t)10)
+ struct colordesc cdspace[NINLINECDS];
+ union tree tree[NBYTS]; /* tree top, plus fill blocks */
};
/* optimization magic to do fast chr->color mapping */
@@ -247,182 +233,196 @@ struct colormap {
#define GETCOLOR(cm, c) ((cm)->tree->tptr[B3(c)]->tptr[B2(c)]->tptr[B1(c)]->tcolor[B0(c)])
#endif
-
-
/*
* Interface definitions for locale-interface functions in locale.c.
- * Multi-character collating elements (MCCEs) cause most of the trouble.
*/
+
+/* Representation of a set of characters. */
struct cvec {
- int nchrs; /* number of chrs */
- int chrspace; /* number of chrs possible */
- chr *chrs; /* pointer to vector of chrs */
- int nranges; /* number of ranges (chr pairs) */
- int rangespace; /* number of chrs possible */
- chr *ranges; /* pointer to vector of chr pairs */
- int nmcces; /* number of MCCEs */
- int mccespace; /* number of MCCEs possible */
- int nmccechrs; /* number of chrs used for MCCEs */
- chr *mcces[1]; /* pointers to 0-terminated MCCEs */
- /* and both batches of chrs are on the end */
+ int nchrs; /* number of chrs */
+ int chrspace; /* number of chrs possible */
+ chr *chrs; /* pointer to vector of chrs */
+ int nranges; /* number of ranges (chr pairs) */
+ int rangespace; /* number of chrs possible */
+ chr *ranges; /* pointer to vector of chr pairs */
};
-/* caution: this value cannot be changed easily */
-#define MAXMCCE 2 /* length of longest MCCE */
-
-
-
/*
- * definitions for NFA internal representation
+ * definitions for non-deterministic finite autmaton (NFA) internal
+ * representation
*
- * Having a "from" pointer within each arc may seem redundant, but it
- * saves a lot of hassle.
+ * Having a "from" pointer within each arc may seem redundant, but it saves a
+ * lot of hassle.
*/
+
struct state;
struct arc {
- int type;
-# define ARCFREE '\0'
- color co;
- struct state *from; /* where it's from (and contained within) */
- struct state *to; /* where it's to */
- struct arc *outchain; /* *from's outs chain or free chain */
-# define freechain outchain
- struct arc *inchain; /* *to's ins chain */
- struct arc *colorchain; /* color's arc chain */
- struct arc *colorchain_rev; /* back-link in color's arc chain */
+ int type;
+#define ARCFREE '\0'
+ color co;
+ struct state *from; /* where it's from (and contained within) */
+ struct state *to; /* where it's to */
+ struct arc *outchain; /* *from's outs chain or free chain */
+#define freechain outchain
+ struct arc *inchain; /* *to's ins chain */
+ struct arc *colorchain; /* color's arc chain */
+ struct arc *colorchainRev; /* back-link in color's arc chain */
};
struct arcbatch { /* for bulk allocation of arcs */
- struct arcbatch *next;
-# define ABSIZE 10
- struct arc a[ABSIZE];
+ struct arcbatch *next;
+#define ABSIZE 10
+ struct arc a[ABSIZE];
};
struct state {
- int no;
-# define FREESTATE (-1)
- char flag; /* marks special states */
- int nins; /* number of inarcs */
- struct arc *ins; /* chain of inarcs */
- int nouts; /* number of outarcs */
- struct arc *outs; /* chain of outarcs */
- struct arc *free; /* chain of free arcs */
- struct state *tmp; /* temporary for traversal algorithms */
- struct state *next; /* chain for traversing all */
- struct state *prev; /* back chain */
- struct arcbatch oas; /* first arcbatch, avoid malloc in easy case */
- int noas; /* number of arcs used in first arcbatch */
+ int no;
+#define FREESTATE (-1)
+ char flag; /* marks special states */
+ int nins; /* number of inarcs */
+ struct arc *ins; /* chain of inarcs */
+ int nouts; /* number of outarcs */
+ struct arc *outs; /* chain of outarcs */
+ struct arc *free; /* chain of free arcs */
+ struct state *tmp; /* temporary for traversal algorithms */
+ struct state *next; /* chain for traversing all */
+ struct state *prev; /* back chain */
+ struct arcbatch oas; /* first arcbatch, avoid malloc in easy case */
+ int noas; /* number of arcs used in first arcbatch */
};
struct nfa {
- struct state *pre; /* pre-initial state */
- struct state *init; /* initial state */
- struct state *final; /* final state */
- struct state *post; /* post-final state */
- int nstates; /* for numbering states */
- struct state *states; /* state-chain header */
- struct state *slast; /* tail of the chain */
- struct state *free; /* free list */
- struct colormap *cm; /* the color map */
- color bos[2]; /* colors, if any, assigned to BOS and BOL */
- color eos[2]; /* colors, if any, assigned to EOS and EOL */
- size_t size; /* current NFA size; differs from nstates as
- * it will be incremented by its children */
- struct vars *v; /* simplifies compile error reporting */
- struct nfa *parent; /* parent NFA, if any */
+ struct state *pre; /* pre-initial state */
+ struct state *init; /* initial state */
+ struct state *final; /* final state */
+ struct state *post; /* post-final state */
+ int nstates; /* for numbering states */
+ struct state *states; /* state-chain header */
+ struct state *slast; /* tail of the chain */
+ struct state *free; /* free list */
+ struct colormap *cm; /* the color map */
+ color bos[2]; /* colors, if any, assigned to BOS and BOL */
+ color eos[2]; /* colors, if any, assigned to EOS and EOL */
+ size_t size; /* Current NFA size; differs from nstates as
+ * it also counts the number of states created
+ * by children of this state. */
+ struct vars *v; /* simplifies compile error reporting */
+ struct nfa *parent; /* parent NFA, if any */
};
-
-
/*
* definitions for compacted NFA
*/
+
struct carc {
- color co; /* COLORLESS is list terminator */
- int to; /* state number */
+ color co; /* COLORLESS is list terminator */
+ int to; /* state number */
};
struct cnfa {
- int nstates; /* number of states */
- int ncolors; /* number of colors */
- int flags;
-# define HASLACONS 01 /* uses lookahead constraints */
- int pre; /* setup state number */
- int post; /* teardown state number */
- color bos[2]; /* colors, if any, assigned to BOS and BOL */
- color eos[2]; /* colors, if any, assigned to EOS and EOL */
- struct carc **states; /* vector of pointers to outarc lists */
- struct carc *arcs; /* the area for the lists */
+ int nstates; /* number of states */
+ int ncolors; /* number of colors */
+ int flags;
+#define HASLACONS 01 /* uses lookahead constraints */
+ int pre; /* setup state number */
+ int post; /* teardown state number */
+ color bos[2]; /* colors, if any, assigned to BOS and BOL */
+ color eos[2]; /* colors, if any, assigned to EOS and EOL */
+ struct carc **states; /* vector of pointers to outarc lists */
+ struct carc *arcs; /* the area for the lists */
};
#define ZAPCNFA(cnfa) ((cnfa).nstates = 0)
#define NULLCNFA(cnfa) ((cnfa).nstates == 0)
+/*
+ * Used to limit the maximum NFA size to something sane. [Bug 1810264]
+ */
-/* Used to limit the maximum NFA size */
#ifndef REG_MAX_STATES
-#define REG_MAX_STATES 100000
+# define REG_MAX_STATES 100000
#endif
-
/*
* subexpression tree
*/
+
struct subre {
- char op; /* '|', '.' (concat), 'b' (backref), '(', '=' */
- char flags;
-# define LONGER 01 /* prefers longer match */
-# define SHORTER 02 /* prefers shorter match */
-# define MIXED 04 /* mixed preference below */
-# 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 LMIX(f) ((f)<<2) /* LONGER -> MIXED */
-# define SMIX(f) ((f)<<1) /* SHORTER -> MIXED */
-# define UP(f) (((f)&~LOCAL) | (LMIX(f) & SMIX(f) & MIXED))
-# define MESSY(f) ((f)&(MIXED|CAP|BACKR))
-# define PREF(f) ((f)&LOCAL)
-# 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 */
- int subno; /* subexpression number (for 'b' and '(') */
- short min; /* min repetitions, for backref only */
- short max; /* max repetitions, for backref only */
- struct subre *left; /* left child, if any (also freelist chain) */
- struct subre *right; /* right child, if any */
- struct state *begin; /* outarcs from here... */
- struct state *end; /* ...ending in inarcs here */
- struct cnfa cnfa; /* compacted NFA, if any */
- struct subre *chain; /* for bookkeeping and error cleanup */
+ char op; /* '|', '.' (concat), 'b' (backref), '(',
+ * '=' */
+ char flags;
+#define LONGER 01 /* prefers longer match */
+#define SHORTER 02 /* prefers shorter match */
+#define MIXED 04 /* mixed preference below */
+#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 LMIX(f) ((f)<<2) /* LONGER -> MIXED */
+#define SMIX(f) ((f)<<1) /* SHORTER -> MIXED */
+#define UP(f) (((f)&~LOCAL) | (LMIX(f) & SMIX(f) & MIXED))
+#define MESSY(f) ((f)&(MIXED|CAP|BACKR))
+#define PREF(f) ((f)&LOCAL)
+#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 */
+ int subno; /* subexpression number (for 'b' and '(') */
+ short min; /* min repetitions, for backref only */
+ short max; /* max repetitions, for backref only */
+ struct subre *left; /* left child, if any (also freelist chain) */
+ struct subre *right; /* right child, if any */
+ struct state *begin; /* outarcs from here... */
+ struct state *end; /* ...ending in inarcs here */
+ struct cnfa cnfa; /* compacted NFA, if any */
+ struct subre *chain; /* for bookkeeping and error cleanup */
};
-
-
/*
- * table of function pointers for generic manipulation functions
- * A regex_t's re_fns points to one of these.
+ * table of function pointers for generic manipulation functions. A regex_t's
+ * re_fns points to one of these.
*/
+
struct fns {
- VOID FUNCPTR(free, (regex_t *));
+ VOID FUNCPTR(free, (regex_t *));
};
-
-
/*
* the insides of a regex_t, hidden behind a void *
*/
+
struct guts {
- int magic;
-# define GUTSMAGIC 0xfed9
- int cflags; /* copy of compile flags */
- long info; /* copy of re_info */
- size_t nsub; /* copy of re_nsub */
- struct subre *tree;
- struct cnfa search; /* for fast preliminary search */
- int ntree;
- struct colormap cmap;
- int FUNCPTR(compare, (CONST chr *, CONST chr *, size_t));
- struct subre *lacons; /* lookahead-constraint vector */
- int nlacons; /* size of lacons */
+ int magic;
+#define GUTSMAGIC 0xfed9
+ int cflags; /* copy of compile flags */
+ long info; /* copy of re_info */
+ size_t nsub; /* copy of re_nsub */
+ struct subre *tree;
+ struct cnfa search; /* for fast preliminary search */
+ int ntree;
+ struct colormap cmap;
+ int FUNCPTR(compare, (CONST chr *, CONST chr *, size_t));
+ struct subre *lacons; /* lookahead-constraint vector */
+ int nlacons; /* size of lacons */
};
+
+/*
+ * Magic for allocating a variable workspace. This default version is
+ * stack-hungry.
+ */
+
+#ifndef AllocVars
+#define AllocVars(vPtr) \
+ struct vars var; \
+ register struct vars *vPtr = &var
+#endif
+#ifndef FreeVars
+#define FreeVars(vPtr) ((void) 0)
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tcl.decls b/generic/tcl.decls
index a2fb082..b4fa6b5 100644
--- a/generic/tcl.decls
+++ b/generic/tcl.decls
@@ -4,10 +4,11 @@
# functions that are exported by the Tcl library via the stubs table.
# This file is used to generate the tclDecls.h, tclPlatDecls.h,
# tclStub.c, and tclPlatStub.c files.
-#
#
# Copyright (c) 1998-1999 by Scriptics Corporation.
# Copyright (c) 2001, 2002 by Kevin B. Kenny. All rights reserved.
+# Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
+#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -26,33 +27,34 @@ hooks {tclPlat tclInt tclIntPlat}
# to preserve backwards compatibility.
declare 0 generic {
- int Tcl_PkgProvideEx(Tcl_Interp* interp, CONST char* name,
- CONST char* version, ClientData clientData)
+ int Tcl_PkgProvideEx(Tcl_Interp *interp, CONST char *name,
+ CONST char *version, ClientData clientData)
}
declare 1 generic {
- CONST84_RETURN char * Tcl_PkgRequireEx(Tcl_Interp *interp, CONST char *name,
- CONST char *version, int exact, ClientData *clientDataPtr)
+ CONST84_RETURN char *Tcl_PkgRequireEx(Tcl_Interp *interp,
+ CONST char *name, CONST char *version, int exact,
+ ClientData *clientDataPtr)
}
declare 2 generic {
void Tcl_Panic(CONST char *format, ...)
}
declare 3 generic {
- char * Tcl_Alloc(unsigned int size)
+ char *Tcl_Alloc(unsigned int size)
}
declare 4 generic {
void Tcl_Free(char *ptr)
}
declare 5 generic {
- char * Tcl_Realloc(char *ptr, unsigned int size)
+ char *Tcl_Realloc(char *ptr, unsigned int size)
}
declare 6 generic {
- char * Tcl_DbCkalloc(unsigned int size, CONST char *file, int line)
+ char *Tcl_DbCkalloc(unsigned int size, CONST char *file, int line)
}
declare 7 generic {
int Tcl_DbCkfree(char *ptr, CONST char *file, int line)
}
declare 8 generic {
- char * Tcl_DbCkrealloc(char *ptr, unsigned int size,
+ char *Tcl_DbCkrealloc(char *ptr, unsigned int size,
CONST char *file, int line)
}
@@ -67,7 +69,6 @@ declare 9 unix {
declare 10 unix {
void Tcl_DeleteFileHandler(int fd)
}
-
declare 11 generic {
void Tcl_SetTimer(Tcl_Time *timePtr)
}
@@ -84,10 +85,10 @@ declare 15 generic {
void Tcl_AppendStringsToObj(Tcl_Obj *objPtr, ...)
}
declare 16 generic {
- void Tcl_AppendToObj(Tcl_Obj* objPtr, CONST char* bytes, int length)
+ void Tcl_AppendToObj(Tcl_Obj *objPtr, CONST char *bytes, int length)
}
declare 17 generic {
- Tcl_Obj * Tcl_ConcatObj(int objc, Tcl_Obj *CONST objv[])
+ Tcl_Obj *Tcl_ConcatObj(int objc, Tcl_Obj *CONST objv[])
}
declare 18 generic {
int Tcl_ConvertToType(Tcl_Interp *interp, Tcl_Obj *objPtr,
@@ -103,48 +104,48 @@ declare 21 generic {
int Tcl_DbIsShared(Tcl_Obj *objPtr, CONST char *file, int line)
}
declare 22 generic {
- Tcl_Obj * Tcl_DbNewBooleanObj(int boolValue, CONST char *file, int line)
+ Tcl_Obj *Tcl_DbNewBooleanObj(int boolValue, CONST char *file, int line)
}
declare 23 generic {
- Tcl_Obj * Tcl_DbNewByteArrayObj(CONST unsigned char *bytes, int length,
+ Tcl_Obj *Tcl_DbNewByteArrayObj(CONST unsigned char *bytes, int length,
CONST char *file, int line)
}
declare 24 generic {
- Tcl_Obj * Tcl_DbNewDoubleObj(double doubleValue,
- CONST char *file, int line)
+ Tcl_Obj *Tcl_DbNewDoubleObj(double doubleValue, CONST char *file,
+ int line)
}
declare 25 generic {
- Tcl_Obj * Tcl_DbNewListObj(int objc, Tcl_Obj *CONST *objv,
+ Tcl_Obj *Tcl_DbNewListObj(int objc, Tcl_Obj *CONST *objv,
CONST char *file, int line)
}
declare 26 generic {
- Tcl_Obj * Tcl_DbNewLongObj(long longValue, CONST char *file, int line)
+ Tcl_Obj *Tcl_DbNewLongObj(long longValue, CONST char *file, int line)
}
declare 27 generic {
- Tcl_Obj * Tcl_DbNewObj(CONST char *file, int line)
+ Tcl_Obj *Tcl_DbNewObj(CONST char *file, int line)
}
declare 28 generic {
- Tcl_Obj * Tcl_DbNewStringObj(CONST char *bytes, int length,
+ Tcl_Obj *Tcl_DbNewStringObj(CONST char *bytes, int length,
CONST char *file, int line)
}
declare 29 generic {
- Tcl_Obj * Tcl_DuplicateObj(Tcl_Obj *objPtr)
+ Tcl_Obj *Tcl_DuplicateObj(Tcl_Obj *objPtr)
}
declare 30 generic {
void TclFreeObj(Tcl_Obj *objPtr)
}
declare 31 generic {
- int Tcl_GetBoolean(Tcl_Interp *interp, CONST char *str, int *boolPtr)
+ int Tcl_GetBoolean(Tcl_Interp *interp, CONST char *src, int *boolPtr)
}
declare 32 generic {
int Tcl_GetBooleanFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
int *boolPtr)
}
declare 33 generic {
- unsigned char * Tcl_GetByteArrayFromObj(Tcl_Obj *objPtr, int *lengthPtr)
+ unsigned char *Tcl_GetByteArrayFromObj(Tcl_Obj *objPtr, int *lengthPtr)
}
declare 34 generic {
- int Tcl_GetDouble(Tcl_Interp *interp, CONST char *str, double *doublePtr)
+ int Tcl_GetDouble(Tcl_Interp *interp, CONST char *src, double *doublePtr)
}
declare 35 generic {
int Tcl_GetDoubleFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
@@ -155,7 +156,7 @@ declare 36 generic {
CONST84 char **tablePtr, CONST char *msg, int flags, int *indexPtr)
}
declare 37 generic {
- int Tcl_GetInt(Tcl_Interp *interp, CONST char *str, int *intPtr)
+ int Tcl_GetInt(Tcl_Interp *interp, CONST char *src, int *intPtr)
}
declare 38 generic {
int Tcl_GetIntFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *intPtr)
@@ -164,10 +165,10 @@ declare 39 generic {
int Tcl_GetLongFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, long *longPtr)
}
declare 40 generic {
- Tcl_ObjType * Tcl_GetObjType(CONST char *typeName)
+ Tcl_ObjType *Tcl_GetObjType(CONST char *typeName)
}
declare 41 generic {
- char * Tcl_GetStringFromObj(Tcl_Obj *objPtr, int *lengthPtr)
+ char *Tcl_GetStringFromObj(Tcl_Obj *objPtr, int *lengthPtr)
}
declare 42 generic {
void Tcl_InvalidateStringRep(Tcl_Obj *objPtr)
@@ -200,22 +201,22 @@ declare 49 generic {
Tcl_Obj *Tcl_NewBooleanObj(int boolValue)
}
declare 50 generic {
- Tcl_Obj *Tcl_NewByteArrayObj(CONST unsigned char* bytes, int length)
+ Tcl_Obj *Tcl_NewByteArrayObj(CONST unsigned char *bytes, int length)
}
declare 51 generic {
- Tcl_Obj * Tcl_NewDoubleObj(double doubleValue)
+ Tcl_Obj *Tcl_NewDoubleObj(double doubleValue)
}
declare 52 generic {
- Tcl_Obj * Tcl_NewIntObj(int intValue)
+ Tcl_Obj *Tcl_NewIntObj(int intValue)
}
declare 53 generic {
- Tcl_Obj * Tcl_NewListObj(int objc, Tcl_Obj *CONST objv[])
+ Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj *CONST objv[])
}
declare 54 generic {
- Tcl_Obj * Tcl_NewLongObj(long longValue)
+ Tcl_Obj *Tcl_NewLongObj(long longValue)
}
declare 55 generic {
- Tcl_Obj * Tcl_NewObj(void)
+ Tcl_Obj *Tcl_NewObj(void)
}
declare 56 generic {
Tcl_Obj *Tcl_NewStringObj(CONST char *bytes, int length)
@@ -224,7 +225,7 @@ declare 57 generic {
void Tcl_SetBooleanObj(Tcl_Obj *objPtr, int boolValue)
}
declare 58 generic {
- unsigned char * Tcl_SetByteArrayLength(Tcl_Obj *objPtr, int length)
+ unsigned char *Tcl_SetByteArrayLength(Tcl_Obj *objPtr, int length)
}
declare 59 generic {
void Tcl_SetByteArrayObj(Tcl_Obj *objPtr, CONST unsigned char *bytes,
@@ -246,7 +247,7 @@ declare 64 generic {
void Tcl_SetObjLength(Tcl_Obj *objPtr, int length)
}
declare 65 generic {
- void Tcl_SetStringObj(Tcl_Obj* objPtr, CONST char* bytes, int length)
+ void Tcl_SetStringObj(Tcl_Obj *objPtr, CONST char *bytes, int length)
}
declare 66 generic {
void Tcl_AddErrorInfo(Tcl_Interp *interp, CONST char *message)
@@ -259,7 +260,7 @@ declare 68 generic {
void Tcl_AllowExceptions(Tcl_Interp *interp)
}
declare 69 generic {
- void Tcl_AppendElement(Tcl_Interp *interp, CONST char *string)
+ void Tcl_AppendElement(Tcl_Interp *interp, CONST char *element)
}
declare 70 generic {
void Tcl_AppendResult(Tcl_Interp *interp, ...)
@@ -304,7 +305,7 @@ declare 82 generic {
int Tcl_CommandComplete(CONST char *cmd)
}
declare 83 generic {
- char * Tcl_Concat(int argc, CONST84 char * CONST *argv)
+ char *Tcl_Concat(int argc, CONST84 char *CONST *argv)
}
declare 84 generic {
int Tcl_ConvertElement(CONST char *src, char *dst, int flags)
@@ -316,7 +317,7 @@ declare 85 generic {
declare 86 generic {
int Tcl_CreateAlias(Tcl_Interp *slave, CONST char *slaveCmd,
Tcl_Interp *target, CONST char *targetCmd, int argc,
- CONST84 char * CONST *argv)
+ CONST84 char *CONST *argv)
}
declare 87 generic {
int Tcl_CreateAliasObj(Tcl_Interp *slave, CONST char *slaveCmd,
@@ -348,11 +349,11 @@ declare 93 generic {
void Tcl_CreateExitHandler(Tcl_ExitProc *proc, ClientData clientData)
}
declare 94 generic {
- Tcl_Interp * Tcl_CreateInterp(void)
+ Tcl_Interp *Tcl_CreateInterp(void)
}
declare 95 generic {
void Tcl_CreateMathFunc(Tcl_Interp *interp, CONST char *name,
- int numArgs, Tcl_ValueType *argTypes,
+ int numArgs, Tcl_ValueType *argTypes,
Tcl_MathProc *proc, ClientData clientData)
}
declare 96 generic {
@@ -362,7 +363,7 @@ declare 96 generic {
Tcl_CmdDeleteProc *deleteProc)
}
declare 97 generic {
- Tcl_Interp * Tcl_CreateSlave(Tcl_Interp *interp, CONST char *slaveName,
+ Tcl_Interp *Tcl_CreateSlave(Tcl_Interp *interp, CONST char *slaveName,
int isSafe)
}
declare 98 generic {
@@ -409,7 +410,7 @@ declare 109 generic {
declare 110 generic {
void Tcl_DeleteInterp(Tcl_Interp *interp)
}
-declare 111 {unix win} {
+declare 111 generic {
void Tcl_DetachPids(int numPids, Tcl_Pid *pidPtr)
}
declare 112 generic {
@@ -429,10 +430,10 @@ declare 116 generic {
void Tcl_DoWhenIdle(Tcl_IdleProc *proc, ClientData clientData)
}
declare 117 generic {
- char * Tcl_DStringAppend(Tcl_DString *dsPtr, CONST char *str, int length)
+ char *Tcl_DStringAppend(Tcl_DString *dsPtr, CONST char *bytes, int length)
}
declare 118 generic {
- char * Tcl_DStringAppendElement(Tcl_DString *dsPtr, CONST char *string)
+ char *Tcl_DStringAppendElement(Tcl_DString *dsPtr, CONST char *element)
}
declare 119 generic {
void Tcl_DStringEndSublist(Tcl_DString *dsPtr)
@@ -459,13 +460,13 @@ declare 126 generic {
int Tcl_Eof(Tcl_Channel chan)
}
declare 127 generic {
- CONST84_RETURN char * Tcl_ErrnoId(void)
+ CONST84_RETURN char *Tcl_ErrnoId(void)
}
declare 128 generic {
- CONST84_RETURN char * Tcl_ErrnoMsg(int err)
+ CONST84_RETURN char *Tcl_ErrnoMsg(int err)
}
declare 129 generic {
- int Tcl_Eval(Tcl_Interp *interp, CONST char *string)
+ int Tcl_Eval(Tcl_Interp *interp, CONST char *script)
}
# This is obsolete, use Tcl_FSEvalFile
declare 130 generic {
@@ -485,19 +486,19 @@ declare 134 generic {
CONST char *cmdName)
}
declare 135 generic {
- int Tcl_ExprBoolean(Tcl_Interp *interp, CONST char *str, int *ptr)
+ int Tcl_ExprBoolean(Tcl_Interp *interp, CONST char *expr, int *ptr)
}
declare 136 generic {
int Tcl_ExprBooleanObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *ptr)
}
declare 137 generic {
- int Tcl_ExprDouble(Tcl_Interp *interp, CONST char *str, double *ptr)
+ int Tcl_ExprDouble(Tcl_Interp *interp, CONST char *expr, double *ptr)
}
declare 138 generic {
int Tcl_ExprDoubleObj(Tcl_Interp *interp, Tcl_Obj *objPtr, double *ptr)
}
declare 139 generic {
- int Tcl_ExprLong(Tcl_Interp *interp, CONST char *str, long *ptr)
+ int Tcl_ExprLong(Tcl_Interp *interp, CONST char *expr, long *ptr)
}
declare 140 generic {
int Tcl_ExprLongObj(Tcl_Interp *interp, Tcl_Obj *objPtr, long *ptr)
@@ -507,7 +508,7 @@ declare 141 generic {
Tcl_Obj **resultPtrPtr)
}
declare 142 generic {
- int Tcl_ExprString(Tcl_Interp *interp, CONST char *string)
+ int Tcl_ExprString(Tcl_Interp *interp, CONST char *expr)
}
declare 143 generic {
void Tcl_Finalize(void)
@@ -516,7 +517,7 @@ declare 144 generic {
void Tcl_FindExecutable(CONST char *argv0)
}
declare 145 generic {
- Tcl_HashEntry * Tcl_FirstHashEntry(Tcl_HashTable *tablePtr,
+ Tcl_HashEntry *Tcl_FirstHashEntry(Tcl_HashTable *tablePtr,
Tcl_HashSearch *searchPtr)
}
declare 146 generic {
@@ -557,47 +558,47 @@ declare 155 generic {
int Tcl_GetChannelMode(Tcl_Channel chan)
}
declare 156 generic {
- CONST84_RETURN char * Tcl_GetChannelName(Tcl_Channel chan)
+ CONST84_RETURN char *Tcl_GetChannelName(Tcl_Channel chan)
}
declare 157 generic {
int Tcl_GetChannelOption(Tcl_Interp *interp, Tcl_Channel chan,
CONST char *optionName, Tcl_DString *dsPtr)
}
declare 158 generic {
- Tcl_ChannelType * Tcl_GetChannelType(Tcl_Channel chan)
+ Tcl_ChannelType *Tcl_GetChannelType(Tcl_Channel chan)
}
declare 159 generic {
int Tcl_GetCommandInfo(Tcl_Interp *interp, CONST char *cmdName,
Tcl_CmdInfo *infoPtr)
}
declare 160 generic {
- CONST84_RETURN char * Tcl_GetCommandName(Tcl_Interp *interp,
+ CONST84_RETURN char *Tcl_GetCommandName(Tcl_Interp *interp,
Tcl_Command command)
}
declare 161 generic {
int Tcl_GetErrno(void)
}
declare 162 generic {
- CONST84_RETURN char * Tcl_GetHostName(void)
+ CONST84_RETURN char *Tcl_GetHostName(void)
}
declare 163 generic {
int Tcl_GetInterpPath(Tcl_Interp *askInterp, Tcl_Interp *slaveInterp)
}
declare 164 generic {
- Tcl_Interp * Tcl_GetMaster(Tcl_Interp *interp)
+ Tcl_Interp *Tcl_GetMaster(Tcl_Interp *interp)
}
declare 165 generic {
- CONST char * Tcl_GetNameOfExecutable(void)
+ CONST char *Tcl_GetNameOfExecutable(void)
}
declare 166 generic {
- Tcl_Obj * Tcl_GetObjResult(Tcl_Interp *interp)
+ Tcl_Obj *Tcl_GetObjResult(Tcl_Interp *interp)
}
# Tcl_GetOpenFile is only available on unix, but it is a part of the old
# generic interface, so we inlcude it here for compatibility reasons.
declare 167 unix {
- int Tcl_GetOpenFile(Tcl_Interp *interp, CONST char *str, int forWriting,
+ int Tcl_GetOpenFile(Tcl_Interp *interp, CONST char *chanID, int forWriting,
int checkUsage, ClientData *filePtr)
}
# Obsolete. Should now use Tcl_FSGetPathType which is objectified
@@ -615,20 +616,20 @@ declare 171 generic {
int Tcl_GetServiceMode(void)
}
declare 172 generic {
- Tcl_Interp * Tcl_GetSlave(Tcl_Interp *interp, CONST char *slaveName)
+ Tcl_Interp *Tcl_GetSlave(Tcl_Interp *interp, CONST char *slaveName)
}
declare 173 generic {
Tcl_Channel Tcl_GetStdChannel(int type)
}
declare 174 generic {
- CONST84_RETURN char * Tcl_GetStringResult(Tcl_Interp *interp)
+ CONST84_RETURN char *Tcl_GetStringResult(Tcl_Interp *interp)
}
declare 175 generic {
- CONST84_RETURN char * Tcl_GetVar(Tcl_Interp *interp, CONST char *varName,
+ CONST84_RETURN char *Tcl_GetVar(Tcl_Interp *interp, CONST char *varName,
int flags)
}
declare 176 generic {
- CONST84_RETURN char * Tcl_GetVar2(Tcl_Interp *interp, CONST char *part1,
+ CONST84_RETURN char *Tcl_GetVar2(Tcl_Interp *interp, CONST char *part1,
CONST char *part2, int flags)
}
declare 177 generic {
@@ -661,7 +662,7 @@ declare 185 generic {
}
# Obsolete, use Tcl_FSJoinPath
declare 186 generic {
- char * Tcl_JoinPath(int argc, CONST84 char * CONST *argv,
+ char *Tcl_JoinPath(int argc, CONST84 char *CONST *argv,
Tcl_DString *resultPtr)
}
declare 187 generic {
@@ -671,7 +672,7 @@ declare 187 generic {
# This slot is reserved for use by the plus patch:
# declare 188 generic {
-# Tcl_MainLoop
+# Tcl_MainLoop
# }
declare 189 generic {
@@ -684,23 +685,23 @@ declare 191 generic {
Tcl_Channel Tcl_MakeTcpClientChannel(ClientData tcpSocket)
}
declare 192 generic {
- char * Tcl_Merge(int argc, CONST84 char * CONST *argv)
+ char *Tcl_Merge(int argc, CONST84 char *CONST *argv)
}
declare 193 generic {
- Tcl_HashEntry * Tcl_NextHashEntry(Tcl_HashSearch *searchPtr)
+ Tcl_HashEntry *Tcl_NextHashEntry(Tcl_HashSearch *searchPtr)
}
declare 194 generic {
void Tcl_NotifyChannel(Tcl_Channel channel, int mask)
}
declare 195 generic {
- Tcl_Obj * Tcl_ObjGetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr,
+ Tcl_Obj *Tcl_ObjGetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr,
Tcl_Obj *part2Ptr, int flags)
}
declare 196 generic {
- Tcl_Obj * Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr,
+ Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr,
Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags)
}
-declare 197 {unix win} {
+declare 197 generic {
Tcl_Channel Tcl_OpenCommandChannel(Tcl_Interp *interp, int argc,
CONST84 char **argv, int flags)
}
@@ -725,10 +726,10 @@ declare 202 generic {
void Tcl_PrintDouble(Tcl_Interp *interp, double value, char *dst)
}
declare 203 generic {
- int Tcl_PutEnv(CONST char *string)
+ int Tcl_PutEnv(CONST char *assignment)
}
declare 204 generic {
- CONST84_RETURN char * Tcl_PosixError(Tcl_Interp *interp)
+ CONST84_RETURN char *Tcl_PosixError(Tcl_Interp *interp)
}
declare 205 generic {
void Tcl_QueueEvent(Tcl_Event *evPtr, Tcl_QueuePosition position)
@@ -736,7 +737,7 @@ declare 205 generic {
declare 206 generic {
int Tcl_Read(Tcl_Channel chan, char *bufPtr, int toRead)
}
-declare 207 {unix win} {
+declare 207 generic {
void Tcl_ReapDetachedProcs(void)
}
declare 208 generic {
@@ -752,14 +753,14 @@ declare 211 generic {
void Tcl_RegisterObjType(Tcl_ObjType *typePtr)
}
declare 212 generic {
- Tcl_RegExp Tcl_RegExpCompile(Tcl_Interp *interp, CONST char *string)
+ Tcl_RegExp Tcl_RegExpCompile(Tcl_Interp *interp, CONST char *pattern)
}
declare 213 generic {
int Tcl_RegExpExec(Tcl_Interp *interp, Tcl_RegExp regexp,
- CONST char *str, CONST char *start)
+ CONST char *text, CONST char *start)
}
declare 214 generic {
- int Tcl_RegExpMatch(Tcl_Interp *interp, CONST char *str,
+ int Tcl_RegExpMatch(Tcl_Interp *interp, CONST char *text,
CONST char *pattern)
}
declare 215 generic {
@@ -773,10 +774,10 @@ declare 217 generic {
void Tcl_ResetResult(Tcl_Interp *interp)
}
declare 218 generic {
- int Tcl_ScanElement(CONST char *str, int *flagPtr)
+ int Tcl_ScanElement(CONST char *src, int *flagPtr)
}
declare 219 generic {
- int Tcl_ScanCountedElement(CONST char *str, int length, int *flagPtr)
+ int Tcl_ScanCountedElement(CONST char *src, int length, int *flagPtr)
}
# Obsolete
declare 220 generic {
@@ -819,7 +820,7 @@ declare 231 generic {
int Tcl_SetRecursionLimit(Tcl_Interp *interp, int depth)
}
declare 232 generic {
- void Tcl_SetResult(Tcl_Interp *interp, char *str,
+ void Tcl_SetResult(Tcl_Interp *interp, char *result,
Tcl_FreeProc *freeProc)
}
declare 233 generic {
@@ -835,18 +836,18 @@ declare 236 generic {
void Tcl_SetStdChannel(Tcl_Channel channel, int type)
}
declare 237 generic {
- CONST84_RETURN char * Tcl_SetVar(Tcl_Interp *interp, CONST char *varName,
+ CONST84_RETURN char *Tcl_SetVar(Tcl_Interp *interp, CONST char *varName,
CONST char *newValue, int flags)
}
declare 238 generic {
- CONST84_RETURN char * Tcl_SetVar2(Tcl_Interp *interp, CONST char *part1,
+ CONST84_RETURN char *Tcl_SetVar2(Tcl_Interp *interp, CONST char *part1,
CONST char *part2, CONST char *newValue, int flags)
}
declare 239 generic {
- CONST84_RETURN char * Tcl_SignalId(int sig)
+ CONST84_RETURN char *Tcl_SignalId(int sig)
}
declare 240 generic {
- CONST84_RETURN char * Tcl_SignalMsg(int sig)
+ CONST84_RETURN char *Tcl_SignalMsg(int sig)
}
declare 241 generic {
void Tcl_SourceRCFile(Tcl_Interp *interp)
@@ -879,7 +880,7 @@ declare 248 generic {
int flags, Tcl_VarTraceProc *proc, ClientData clientData)
}
declare 249 generic {
- char * Tcl_TranslateFileName(Tcl_Interp *interp, CONST char *name,
+ char *Tcl_TranslateFileName(Tcl_Interp *interp, CONST char *name,
Tcl_DString *bufferPtr)
}
declare 250 generic {
@@ -943,7 +944,6 @@ declare 265 generic {
declare 266 generic {
void Tcl_ValidateAllMemory(CONST char *file, int line)
}
-
declare 267 generic {
void Tcl_AppendResultVA(Tcl_Interp *interp, va_list argList)
}
@@ -954,27 +954,25 @@ declare 269 generic {
char *Tcl_HashStats(Tcl_HashTable *tablePtr)
}
declare 270 generic {
- CONST84_RETURN char * Tcl_ParseVar(Tcl_Interp *interp, CONST char *str,
+ CONST84_RETURN char *Tcl_ParseVar(Tcl_Interp *interp, CONST char *start,
CONST84 char **termPtr)
}
declare 271 generic {
- CONST84_RETURN char * Tcl_PkgPresent(Tcl_Interp *interp, CONST char *name,
+ CONST84_RETURN char *Tcl_PkgPresent(Tcl_Interp *interp, CONST char *name,
CONST char *version, int exact)
}
declare 272 generic {
- CONST84_RETURN char * Tcl_PkgPresentEx(Tcl_Interp *interp, CONST char *name,
- CONST char *version, int exact, ClientData *clientDataPtr)
+ CONST84_RETURN char *Tcl_PkgPresentEx(Tcl_Interp *interp,
+ CONST char *name, CONST char *version, int exact,
+ ClientData *clientDataPtr)
}
declare 273 generic {
- int Tcl_PkgProvide(Tcl_Interp *interp, CONST char *name,
+ int Tcl_PkgProvide(Tcl_Interp *interp, CONST char *name,
CONST char *version)
}
-
-# TIP #268: The internally used new Require function is in slot
-# 573. Assuming TCL_TIP268 was activated.
-
+# TIP #268: The internally used new Require function is in slot 573.
declare 274 generic {
- CONST84_RETURN char * Tcl_PkgRequire(Tcl_Interp *interp, CONST char *name,
+ CONST84_RETURN char *Tcl_PkgRequire(Tcl_Interp *interp, CONST char *name,
CONST char *version, int exact)
}
declare 275 generic {
@@ -1011,8 +1009,9 @@ declare 280 generic {
# version into the new one).
declare 281 generic {
- Tcl_Channel Tcl_StackChannel(Tcl_Interp *interp, Tcl_ChannelType *typePtr,
- ClientData instanceData, int mask, Tcl_Channel prevChan)
+ Tcl_Channel Tcl_StackChannel(Tcl_Interp *interp,
+ Tcl_ChannelType *typePtr, ClientData instanceData,
+ int mask, Tcl_Channel prevChan)
}
declare 282 generic {
int Tcl_UnstackChannel(Tcl_Interp *interp, Tcl_Channel chan)
@@ -1030,14 +1029,13 @@ declare 284 generic {
# declare 285 generic {
# }
-
# Added in 8.1:
declare 286 generic {
void Tcl_AppendObjToObj(Tcl_Obj *objPtr, Tcl_Obj *appendObjPtr)
}
declare 287 generic {
- Tcl_Encoding Tcl_CreateEncoding(Tcl_EncodingType *typePtr)
+ Tcl_Encoding Tcl_CreateEncoding(CONST Tcl_EncodingType *typePtr)
}
declare 288 generic {
void Tcl_CreateThreadExitHandler(Tcl_ExitProc *proc, ClientData clientData)
@@ -1069,7 +1067,7 @@ declare 295 generic {
int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr)
}
declare 296 generic {
- char * Tcl_ExternalToUtfDString(Tcl_Encoding encoding,
+ char *Tcl_ExternalToUtfDString(Tcl_Encoding encoding,
CONST char *src, int srcLen, Tcl_DString *dsPtr)
}
declare 297 generic {
@@ -1088,21 +1086,21 @@ declare 301 generic {
Tcl_Encoding Tcl_GetEncoding(Tcl_Interp *interp, CONST char *name)
}
declare 302 generic {
- CONST84_RETURN char * Tcl_GetEncodingName(Tcl_Encoding encoding)
+ CONST84_RETURN char *Tcl_GetEncodingName(Tcl_Encoding encoding)
}
declare 303 generic {
void Tcl_GetEncodingNames(Tcl_Interp *interp)
}
declare 304 generic {
int Tcl_GetIndexFromObjStruct(Tcl_Interp *interp, Tcl_Obj *objPtr,
- CONST VOID *tablePtr, int offset, CONST char *msg, int flags,
+ CONST void *tablePtr, int offset, CONST char *msg, int flags,
int *indexPtr)
}
declare 305 generic {
- VOID * Tcl_GetThreadData(Tcl_ThreadDataKey *keyPtr, int size)
+ void *Tcl_GetThreadData(Tcl_ThreadDataKey *keyPtr, int size)
}
declare 306 generic {
- Tcl_Obj * Tcl_GetVar2Ex(Tcl_Interp *interp, CONST char *part1,
+ Tcl_Obj *Tcl_GetVar2Ex(Tcl_Interp *interp, CONST char *part1,
CONST char *part2, int flags)
}
declare 307 generic {
@@ -1122,7 +1120,7 @@ declare 311 generic {
Tcl_Time *timePtr)
}
declare 312 generic {
- int Tcl_NumUtfChars(CONST char *src, int len)
+ int Tcl_NumUtfChars(CONST char *src, int length)
}
declare 313 generic {
int Tcl_ReadChars(Tcl_Channel channel, Tcl_Obj *objPtr, int charsToRead,
@@ -1138,14 +1136,14 @@ declare 316 generic {
int Tcl_SetSystemEncoding(Tcl_Interp *interp, CONST char *name)
}
declare 317 generic {
- Tcl_Obj * Tcl_SetVar2Ex(Tcl_Interp *interp, CONST char *part1,
- CONST char *part2, Tcl_Obj *newValuePtr, int flags)
+ Tcl_Obj *Tcl_SetVar2Ex(Tcl_Interp *interp, CONST char *part1,
+ CONST char *part2, Tcl_Obj *newValuePtr, int flags)
}
declare 318 generic {
void Tcl_ThreadAlert(Tcl_ThreadId threadId)
}
declare 319 generic {
- void Tcl_ThreadQueueEvent(Tcl_ThreadId threadId, Tcl_Event* evPtr,
+ void Tcl_ThreadQueueEvent(Tcl_ThreadId threadId, Tcl_Event *evPtr,
Tcl_QueuePosition position)
}
declare 320 generic {
@@ -1164,25 +1162,25 @@ declare 324 generic {
int Tcl_UniCharToUtf(int ch, char *buf)
}
declare 325 generic {
- CONST84_RETURN char * Tcl_UtfAtIndex(CONST char *src, int index)
+ CONST84_RETURN char *Tcl_UtfAtIndex(CONST char *src, int index)
}
declare 326 generic {
- int Tcl_UtfCharComplete(CONST char *src, int len)
+ int Tcl_UtfCharComplete(CONST char *src, int length)
}
declare 327 generic {
int Tcl_UtfBackslash(CONST char *src, int *readPtr, char *dst)
}
declare 328 generic {
- CONST84_RETURN char * Tcl_UtfFindFirst(CONST char *src, int ch)
+ CONST84_RETURN char *Tcl_UtfFindFirst(CONST char *src, int ch)
}
declare 329 generic {
- CONST84_RETURN char * Tcl_UtfFindLast(CONST char *src, int ch)
+ CONST84_RETURN char *Tcl_UtfFindLast(CONST char *src, int ch)
}
declare 330 generic {
- CONST84_RETURN char * Tcl_UtfNext(CONST char *src)
+ CONST84_RETURN char *Tcl_UtfNext(CONST char *src)
}
declare 331 generic {
- CONST84_RETURN char * Tcl_UtfPrev(CONST char *src, CONST char *start)
+ CONST84_RETURN char *Tcl_UtfPrev(CONST char *src, CONST char *start)
}
declare 332 generic {
int Tcl_UtfToExternal(Tcl_Interp *interp, Tcl_Encoding encoding,
@@ -1191,7 +1189,7 @@ declare 332 generic {
int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr)
}
declare 333 generic {
- char * Tcl_UtfToExternalDString(Tcl_Encoding encoding,
+ char *Tcl_UtfToExternalDString(Tcl_Encoding encoding,
CONST char *src, int srcLen, Tcl_DString *dsPtr)
}
declare 334 generic {
@@ -1213,10 +1211,10 @@ declare 339 generic {
int Tcl_WriteObj(Tcl_Channel chan, Tcl_Obj *objPtr)
}
declare 340 generic {
- char * Tcl_GetString(Tcl_Obj *objPtr)
+ char *Tcl_GetString(Tcl_Obj *objPtr)
}
declare 341 generic {
- CONST84_RETURN char * Tcl_GetDefaultEncodingDir(void)
+ CONST84_RETURN char *Tcl_GetDefaultEncodingDir(void)
}
declare 342 generic {
void Tcl_SetDefaultEncodingDir(CONST char *path)
@@ -1249,25 +1247,24 @@ declare 351 generic {
int Tcl_UniCharIsWordChar(int ch)
}
declare 352 generic {
- int Tcl_UniCharLen(CONST Tcl_UniChar *str)
+ int Tcl_UniCharLen(CONST Tcl_UniChar *uniStr)
}
declare 353 generic {
- int Tcl_UniCharNcmp(CONST Tcl_UniChar *cs, CONST Tcl_UniChar *ct,
- unsigned long n)
+ int Tcl_UniCharNcmp(CONST Tcl_UniChar *ucs, CONST Tcl_UniChar *uct,
+ unsigned long numChars)
}
declare 354 generic {
- char * Tcl_UniCharToUtfDString(CONST Tcl_UniChar *string,
- int numChars, Tcl_DString *dsPtr)
+ char *Tcl_UniCharToUtfDString(CONST Tcl_UniChar *uniStr,
+ int uniLength, Tcl_DString *dsPtr)
}
declare 355 generic {
- Tcl_UniChar * Tcl_UtfToUniCharDString(CONST char *string,
+ Tcl_UniChar *Tcl_UtfToUniCharDString(CONST char *src,
int length, Tcl_DString *dsPtr)
}
declare 356 generic {
Tcl_RegExp Tcl_GetRegExpFromObj(Tcl_Interp *interp, Tcl_Obj *patObj,
int flags)
}
-
declare 357 generic {
Tcl_Obj *Tcl_EvalTokens(Tcl_Interp *interp, Tcl_Token *tokenPtr,
int count)
@@ -1280,24 +1277,24 @@ declare 359 generic {
CONST char *command, int length)
}
declare 360 generic {
- int Tcl_ParseBraces(Tcl_Interp *interp, CONST char *string, int numBytes,
+ int Tcl_ParseBraces(Tcl_Interp *interp, CONST char *start, int numBytes,
Tcl_Parse *parsePtr, int append, CONST84 char **termPtr)
}
declare 361 generic {
- int Tcl_ParseCommand(Tcl_Interp *interp, CONST char *string, int numBytes,
+ int Tcl_ParseCommand(Tcl_Interp *interp, CONST char *start, int numBytes,
int nested, Tcl_Parse *parsePtr)
}
declare 362 generic {
- int Tcl_ParseExpr(Tcl_Interp *interp, CONST char *string, int numBytes,
- Tcl_Parse *parsePtr)
+ int Tcl_ParseExpr(Tcl_Interp *interp, CONST char *start, int numBytes,
+ Tcl_Parse *parsePtr)
}
declare 363 generic {
- int Tcl_ParseQuotedString(Tcl_Interp *interp, CONST char *string,
+ int Tcl_ParseQuotedString(Tcl_Interp *interp, CONST char *start,
int numBytes, Tcl_Parse *parsePtr, int append,
CONST84 char **termPtr)
}
declare 364 generic {
- int Tcl_ParseVarName(Tcl_Interp *interp, CONST char *string, int numBytes,
+ int Tcl_ParseVarName(Tcl_Interp *interp, CONST char *start, int numBytes,
Tcl_Parse *parsePtr, int append)
}
# These 4 functions are obsolete, use Tcl_FSGetCwd, Tcl_FSChdir,
@@ -1337,13 +1334,13 @@ declare 375 generic {
}
declare 376 generic {
int Tcl_RegExpExecObj(Tcl_Interp *interp, Tcl_RegExp regexp,
- Tcl_Obj *objPtr, int offset, int nmatches, int flags)
+ Tcl_Obj *textObj, int offset, int nmatches, int flags)
}
declare 377 generic {
void Tcl_RegExpGetInfo(Tcl_RegExp regexp, Tcl_RegExpInfo *infoPtr)
}
declare 378 generic {
- Tcl_Obj * Tcl_NewUnicodeObj(CONST Tcl_UniChar *unicode, int numChars)
+ Tcl_Obj *Tcl_NewUnicodeObj(CONST Tcl_UniChar *unicode, int numChars)
}
declare 379 generic {
void Tcl_SetUnicodeObj(Tcl_Obj *objPtr, CONST Tcl_UniChar *unicode,
@@ -1356,24 +1353,24 @@ declare 381 generic {
Tcl_UniChar Tcl_GetUniChar(Tcl_Obj *objPtr, int index)
}
declare 382 generic {
- Tcl_UniChar * Tcl_GetUnicode(Tcl_Obj *objPtr)
+ Tcl_UniChar *Tcl_GetUnicode(Tcl_Obj *objPtr)
}
declare 383 generic {
- Tcl_Obj * Tcl_GetRange(Tcl_Obj *objPtr, int first, int last)
+ Tcl_Obj *Tcl_GetRange(Tcl_Obj *objPtr, int first, int last)
}
declare 384 generic {
void Tcl_AppendUnicodeToObj(Tcl_Obj *objPtr, CONST Tcl_UniChar *unicode,
int length)
}
declare 385 generic {
- int Tcl_RegExpMatchObj(Tcl_Interp *interp, Tcl_Obj *stringObj,
+ int Tcl_RegExpMatchObj(Tcl_Interp *interp, Tcl_Obj *textObj,
Tcl_Obj *patternObj)
}
declare 386 generic {
void Tcl_SetNotifier(Tcl_NotifierProcs *notifierProcPtr)
}
declare 387 generic {
- Tcl_Mutex * Tcl_GetAllocMutex(void)
+ Tcl_Mutex *Tcl_GetAllocMutex(void)
}
declare 388 generic {
int Tcl_GetChannelNames(Tcl_Interp *interp)
@@ -1410,62 +1407,70 @@ declare 397 generic {
int Tcl_ChannelBuffered(Tcl_Channel chan)
}
declare 398 generic {
- CONST84_RETURN char * Tcl_ChannelName(Tcl_ChannelType *chanTypePtr)
+ CONST84_RETURN char *Tcl_ChannelName(CONST Tcl_ChannelType *chanTypePtr)
}
declare 399 generic {
- Tcl_ChannelTypeVersion Tcl_ChannelVersion(Tcl_ChannelType *chanTypePtr)
+ Tcl_ChannelTypeVersion Tcl_ChannelVersion(
+ CONST Tcl_ChannelType *chanTypePtr)
}
declare 400 generic {
- Tcl_DriverBlockModeProc * Tcl_ChannelBlockModeProc(Tcl_ChannelType
- *chanTypePtr)
+ Tcl_DriverBlockModeProc *Tcl_ChannelBlockModeProc(
+ CONST Tcl_ChannelType *chanTypePtr)
}
declare 401 generic {
- Tcl_DriverCloseProc * Tcl_ChannelCloseProc(Tcl_ChannelType *chanTypePtr)
+ Tcl_DriverCloseProc *Tcl_ChannelCloseProc(
+ CONST Tcl_ChannelType *chanTypePtr)
}
declare 402 generic {
- Tcl_DriverClose2Proc * Tcl_ChannelClose2Proc(Tcl_ChannelType *chanTypePtr)
+ Tcl_DriverClose2Proc *Tcl_ChannelClose2Proc(
+ CONST Tcl_ChannelType *chanTypePtr)
}
declare 403 generic {
- Tcl_DriverInputProc * Tcl_ChannelInputProc(Tcl_ChannelType *chanTypePtr)
+ Tcl_DriverInputProc *Tcl_ChannelInputProc(
+ CONST Tcl_ChannelType *chanTypePtr)
}
declare 404 generic {
- Tcl_DriverOutputProc * Tcl_ChannelOutputProc(Tcl_ChannelType *chanTypePtr)
+ Tcl_DriverOutputProc *Tcl_ChannelOutputProc(
+ CONST Tcl_ChannelType *chanTypePtr)
}
declare 405 generic {
- Tcl_DriverSeekProc * Tcl_ChannelSeekProc(Tcl_ChannelType *chanTypePtr)
+ Tcl_DriverSeekProc *Tcl_ChannelSeekProc(
+ CONST Tcl_ChannelType *chanTypePtr)
}
declare 406 generic {
- Tcl_DriverSetOptionProc * Tcl_ChannelSetOptionProc(Tcl_ChannelType
- *chanTypePtr)
+ Tcl_DriverSetOptionProc *Tcl_ChannelSetOptionProc(
+ CONST Tcl_ChannelType *chanTypePtr)
}
declare 407 generic {
- Tcl_DriverGetOptionProc * Tcl_ChannelGetOptionProc(Tcl_ChannelType
- *chanTypePtr)
+ Tcl_DriverGetOptionProc *Tcl_ChannelGetOptionProc(
+ CONST Tcl_ChannelType *chanTypePtr)
}
declare 408 generic {
- Tcl_DriverWatchProc * Tcl_ChannelWatchProc(Tcl_ChannelType *chanTypePtr)
+ Tcl_DriverWatchProc *Tcl_ChannelWatchProc(
+ CONST Tcl_ChannelType *chanTypePtr)
}
declare 409 generic {
- Tcl_DriverGetHandleProc * Tcl_ChannelGetHandleProc(Tcl_ChannelType
- *chanTypePtr)
+ Tcl_DriverGetHandleProc *Tcl_ChannelGetHandleProc(
+ CONST Tcl_ChannelType *chanTypePtr)
}
declare 410 generic {
- Tcl_DriverFlushProc * Tcl_ChannelFlushProc(Tcl_ChannelType *chanTypePtr)
+ Tcl_DriverFlushProc *Tcl_ChannelFlushProc(
+ CONST Tcl_ChannelType *chanTypePtr)
}
declare 411 generic {
- Tcl_DriverHandlerProc * Tcl_ChannelHandlerProc(Tcl_ChannelType
- *chanTypePtr)
+ Tcl_DriverHandlerProc *Tcl_ChannelHandlerProc(
+ CONST Tcl_ChannelType *chanTypePtr)
}
# Introduced in 8.4a2
declare 412 generic {
- int Tcl_JoinThread(Tcl_ThreadId threadId, int* result)
+ int Tcl_JoinThread(Tcl_ThreadId threadId, int *result)
}
declare 413 generic {
int Tcl_IsChannelShared(Tcl_Channel channel)
}
declare 414 generic {
- int Tcl_IsChannelRegistered(Tcl_Interp* interp, Tcl_Channel channel)
+ int Tcl_IsChannelRegistered(Tcl_Interp *interp, Tcl_Channel channel)
}
declare 415 generic {
void Tcl_CutChannel(Tcl_Channel channel)
@@ -1477,32 +1482,27 @@ declare 417 generic {
void Tcl_ClearChannelHandlers(Tcl_Channel channel)
}
declare 418 generic {
- int Tcl_IsChannelExisting(CONST char* channelName)
+ int Tcl_IsChannelExisting(CONST char *channelName)
}
-
declare 419 generic {
- int Tcl_UniCharNcasecmp(CONST Tcl_UniChar *cs, CONST Tcl_UniChar *ct,
- unsigned long n)
+ int Tcl_UniCharNcasecmp(CONST Tcl_UniChar *ucs, CONST Tcl_UniChar *uct,
+ unsigned long numChars)
}
declare 420 generic {
- int Tcl_UniCharCaseMatch(CONST Tcl_UniChar *ustr,
- CONST Tcl_UniChar *pattern, int nocase)
+ int Tcl_UniCharCaseMatch(CONST Tcl_UniChar *uniStr,
+ CONST Tcl_UniChar *uniPattern, int nocase)
}
-
declare 421 generic {
Tcl_HashEntry *Tcl_FindHashEntry(Tcl_HashTable *tablePtr, CONST char *key)
}
-
declare 422 generic {
Tcl_HashEntry *Tcl_CreateHashEntry(Tcl_HashTable *tablePtr,
CONST char *key, int *newPtr)
}
-
declare 423 generic {
void Tcl_InitCustomHashTable(Tcl_HashTable *tablePtr, int keyType,
Tcl_HashKeyType *typePtr)
}
-
declare 424 generic {
void Tcl_InitObjHashTable(Tcl_HashTable *tablePtr)
}
@@ -1520,46 +1520,54 @@ declare 427 generic {
int flags, Tcl_CommandTraceProc *proc, ClientData clientData)
}
declare 428 generic {
- char * Tcl_AttemptAlloc(unsigned int size)
+ char *Tcl_AttemptAlloc(unsigned int size)
}
declare 429 generic {
- char * Tcl_AttemptDbCkalloc(unsigned int size, CONST char *file, int line)
+ char *Tcl_AttemptDbCkalloc(unsigned int size, CONST char *file, int line)
}
declare 430 generic {
- char * Tcl_AttemptRealloc(char *ptr, unsigned int size)
+ char *Tcl_AttemptRealloc(char *ptr, unsigned int size)
}
declare 431 generic {
- char * Tcl_AttemptDbCkrealloc(char *ptr, unsigned int size,
+ char *Tcl_AttemptDbCkrealloc(char *ptr, unsigned int size,
CONST char *file, int line)
}
declare 432 generic {
int Tcl_AttemptSetObjLength(Tcl_Obj *objPtr, int length)
}
+
+# TIP#10 (thread-aware channels) akupries
declare 433 generic {
Tcl_ThreadId Tcl_GetChannelThread(Tcl_Channel channel)
}
+
# introduced in 8.4a3
declare 434 generic {
- Tcl_UniChar * Tcl_GetUnicodeFromObj(Tcl_Obj *objPtr, int *lengthPtr)
+ Tcl_UniChar *Tcl_GetUnicodeFromObj(Tcl_Obj *objPtr, int *lengthPtr)
}
+
+# TIP#15 (math function introspection) dkf
declare 435 generic {
int Tcl_GetMathFuncInfo(Tcl_Interp *interp, CONST char *name,
int *numArgsPtr, Tcl_ValueType **argTypesPtr,
Tcl_MathProc **procPtr, ClientData *clientDataPtr)
}
declare 436 generic {
- Tcl_Obj * Tcl_ListMathFuncs(Tcl_Interp *interp, CONST char *pattern)
+ Tcl_Obj *Tcl_ListMathFuncs(Tcl_Interp *interp, CONST char *pattern)
}
+
+# TIP#36 (better access to 'subst') dkf
declare 437 generic {
- Tcl_Obj * Tcl_SubstObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags)
+ Tcl_Obj *Tcl_SubstObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags)
}
+
+# TIP#17 (virtual filesystem layer) vdarley
declare 438 generic {
- int Tcl_DetachChannel(Tcl_Interp* interp, Tcl_Channel channel)
+ int Tcl_DetachChannel(Tcl_Interp *interp, Tcl_Channel channel)
}
declare 439 generic {
int Tcl_IsStandardChannel(Tcl_Channel channel)
}
-# New functions due to TIP#17
declare 440 generic {
int Tcl_FSCopyFile(Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr)
}
@@ -1574,11 +1582,9 @@ declare 443 generic {
int Tcl_FSDeleteFile(Tcl_Obj *pathPtr)
}
declare 444 generic {
- int Tcl_FSLoadFile(Tcl_Interp * interp,
- Tcl_Obj *pathPtr, CONST char * sym1, CONST char * sym2,
- Tcl_PackageInitProc ** proc1Ptr,
- Tcl_PackageInitProc ** proc2Ptr,
- Tcl_LoadHandle * handlePtr,
+ int Tcl_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *pathPtr, CONST char *sym1,
+ CONST char *sym2, Tcl_PackageInitProc **proc1Ptr,
+ Tcl_PackageInitProc **proc2Ptr, Tcl_LoadHandle *handlePtr,
Tcl_FSUnloadFileProc **unloadProcPtr)
}
declare 445 generic {
@@ -1586,7 +1592,7 @@ declare 445 generic {
Tcl_Obj *pathPtr, CONST char *pattern, Tcl_GlobTypeData *types)
}
declare 446 generic {
- Tcl_Obj * Tcl_FSLink(Tcl_Obj *pathPtr, Tcl_Obj *toPtr, int linkAction)
+ Tcl_Obj *Tcl_FSLink(Tcl_Obj *pathPtr, Tcl_Obj *toPtr, int linkAction)
}
declare 447 generic {
int Tcl_FSRemoveDirectory(Tcl_Obj *pathPtr,
@@ -1610,7 +1616,8 @@ declare 452 generic {
int index, Tcl_Obj *pathPtr, Tcl_Obj *objPtr)
}
declare 453 generic {
- CONST char ** Tcl_FSFileAttrStrings(Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef)
+ CONST char **Tcl_FSFileAttrStrings(Tcl_Obj *pathPtr,
+ Tcl_Obj **objPtrRef)
}
declare 454 generic {
int Tcl_FSStat(Tcl_Obj *pathPtr, Tcl_StatBuf *buf)
@@ -1623,7 +1630,7 @@ declare 456 generic {
CONST char *modeString, int permissions)
}
declare 457 generic {
- Tcl_Obj* Tcl_FSGetCwd(Tcl_Interp *interp)
+ Tcl_Obj *Tcl_FSGetCwd(Tcl_Interp *interp)
}
declare 458 generic {
int Tcl_FSChdir(Tcl_Obj *pathPtr)
@@ -1632,46 +1639,46 @@ declare 459 generic {
int Tcl_FSConvertToPathType(Tcl_Interp *interp, Tcl_Obj *pathPtr)
}
declare 460 generic {
- Tcl_Obj* Tcl_FSJoinPath(Tcl_Obj *listObj, int elements)
+ Tcl_Obj *Tcl_FSJoinPath(Tcl_Obj *listObj, int elements)
}
declare 461 generic {
- Tcl_Obj* Tcl_FSSplitPath(Tcl_Obj* pathPtr, int *lenPtr)
+ Tcl_Obj *Tcl_FSSplitPath(Tcl_Obj *pathPtr, int *lenPtr)
}
declare 462 generic {
- int Tcl_FSEqualPaths(Tcl_Obj* firstPtr, Tcl_Obj* secondPtr)
+ int Tcl_FSEqualPaths(Tcl_Obj *firstPtr, Tcl_Obj *secondPtr)
}
declare 463 generic {
- Tcl_Obj* Tcl_FSGetNormalizedPath(Tcl_Interp *interp, Tcl_Obj* pathObjPtr)
+ Tcl_Obj *Tcl_FSGetNormalizedPath(Tcl_Interp *interp, Tcl_Obj *pathPtr)
}
declare 464 generic {
- Tcl_Obj* Tcl_FSJoinToPath(Tcl_Obj *basePtr, int objc,
+ Tcl_Obj *Tcl_FSJoinToPath(Tcl_Obj *pathPtr, int objc,
Tcl_Obj *CONST objv[])
}
declare 465 generic {
- ClientData Tcl_FSGetInternalRep(Tcl_Obj* pathObjPtr,
+ ClientData Tcl_FSGetInternalRep(Tcl_Obj *pathPtr,
Tcl_Filesystem *fsPtr)
}
declare 466 generic {
- Tcl_Obj* Tcl_FSGetTranslatedPath(Tcl_Interp *interp, Tcl_Obj* pathPtr)
+ Tcl_Obj *Tcl_FSGetTranslatedPath(Tcl_Interp *interp, Tcl_Obj *pathPtr)
}
declare 467 generic {
int Tcl_FSEvalFile(Tcl_Interp *interp, Tcl_Obj *fileName)
}
declare 468 generic {
- Tcl_Obj* Tcl_FSNewNativePath(Tcl_Filesystem* fromFilesystem,
+ Tcl_Obj *Tcl_FSNewNativePath(Tcl_Filesystem *fromFilesystem,
ClientData clientData)
}
declare 469 generic {
- CONST char* Tcl_FSGetNativePath(Tcl_Obj* pathObjPtr)
+ CONST char *Tcl_FSGetNativePath(Tcl_Obj *pathPtr)
}
declare 470 generic {
- Tcl_Obj* Tcl_FSFileSystemInfo(Tcl_Obj* pathObjPtr)
+ Tcl_Obj *Tcl_FSFileSystemInfo(Tcl_Obj *pathPtr)
}
declare 471 generic {
- Tcl_Obj* Tcl_FSPathSeparator(Tcl_Obj* pathObjPtr)
+ Tcl_Obj *Tcl_FSPathSeparator(Tcl_Obj *pathPtr)
}
declare 472 generic {
- Tcl_Obj* Tcl_FSListVolumes(void)
+ Tcl_Obj *Tcl_FSListVolumes(void)
}
declare 473 generic {
int Tcl_FSRegister(ClientData clientData, Tcl_Filesystem *fsPtr)
@@ -1683,51 +1690,53 @@ declare 475 generic {
ClientData Tcl_FSData(Tcl_Filesystem *fsPtr)
}
declare 476 generic {
- CONST char* Tcl_FSGetTranslatedStringPath(Tcl_Interp *interp,
- Tcl_Obj* pathPtr)
+ CONST char *Tcl_FSGetTranslatedStringPath(Tcl_Interp *interp,
+ Tcl_Obj *pathPtr)
}
declare 477 generic {
- Tcl_Filesystem* Tcl_FSGetFileSystemForPath(Tcl_Obj* pathObjPtr)
+ Tcl_Filesystem *Tcl_FSGetFileSystemForPath(Tcl_Obj *pathPtr)
}
declare 478 generic {
- Tcl_PathType Tcl_FSGetPathType(Tcl_Obj *pathObjPtr)
+ Tcl_PathType Tcl_FSGetPathType(Tcl_Obj *pathPtr)
}
-# New function due to TIP#49
+
+# TIP#49 (detection of output buffering) akupries
declare 479 generic {
int Tcl_OutputBuffered(Tcl_Channel chan)
}
declare 480 generic {
void Tcl_FSMountsChanged(Tcl_Filesystem *fsPtr)
-}
-# New function due to TIP#56
+}
+
+# TIP#56 (evaluate a parsed script) msofer
declare 481 generic {
int Tcl_EvalTokensStandard(Tcl_Interp *interp, Tcl_Token *tokenPtr,
int count)
}
-# New export due to TIP#73
+# TIP#73 (access to current time) kbk
declare 482 generic {
- void Tcl_GetTime(Tcl_Time* timeBuf)
+ void Tcl_GetTime(Tcl_Time *timeBuf)
}
-# New exports due to TIP#32
-
+# TIP#32 (object-enabled traces) kbk
declare 483 generic {
- Tcl_Trace Tcl_CreateObjTrace(Tcl_Interp* interp, int level, int flags,
- Tcl_CmdObjTraceProc* objProc, ClientData clientData,
- Tcl_CmdObjTraceDeleteProc* delProc)
+ Tcl_Trace Tcl_CreateObjTrace(Tcl_Interp *interp, int level, int flags,
+ Tcl_CmdObjTraceProc *objProc, ClientData clientData,
+ Tcl_CmdObjTraceDeleteProc *delProc)
}
declare 484 generic {
- int Tcl_GetCommandInfoFromToken(Tcl_Command token, Tcl_CmdInfo* infoPtr)
+ int Tcl_GetCommandInfoFromToken(Tcl_Command token, Tcl_CmdInfo *infoPtr)
}
declare 485 generic {
int Tcl_SetCommandInfoFromToken(Tcl_Command token,
- CONST Tcl_CmdInfo* infoPtr)
+ CONST Tcl_CmdInfo *infoPtr)
}
### New functions on 64-bit dev branch ###
+# TIP#72 (64-bit values) dkf
declare 486 generic {
- Tcl_Obj * Tcl_DbNewWideIntObj(Tcl_WideInt wideValue,
+ Tcl_Obj *Tcl_DbNewWideIntObj(Tcl_WideInt wideValue,
CONST char *file, int line)
}
declare 487 generic {
@@ -1735,13 +1744,13 @@ declare 487 generic {
Tcl_WideInt *widePtr)
}
declare 488 generic {
- Tcl_Obj * Tcl_NewWideIntObj(Tcl_WideInt wideValue)
+ Tcl_Obj *Tcl_NewWideIntObj(Tcl_WideInt wideValue)
}
declare 489 generic {
void Tcl_SetWideIntObj(Tcl_Obj *objPtr, Tcl_WideInt wideValue)
}
declare 490 generic {
- Tcl_StatBuf * Tcl_AllocStatBuf(void)
+ Tcl_StatBuf *Tcl_AllocStatBuf(void)
}
declare 491 generic {
Tcl_WideInt Tcl_Seek(Tcl_Channel chan, Tcl_WideInt offset, int mode)
@@ -1750,130 +1759,433 @@ declare 492 generic {
Tcl_WideInt Tcl_Tell(Tcl_Channel chan)
}
-# New export due to TIP#91
+# TIP#91 (back-compat enhancements for channels) dkf
declare 493 generic {
- Tcl_DriverWideSeekProc * Tcl_ChannelWideSeekProc(
- Tcl_ChannelType *chanTypePtr)
-}
-
-# Slots 494 to 553 are taken already by 8.5
-# #111 - Dicts (494 ... 504)
-# #59 - Config (505)
-# #139 - Namespace API (506 ... 517)
-# #137 - source -encoding (518)
-# #121 - ExitProc (519)
-# #121 - Resource Limits (520 ... 534)
-# #226 - S/R Interp State (535 ... 537)
-# #227 - S/G Return Opts (538 ... 539)
-# #235 - Ensemble C API (540 ... 551)
-# #233 - Virtualized Time (552 ... 553)
-
-# TIP#218 (Driver Thread Actions) davygrvy/akupries ChannelType ver 4
-# These slots are used by 8.5 as well.
+ Tcl_DriverWideSeekProc *Tcl_ChannelWideSeekProc(
+ CONST Tcl_ChannelType *chanTypePtr)
+}
+
+# ----- BASELINE -- FOR -- 8.4.0 ----- #
+
+# TIP#111 (dictionaries) dkf
+declare 494 generic {
+ int Tcl_DictObjPut(Tcl_Interp *interp, Tcl_Obj *dictPtr,
+ Tcl_Obj *keyPtr, Tcl_Obj *valuePtr)
+}
+declare 495 generic {
+ int Tcl_DictObjGet(Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Obj *keyPtr,
+ Tcl_Obj **valuePtrPtr)
+}
+declare 496 generic {
+ int Tcl_DictObjRemove(Tcl_Interp *interp, Tcl_Obj *dictPtr,
+ Tcl_Obj *keyPtr)
+}
+declare 497 generic {
+ int Tcl_DictObjSize(Tcl_Interp *interp, Tcl_Obj *dictPtr, int *sizePtr)
+}
+declare 498 generic {
+ int Tcl_DictObjFirst(Tcl_Interp *interp, Tcl_Obj *dictPtr,
+ Tcl_DictSearch *searchPtr,
+ Tcl_Obj **keyPtrPtr, Tcl_Obj **valuePtrPtr, int *donePtr)
+}
+declare 499 generic {
+ void Tcl_DictObjNext(Tcl_DictSearch *searchPtr,
+ Tcl_Obj **keyPtrPtr, Tcl_Obj **valuePtrPtr, int *donePtr)
+}
+declare 500 generic {
+ void Tcl_DictObjDone(Tcl_DictSearch *searchPtr)
+}
+declare 501 generic {
+ int Tcl_DictObjPutKeyList(Tcl_Interp *interp, Tcl_Obj *dictPtr,
+ int keyc, Tcl_Obj *CONST *keyv, Tcl_Obj *valuePtr)
+}
+declare 502 generic {
+ int Tcl_DictObjRemoveKeyList(Tcl_Interp *interp, Tcl_Obj *dictPtr,
+ int keyc, Tcl_Obj *CONST *keyv)
+}
+declare 503 generic {
+ Tcl_Obj *Tcl_NewDictObj(void)
+}
+declare 504 generic {
+ Tcl_Obj *Tcl_DbNewDictObj(CONST char *file, int line)
+}
+
+# TIP#59 (configuration reporting) akupries
+declare 505 generic {
+ void Tcl_RegisterConfig(Tcl_Interp *interp, CONST char *pkgName,
+ Tcl_Config *configuration, CONST char *valEncoding)
+}
+
+# TIP #139 (partial exposure of namespace API - transferred from tclInt.decls)
+# dkf, API by Brent Welch?
+declare 506 generic {
+ Tcl_Namespace *Tcl_CreateNamespace(Tcl_Interp *interp, CONST char *name,
+ ClientData clientData, Tcl_NamespaceDeleteProc *deleteProc)
+}
+declare 507 generic {
+ void Tcl_DeleteNamespace(Tcl_Namespace *nsPtr)
+}
+declare 508 generic {
+ int Tcl_AppendExportList(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
+ Tcl_Obj *objPtr)
+}
+declare 509 generic {
+ int Tcl_Export(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
+ CONST char *pattern, int resetListFirst)
+}
+declare 510 generic {
+ int Tcl_Import(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
+ CONST char *pattern, int allowOverwrite)
+}
+declare 511 generic {
+ int Tcl_ForgetImport(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
+ CONST char *pattern)
+}
+declare 512 generic {
+ Tcl_Namespace *Tcl_GetCurrentNamespace(Tcl_Interp *interp)
+}
+declare 513 generic {
+ Tcl_Namespace *Tcl_GetGlobalNamespace(Tcl_Interp *interp)
+}
+declare 514 generic {
+ Tcl_Namespace *Tcl_FindNamespace(Tcl_Interp *interp, CONST char *name,
+ Tcl_Namespace *contextNsPtr, int flags)
+}
+declare 515 generic {
+ Tcl_Command Tcl_FindCommand(Tcl_Interp *interp, CONST char *name,
+ Tcl_Namespace *contextNsPtr, int flags)
+}
+declare 516 generic {
+ Tcl_Command Tcl_GetCommandFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr)
+}
+declare 517 generic {
+ void Tcl_GetCommandFullName(Tcl_Interp *interp, Tcl_Command command,
+ Tcl_Obj *objPtr)
+}
+
+# TIP#137 (encoding-aware source command) dgp for Anton Kovalenko
+declare 518 generic {
+ int Tcl_FSEvalFileEx(Tcl_Interp *interp, Tcl_Obj *fileName,
+ CONST char *encodingName)
+}
+
+# TIP#121 (exit handler) dkf for Joe Mistachkin
+declare 519 generic {
+ Tcl_ExitProc *Tcl_SetExitProc(Tcl_ExitProc *proc)
+}
+
+# TIP#143 (resource limits) dkf
+declare 520 generic {
+ void Tcl_LimitAddHandler(Tcl_Interp *interp, int type,
+ Tcl_LimitHandlerProc *handlerProc, ClientData clientData,
+ Tcl_LimitHandlerDeleteProc *deleteProc)
+}
+declare 521 generic {
+ void Tcl_LimitRemoveHandler(Tcl_Interp *interp, int type,
+ Tcl_LimitHandlerProc *handlerProc, ClientData clientData)
+}
+declare 522 generic {
+ int Tcl_LimitReady(Tcl_Interp *interp)
+}
+declare 523 generic {
+ int Tcl_LimitCheck(Tcl_Interp *interp)
+}
+declare 524 generic {
+ int Tcl_LimitExceeded(Tcl_Interp *interp)
+}
+declare 525 generic {
+ void Tcl_LimitSetCommands(Tcl_Interp *interp, int commandLimit)
+}
+declare 526 generic {
+ void Tcl_LimitSetTime(Tcl_Interp *interp, Tcl_Time *timeLimitPtr)
+}
+declare 527 generic {
+ void Tcl_LimitSetGranularity(Tcl_Interp *interp, int type, int granularity)
+}
+declare 528 generic {
+ int Tcl_LimitTypeEnabled(Tcl_Interp *interp, int type)
+}
+declare 529 generic {
+ int Tcl_LimitTypeExceeded(Tcl_Interp *interp, int type)
+}
+declare 530 generic {
+ void Tcl_LimitTypeSet(Tcl_Interp *interp, int type)
+}
+declare 531 generic {
+ void Tcl_LimitTypeReset(Tcl_Interp *interp, int type)
+}
+declare 532 generic {
+ int Tcl_LimitGetCommands(Tcl_Interp *interp)
+}
+declare 533 generic {
+ void Tcl_LimitGetTime(Tcl_Interp *interp, Tcl_Time *timeLimitPtr)
+}
+declare 534 generic {
+ int Tcl_LimitGetGranularity(Tcl_Interp *interp, int type)
+}
+
+# TIP#226 (interpreter result state management) dgp
+declare 535 generic {
+ Tcl_InterpState Tcl_SaveInterpState(Tcl_Interp *interp, int status)
+}
+declare 536 generic {
+ int Tcl_RestoreInterpState(Tcl_Interp *interp, Tcl_InterpState state)
+}
+declare 537 generic {
+ void Tcl_DiscardInterpState(Tcl_InterpState state)
+}
+
+# TIP#227 (return options interface) dgp
+declare 538 generic {
+ int Tcl_SetReturnOptions(Tcl_Interp *interp, Tcl_Obj *options)
+}
+declare 539 generic {
+ Tcl_Obj *Tcl_GetReturnOptions(Tcl_Interp *interp, int result)
+}
+
+# TIP#235 (ensembles) dkf
+declare 540 generic {
+ int Tcl_IsEnsemble(Tcl_Command token)
+}
+declare 541 generic {
+ Tcl_Command Tcl_CreateEnsemble(Tcl_Interp *interp, CONST char *name,
+ Tcl_Namespace *namespacePtr, int flags)
+}
+declare 542 generic {
+ Tcl_Command Tcl_FindEnsemble(Tcl_Interp *interp, Tcl_Obj *cmdNameObj,
+ int flags)
+}
+declare 543 generic {
+ int Tcl_SetEnsembleSubcommandList(Tcl_Interp *interp, Tcl_Command token,
+ Tcl_Obj *subcmdList)
+}
+declare 544 generic {
+ int Tcl_SetEnsembleMappingDict(Tcl_Interp *interp, Tcl_Command token,
+ Tcl_Obj *mapDict)
+}
+declare 545 generic {
+ int Tcl_SetEnsembleUnknownHandler(Tcl_Interp *interp, Tcl_Command token,
+ Tcl_Obj *unknownList)
+}
+declare 546 generic {
+ int Tcl_SetEnsembleFlags(Tcl_Interp *interp, Tcl_Command token, int flags)
+}
+declare 547 generic {
+ int Tcl_GetEnsembleSubcommandList(Tcl_Interp *interp, Tcl_Command token,
+ Tcl_Obj **subcmdListPtr)
+}
+declare 548 generic {
+ int Tcl_GetEnsembleMappingDict(Tcl_Interp *interp, Tcl_Command token,
+ Tcl_Obj **mapDictPtr)
+}
+declare 549 generic {
+ int Tcl_GetEnsembleUnknownHandler(Tcl_Interp *interp, Tcl_Command token,
+ Tcl_Obj **unknownListPtr)
+}
+declare 550 generic {
+ int Tcl_GetEnsembleFlags(Tcl_Interp *interp, Tcl_Command token,
+ int *flagsPtr)
+}
+declare 551 generic {
+ int Tcl_GetEnsembleNamespace(Tcl_Interp *interp, Tcl_Command token,
+ Tcl_Namespace **namespacePtrPtr)
+}
+
+# TIP#233 (virtualized time) akupries
+declare 552 generic {
+ void Tcl_SetTimeProc(Tcl_GetTimeProc *getProc,
+ Tcl_ScaleTimeProc *scaleProc,
+ ClientData clientData)
+}
+declare 553 generic {
+ void Tcl_QueryTimeProc(Tcl_GetTimeProc **getProc,
+ Tcl_ScaleTimeProc **scaleProc,
+ ClientData *clientData)
+}
+
+# TIP#218 (driver thread actions) davygrvy/akupries ChannelType ver 4
declare 554 generic {
- Tcl_DriverThreadActionProc *Tcl_ChannelThreadActionProc(Tcl_ChannelType *chanTypePtr)
+ Tcl_DriverThreadActionProc *Tcl_ChannelThreadActionProc(
+ CONST Tcl_ChannelType *chanTypePtr)
}
-# Slots 555 to 572 are taken already by 8.5
-# TIP #237: Arbitrary-prec Integers (555 ... 559)
-# TIP #208: 'chan' Command (560 ... 561)
-# TIP #219: Channel Reflection (562 ... 565)
-# TIP #237: Add. bignum support (566)
-# TIP #181: 'namespace unknown' Cmd (567 ... 568)
-# TIP #258: Enhanced Encodings API (569 ... 572)
+# TIP#237 (arbitrary-precision integers) kbk
+declare 555 generic {
+ Tcl_Obj *Tcl_NewBignumObj(mp_int *value)
+}
+declare 556 generic {
+ Tcl_Obj *Tcl_DbNewBignumObj(mp_int *value, CONST char *file, int line)
+}
+declare 557 generic {
+ void Tcl_SetBignumObj(Tcl_Obj *obj, mp_int *value)
+}
+declare 558 generic {
+ int Tcl_GetBignumFromObj(Tcl_Interp *interp, Tcl_Obj *obj, mp_int *value)
+}
+declare 559 generic {
+ int Tcl_TakeBignumFromObj(Tcl_Interp *interp, Tcl_Obj *obj, mp_int *value)
+}
-# TIP#268: Extended version numbers and requirements.
-# The slot is present even if TCL_TIP268 is not activated.
+# TIP #208 ('chan' command) jeffh
+declare 560 generic {
+ int Tcl_TruncateChannel(Tcl_Channel chan, Tcl_WideInt length)
+}
+declare 561 generic {
+ Tcl_DriverTruncateProc *Tcl_ChannelTruncateProc(
+ CONST Tcl_ChannelType *chanTypePtr)
+}
+# TIP#219 (channel reflection api) akupries
+declare 562 generic {
+ void Tcl_SetChannelErrorInterp(Tcl_Interp *interp, Tcl_Obj *msg)
+}
+declare 563 generic {
+ void Tcl_GetChannelErrorInterp(Tcl_Interp *interp, Tcl_Obj **msg)
+}
+declare 564 generic {
+ void Tcl_SetChannelError(Tcl_Channel chan, Tcl_Obj *msg)
+}
+declare 565 generic {
+ void Tcl_GetChannelError(Tcl_Channel chan, Tcl_Obj **msg)
+}
+
+# TIP #237 (additional conversion functions for bignum support) kbk/dgp
+declare 566 generic {
+ int Tcl_InitBignumFromDouble(Tcl_Interp *interp, double initval,
+ mp_int *toInit)
+}
+
+# TIP#181 (namespace unknown command) dgp for Neil Madden
+declare 567 generic {
+ Tcl_Obj *Tcl_GetNamespaceUnknownHandler(Tcl_Interp *interp,
+ Tcl_Namespace *nsPtr)
+}
+declare 568 generic {
+ int Tcl_SetNamespaceUnknownHandler(Tcl_Interp *interp,
+ Tcl_Namespace *nsPtr, Tcl_Obj *handlerPtr)
+}
+
+# TIP#258 (enhanced interface for encodings) dgp
+declare 569 generic {
+ int Tcl_GetEncodingFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+ Tcl_Encoding *encodingPtr)
+}
+declare 570 generic {
+ Tcl_Obj *Tcl_GetEncodingSearchPath(void)
+}
+declare 571 generic {
+ int Tcl_SetEncodingSearchPath(Tcl_Obj *searchPath)
+}
+declare 572 generic {
+ CONST char *Tcl_GetEncodingNameFromEnvironment(Tcl_DString *bufPtr)
+}
+
+# TIP#268 (extended version numbers and requirements) akupries
declare 573 generic {
- int Tcl_PkgRequireProc(Tcl_Interp *interp, CONST char *name,
+ int Tcl_PkgRequireProc(Tcl_Interp *interp, CONST char *name,
int objc, Tcl_Obj *CONST objv[], ClientData *clientDataPtr)
}
+# TIP#270 (utility C routines for string formatting) dgp
+declare 574 generic {
+ void Tcl_AppendObjToErrorInfo(Tcl_Interp *interp, Tcl_Obj *objPtr)
+}
+declare 575 generic {
+ void Tcl_AppendLimitedToObj(Tcl_Obj *objPtr, CONST char *bytes, int length,
+ int limit, CONST char *ellipsis)
+}
+declare 576 generic {
+ Tcl_Obj *Tcl_Format(Tcl_Interp *interp, CONST char *format, int objc,
+ Tcl_Obj *CONST objv[])
+}
+declare 577 generic {
+ int Tcl_AppendFormatToObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+ CONST char *format, int objc, Tcl_Obj *CONST objv[])
+}
+declare 578 generic {
+ Tcl_Obj *Tcl_ObjPrintf(CONST char *format, ...)
+}
+declare 579 generic {
+ void Tcl_AppendPrintfToObj(Tcl_Obj *objPtr, CONST char *format, ...)
+}
+
##############################################################################
-# Define the platform specific public Tcl interface. These functions are
-# only available on the designated platform.
+# Define the platform specific public Tcl interface. These functions are only
+# available on the designated platform.
interface tclPlat
-######################
-# Windows declarations
+################################
+# Unix specific functions
+# (none)
+
+################################
+# Windows specific functions
# Added in Tcl 8.1
declare 0 win {
- TCHAR * Tcl_WinUtfToTChar(CONST char *str, int len, Tcl_DString *dsPtr)
+ TCHAR *Tcl_WinUtfToTChar(CONST char *str, int len, Tcl_DString *dsPtr)
}
declare 1 win {
- char * Tcl_WinTCharToUtf(CONST TCHAR *str, int len, Tcl_DString *dsPtr)
+ char *Tcl_WinTCharToUtf(CONST TCHAR *str, int len, Tcl_DString *dsPtr)
}
-##################
-# Mac declarations
-
-# This is needed by the shells to handle Macintosh events.
-
-declare 0 mac {
- void Tcl_MacSetEventProc(Tcl_MacConvertEventPtr procPtr)
-}
+################################
+# Mac OS X specific functions
-# These routines are useful for handling using scripts from resources
-# in the application shell
-
-declare 1 mac {
- char * Tcl_MacConvertTextResource(Handle resource)
-}
-declare 2 mac {
- int Tcl_MacEvalResource(Tcl_Interp *interp, CONST char *resourceName,
- int resourceNumber, CONST char *fileName)
+declare 0 {unix macosx} {
+ int Tcl_MacOSXOpenBundleResources(Tcl_Interp *interp,
+ CONST char *bundleName, int hasResourceFile,
+ int maxPathLen, char *libraryPath)
}
-declare 3 mac {
- Handle Tcl_MacFindResource(Tcl_Interp *interp, long resourceType,
- CONST char *resourceName, int resourceNumber,
- CONST char *resFileRef, int * releaseIt)
+declare 1 {unix macosx} {
+ int Tcl_MacOSXOpenVersionedBundleResources(Tcl_Interp *interp,
+ CONST char *bundleName, CONST char *bundleVersion,
+ int hasResourceFile, int maxPathLen, char *libraryPath)
}
-# These routines support the new OSType object type (i.e. the packed 4
-# character type and creator codes).
+##############################################################################
+
+# Public functions that are not accessible via the stubs table.
-declare 4 mac {
- int Tcl_GetOSTypeFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
- OSType *osTypePtr)
+export {
+ void Tcl_Main(int argc, char **argv, Tcl_AppInitProc *appInitProc)
}
-declare 5 mac {
- void Tcl_SetOSTypeObj(Tcl_Obj *objPtr, OSType osType)
+export {
+ CONST char *Tcl_InitStubs(Tcl_Interp *interp, CONST char *version,
+ int exact)
}
-declare 6 mac {
- Tcl_Obj * Tcl_NewOSTypeObj(OSType osType)
+export {
+ CONST char *TclTomMathInitializeStubs(Tcl_Interp* interp,
+ CONST char* version, int epoch, int revision)
}
-
-# These are not in MSL 2.1.2, so we need to export them from the
-# Tcl shared library. They are found in the compat directory.
-
-declare 7 mac {
- int strncasecmp(CONST char *s1, CONST char *s2, size_t n)
+export {
+ CONST char *Tcl_PkgInitStubsCheck(Tcl_Interp *interp, CONST char *version,
+ int exact)
}
-declare 8 mac {
- int strcasecmp(CONST char *s1, CONST char *s2)
+export {
+ void Tcl_GetMemoryInfo(Tcl_DString *dsPtr)
}
-##################
-# Mac OS X declarations
-#
+# Global variables that need to be exported from the tcl shared library.
-declare 0 unix {
- int Tcl_MacOSXOpenBundleResources(Tcl_Interp *interp,
- CONST char *bundleName,
- int hasResourceFile,
- int maxPathLen,
- char *libraryPath)
+export {
+ TclStubs *tclStubsPtr (fool checkstubs)
}
-declare 1 unix {
- int Tcl_MacOSXOpenVersionedBundleResources(Tcl_Interp *interp,
- CONST char *bundleName,
- CONST char *bundleVersion,
- int hasResourceFile,
- int maxPathLen,
- char *libraryPath)
+export {
+ TclPlatStubs *tclPlatStubsPtr (fool checkstubs)
+}
+export {
+ TclIntStubs *tclIntStubsPtr (fool checkstubs)
+}
+export {
+ TclIntPlatStubs *tclIntPlatStubsPtr (fool checkstubs)
+}
+export {
+ TclTomMathStubs* tclTomMathStubsPtr (fool checkstubs)
}
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/generic/tcl.h b/generic/tcl.h
index 3c6ef5e..ec6f9b0 100644
--- a/generic/tcl.h
+++ b/generic/tcl.h
@@ -1,8 +1,8 @@
/*
* tcl.h --
*
- * This header file describes the externally-visible facilities
- * of the Tcl interpreter.
+ * This header file describes the externally-visible facilities of the
+ * Tcl interpreter.
*
* Copyright (c) 1987-1994 The Regents of the University of California.
* Copyright (c) 1993-1996 Lucent Technologies.
@@ -10,8 +10,8 @@
* Copyright (c) 1998-2000 by Scriptics Corporation.
* Copyright (c) 2002 by Kevin B. Kenny. All rights reserved.
*
- * 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.
*/
#ifndef _TCL
@@ -34,37 +34,38 @@ extern "C" {
#define TCL_FINAL_RELEASE 2
/*
- * When version numbers change here, must also go into the following files
- * and update the version numbers:
+ * When version numbers change here, must also go into the following files and
+ * update the version numbers:
*
- * library/init.tcl (only if Major.minor changes, not patchlevel) 1 LOC
+ * library/init.tcl (1 LOC patch)
* unix/configure.in (2 LOC Major, 2 LOC minor, 1 LOC patch)
* win/configure.in (as above)
* win/tcl.m4 (not patchlevel)
- * win/makefile.vc (not patchlevel) 2 LOC
- * README (sections 0 and 2)
- * mac/README (2 LOC, not patchlevel)
+ * win/makefile.bc (not patchlevel) 2 LOC
+ * README (sections 0 and 2, with and without separator)
* macosx/Tcl.pbproj/project.pbxproj (not patchlevel) 1 LOC
* macosx/Tcl.pbproj/default.pbxuser (not patchlevel) 1 LOC
- * win/README.binary (sections 0-4)
+ * macosx/Tcl.xcode/project.pbxproj (not patchlevel) 2 LOC
+ * macosx/Tcl.xcode/default.pbxuser (not patchlevel) 1 LOC
+ * macosx/Tcl-Common.xcconfig (not patchlevel) 1 LOC
* win/README (not patchlevel) (sections 0 and 2)
- * unix/tcl.spec (2 LOC Major/Minor, 1 LOC patch)
- * tests/basic.test (1 LOC M/M, not patchlevel)
+ * 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 4
+#define TCL_MINOR_VERSION 5
#define TCL_RELEASE_LEVEL TCL_FINAL_RELEASE
-#define TCL_RELEASE_SERIAL 19
+#define TCL_RELEASE_SERIAL 11
-#define TCL_VERSION "8.4"
-#define TCL_PATCH_LEVEL "8.4.19"
+#define TCL_VERSION "8.5"
+#define TCL_PATCH_LEVEL "8.5.11"
/*
- * The following definitions set up the proper options for Windows
- * compilers. We use this method because there is no autoconf equivalent.
+ * The following definitions set up the proper options for Windows compilers.
+ * We use this method because there is no autoconf equivalent.
*/
#ifndef __WIN32__
@@ -90,26 +91,10 @@ extern "C" {
#endif /* __WIN32__ */
/*
- * The following definitions set up the proper options for Macintosh
- * compilers. We use this method because there is no autoconf equivalent.
- */
-
-#ifdef MAC_TCL
-#include <ConditionalMacros.h>
-# ifndef USE_TCLALLOC
-# define USE_TCLALLOC 1
-# endif
-# ifndef NO_STRERROR
-# define NO_STRERROR 1
-# endif
-# define INLINE
-#endif
-
-
-/*
* Utility macros: STRINGIFY takes an argument and wraps it in "" (double
* quotation marks), JOIN joins two arguments.
*/
+
#ifndef STRINGIFY
# define STRINGIFY(x) STRINGIFY1(x)
# define STRINGIFY1(x) #x
@@ -119,21 +104,20 @@ extern "C" {
# define JOIN1(a,b) a##b
#endif
-/*
- * A special definition used to allow this header file to be included
- * from windows or mac resource files so that they can obtain version
- * information. RC_INVOKED is defined by default by the windows RC tool
- * and manually set for macintosh.
+/*
+ * A special definition used to allow this header file to be included from
+ * windows resource files so that they can obtain version information.
+ * RC_INVOKED is defined by default by the windows RC tool.
*
- * Resource compilers don't like all the C stuff, like typedefs and
- * procedure declarations, that occur below, so block them out.
+ * Resource compilers don't like all the C stuff, like typedefs and function
+ * declarations, that occur below, so block them out.
*/
#ifndef RC_INVOKED
/*
- * Special macro to define mutexes, that doesn't do anything
- * if we are not using threads.
+ * Special macro to define mutexes, that doesn't do anything if we are not
+ * using threads.
*/
#ifdef TCL_THREADS
@@ -143,62 +127,61 @@ extern "C" {
#endif
/*
- * Macros that eliminate the overhead of the thread synchronization
- * functions when compiling without thread support.
+ * Tcl's public routine Tcl_FSSeek() uses the values SEEK_SET, SEEK_CUR, and
+ * SEEK_END, all #define'd by stdio.h .
+ *
+ * Also, many extensions need stdio.h, and they've grown accustomed to tcl.h
+ * providing it for them rather than #include-ing it themselves as they
+ * should, so also for their sake, we keep the #include to be consistent with
+ * prior Tcl releases.
*/
-#ifndef TCL_THREADS
-#define Tcl_MutexLock(mutexPtr)
-#define Tcl_MutexUnlock(mutexPtr)
-#define Tcl_MutexFinalize(mutexPtr)
-#define Tcl_ConditionNotify(condPtr)
-#define Tcl_ConditionWait(condPtr, mutexPtr, timePtr)
-#define Tcl_ConditionFinalize(condPtr)
-#endif /* TCL_THREADS */
-
-
-#ifndef BUFSIZ
-# include <stdio.h>
-#endif
-
+#include <stdio.h>
/*
- * Definitions that allow Tcl functions with variable numbers of
- * arguments to be used with either varargs.h or stdarg.h. TCL_VARARGS
- * is used in procedure prototypes. TCL_VARARGS_DEF is used to declare
- * the arguments in a function definiton: it takes the type and name of
- * the first argument and supplies the appropriate argument declaration
- * string for use in the function definition. TCL_VARARGS_START
- * initializes the va_list data structure and returns the first argument.
+ * Support for functions with a variable number of arguments.
+ *
+ * The following TCL_VARARGS* macros are to support old extensions
+ * written for older versions of Tcl where the macros permitted
+ * support for the varargs.h system as well as stdarg.h .
+ *
+ * New code should just directly be written to use stdarg.h conventions.
*/
-#if !defined(NO_STDARG)
-# include <stdarg.h>
-# define TCL_VARARGS(type, name) (type name, ...)
-# define TCL_VARARGS_DEF(type, name) (type name, ...)
-# define TCL_VARARGS_START(type, name, list) (va_start(list, name), name)
-#else
-# include <varargs.h>
-# define TCL_VARARGS(type, name) ()
-# define TCL_VARARGS_DEF(type, name) (va_alist)
-# define TCL_VARARGS_START(type, name, list) \
- (va_start(list), va_arg(list, type))
+
+#include <stdarg.h>
+#ifndef TCL_NO_DEPRECATED
+# define TCL_VARARGS(type, name) (type name, ...)
+# define TCL_VARARGS_DEF(type, name) (type name, ...)
+# define TCL_VARARGS_START(type, name, list) (va_start(list, name), name)
#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 windows is for a DLL, which causes the DLLIMPORT
- * and DLLEXPORT macros to be nonempty. To build a static library, the
- * macro STATIC_BUILD should be defined.
+ * 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
+ * windows is for a DLL, which causes the DLLIMPORT and DLLEXPORT macros to be
+ * nonempty. To build a static library, the macro STATIC_BUILD should be
+ * defined.
+ *
+ * Note: when building static but linking dynamically to MSVCRT we must still
+ * correctly decorate the C library imported function. Use CRTIMPORT
+ * for this purpose. _DLL is defined by the compiler when linking to
+ * MSVCRT.
*/
#if (defined(__WIN32__) && (defined(_MSC_VER) || (__BORLANDC__ >= 0x0550) || defined(__LCC__) || defined(__WATCOMC__) || (defined(__GNUC__) && defined(__declspec))))
+# define HAVE_DECLSPEC 1
# ifdef STATIC_BUILD
# define DLLIMPORT
# define DLLEXPORT
+# ifdef _DLL
+# define CRTIMPORT __declspec(dllimport)
+# else
+# define CRTIMPORT
+# endif
# else
# define DLLIMPORT __declspec(dllimport)
# define DLLEXPORT __declspec(dllexport)
+# define CRTIMPORT __declspec(dllimport)
# endif
#else
# define DLLIMPORT
@@ -207,23 +190,25 @@ extern "C" {
# else
# define DLLEXPORT
# endif
+# define CRTIMPORT
#endif
/*
* These macros are used to control whether functions are being declared for
- * import or export. If a function is being declared while it is being built
+ * import or export. If a function is being declared while it is being built
* to be included in a shared library, then it should have the DLLEXPORT
- * storage class. If is being declared for use by a module that is going to
+ * storage class. If is being declared for use by a module that is going to
* link against the shared library, then it should have the DLLIMPORT storage
- * class. If the symbol is beind declared for a static build or for use from a
+ * class. If the symbol is beind declared for a static build or for use from a
* stub library, then the storage class should be empty.
*
- * The convention is that a macro called BUILD_xxxx, where xxxx is the
- * name of a library we are building, is set on the compile line for sources
- * that are to be placed in the library. When this macro is set, the
- * storage class will be set to DLLEXPORT. At the end of the header file, the
- * storage class will be reset to DLLIMPORT.
+ * The convention is that a macro called BUILD_xxxx, where xxxx is the name of
+ * a library we are building, is set on the compile line for sources that are
+ * to be placed in the library. When this macro is set, the storage class will
+ * be set to DLLEXPORT. At the end of the header file, the storage class will
+ * be reset to DLLIMPORT.
*/
+
#undef TCL_STORAGE_CLASS
#ifdef BUILD_tcl
# define TCL_STORAGE_CLASS DLLEXPORT
@@ -236,8 +221,8 @@ extern "C" {
#endif
/*
- * Definitions that allow this header file to be used either with or
- * without ANSI C features like function prototypes.
+ * Definitions that allow this header file to be used either with or without
+ * ANSI C features like function prototypes.
*/
#undef _ANSI_ARGS_
@@ -275,7 +260,7 @@ extern "C" {
#endif
/*
- * Make sure EXTERN isn't defined elsewhere
+ * Make sure EXTERN isn't defined elsewhere.
*/
#ifdef EXTERN
@@ -289,12 +274,9 @@ extern "C" {
#endif
/*
- * The following code is copied from winnt.h.
- * If we don't replicate it here, then <windows.h> can't be included
- * after tcl.h, since tcl.h also defines VOID.
- * This block is skipped under Cygwin and Mingw.
- *
- *
+ * The following code is copied from winnt.h. If we don't replicate it here,
+ * then <windows.h> can't be included after tcl.h, since tcl.h also defines
+ * VOID. This block is skipped under Cygwin and Mingw.
*/
#if defined(__WIN32__) && !defined(HAVE_WINNT_IGNORE_VOID)
@@ -307,15 +289,14 @@ typedef long LONG;
#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.
+ * 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
+#define VOID void
#else
-# define VOID char
+#define VOID char
#endif
/*
@@ -340,22 +321,23 @@ typedef long LONG;
# ifdef __LP64__
# undef TCL_WIDE_INT_TYPE
# define TCL_WIDE_INT_IS_LONG 1
+# define TCL_CFG_DO64BIT 1
# else /* !__LP64__ */
# define TCL_WIDE_INT_TYPE long long
# undef TCL_WIDE_INT_IS_LONG
+# undef TCL_CFG_DO64BIT
# endif /* __LP64__ */
# undef HAVE_STRUCT_STAT64
-# include <mach/mach.h>
#endif /* __APPLE__ */
/*
- * Define Tcl_WideInt to be a type that is (at least) 64-bits wide,
- * and define Tcl_WideUInt to be the unsigned variant of that type
- * (assuming that where we have one, we can have the other.)
+ * Define Tcl_WideInt to be a type that is (at least) 64-bits wide, and define
+ * Tcl_WideUInt to be the unsigned variant of that type (assuming that where
+ * we have one, we can have the other.)
*
* Also defines the following macros:
- * TCL_WIDE_INT_IS_LONG - if wide ints are really longs (i.e. we're on
- * a real 64-bit system.)
+ * TCL_WIDE_INT_IS_LONG - if wide ints are really longs (i.e. we're on a real
+ * 64-bit system.)
* Tcl_WideAsLong - forgetful converter from wideInt to long.
* Tcl_LongAsWide - sign-extending converter from long to wideInt.
* Tcl_WideAsDouble - converter from wideInt to double.
@@ -364,12 +346,9 @@ typedef long LONG;
* The following invariant should hold for any long value 'longVal':
* longVal == Tcl_WideAsLong(Tcl_LongAsWide(longVal))
*
- * Note on converting between Tcl_WideInt and strings. This
- * implementation (in tclObj.c) depends on the functions strtoull()
- * and sprintf(...,"%" TCL_LL_MODIFIER "d",...). TCL_LL_MODIFIER_SIZE
- * is the length of the modifier string, which is "ll" on most 32-bit
- * Unix systems. It has to be split up like this to allow for the more
- * complex formats sometimes needed (e.g. in the format(n) command.)
+ * Note on converting between Tcl_WideInt and strings. This implementation (in
+ * tclObj.c) depends on the function
+ * sprintf(...,"%" TCL_LL_MODIFIER "d",...).
*/
#if !defined(TCL_WIDE_INT_TYPE)&&!defined(TCL_WIDE_INT_IS_LONG)
@@ -377,19 +356,16 @@ typedef long LONG;
# define TCL_WIDE_INT_TYPE __int64
# ifdef __BORLANDC__
# define TCL_LL_MODIFIER "L"
-# define TCL_LL_MODIFIER_SIZE 1
# else /* __BORLANDC__ */
# define TCL_LL_MODIFIER "I64"
-# define TCL_LL_MODIFIER_SIZE 3
# endif /* __BORLANDC__ */
# elif defined(__GNUC__)
# define TCL_WIDE_INT_TYPE long long
# define TCL_LL_MODIFIER "ll"
-# define TCL_LL_MODIFIER_SIZE 2
# else /* ! __WIN32__ && ! __GNUC__ */
/*
- * Don't know what platform it is and configure hasn't discovered what
- * is going on for us. Try to guess...
+ * Don't know what platform it is and configure hasn't discovered what is
+ * going on for us. Try to guess...
*/
# ifdef NO_LIMITS_H
# error please define either TCL_WIDE_INT_TYPE or TCL_WIDE_INT_IS_LONG
@@ -418,16 +394,14 @@ typedef unsigned TCL_WIDE_INT_TYPE Tcl_WideUInt;
# define Tcl_DoubleAsWide(val) ((long)((double)(val)))
# ifndef TCL_LL_MODIFIER
# define TCL_LL_MODIFIER "l"
-# define TCL_LL_MODIFIER_SIZE 1
# endif /* !TCL_LL_MODIFIER */
#else /* TCL_WIDE_INT_IS_LONG */
/*
- * The next short section of defines are only done when not running on
- * Windows or some other strange platform.
+ * The next short section of defines are only done when not running on Windows
+ * or some other strange platform.
*/
# ifndef TCL_LL_MODIFIER
# define TCL_LL_MODIFIER "ll"
-# define TCL_LL_MODIFIER_SIZE 2
# endif /* !TCL_LL_MODIFIER */
# define Tcl_WideAsLong(val) ((long)((Tcl_WideInt)(val)))
# define Tcl_LongAsWide(val) ((Tcl_WideInt)((long)(val)))
@@ -468,32 +442,21 @@ typedef unsigned TCL_WIDE_INT_TYPE Tcl_WideUInt;
typedef struct stat Tcl_StatBuf;
#endif
-
/*
- * This flag controls whether binary compatability is maintained with
- * extensions built against a previous version of Tcl. This is true
- * by default.
- */
-#ifndef TCL_PRESERVE_BINARY_COMPATABILITY
-# define TCL_PRESERVE_BINARY_COMPATABILITY 1
-#endif
-
-
-/*
- * Data structures defined opaquely in this module. The definitions below
- * just provide dummy types. A few fields are made visible in Tcl_Interp
- * structures, namely those used for returning a string result from
- * commands. Direct access to the result field is discouraged in Tcl 8.0.
- * The interpreter result is either an object or a string, and the two
- * values are kept consistent unless some C code sets interp->result
- * directly. Programmers should use either the procedure Tcl_GetObjResult()
- * or Tcl_GetStringResult() to read the interpreter's result. See the
- * SetResult man page for details.
- *
- * Note: any change to the Tcl_Interp definition below must be mirrored
- * in the "real" definition in tclInt.h.
+ * Data structures defined opaquely in this module. The definitions below just
+ * provide dummy types. A few fields are made visible in Tcl_Interp
+ * structures, namely those used for returning a string result from commands.
+ * Direct access to the result field is discouraged in Tcl 8.0. The
+ * interpreter result is either an object or a string, and the two values are
+ * kept consistent unless some C code sets interp->result directly.
+ * Programmers should use either the function Tcl_GetObjResult() or
+ * Tcl_GetStringResult() to read the interpreter's result. See the SetResult
+ * man page for details.
+ *
+ * Note: any change to the Tcl_Interp definition below must be mirrored in the
+ * "real" definition in tclInt.h.
*
- * Note: Tcl_ObjCmdProc procedures do not directly set result and freeProc.
+ * Note: Tcl_ObjCmdProc functions do not directly set result and freeProc.
* Instead, they set a Tcl_Obj member in the "real" structure that can be
* accessed with Tcl_GetObjResult() and Tcl_SetObjResult().
*/
@@ -502,25 +465,29 @@ typedef struct Tcl_Interp {
char *result; /* If the last command returned a string
* result, this points to it. */
void (*freeProc) _ANSI_ARGS_((char *blockPtr));
- /* Zero means the string result is
- * statically allocated. TCL_DYNAMIC means
- * it was allocated with ckalloc and should
- * be freed with ckfree. Other values give
- * the address of procedure to invoke to
- * free the result. Tcl_Eval must free it
- * before executing next command. */
- int errorLine; /* When TCL_ERROR is returned, this gives
- * the line number within the command where
- * the error occurred (1 if first line). */
+ /* Zero means the string result is statically
+ * allocated. TCL_DYNAMIC means it was
+ * allocated with ckalloc and should be freed
+ * with ckfree. Other values give the address
+ * of function to invoke to free the result.
+ * Tcl_Eval must free it before executing next
+ * command. */
+ int errorLine; /* When TCL_ERROR is returned, this gives the
+ * line number within the command where the
+ * error occurred (1 if first line). */
} Tcl_Interp;
typedef struct Tcl_AsyncHandler_ *Tcl_AsyncHandler;
typedef struct Tcl_Channel_ *Tcl_Channel;
+typedef struct Tcl_ChannelTypeVersion_ *Tcl_ChannelTypeVersion;
typedef struct Tcl_Command_ *Tcl_Command;
typedef struct Tcl_Condition_ *Tcl_Condition;
+typedef struct Tcl_Dict_ *Tcl_Dict;
typedef struct Tcl_EncodingState_ *Tcl_EncodingState;
typedef struct Tcl_Encoding_ *Tcl_Encoding;
typedef struct Tcl_Event Tcl_Event;
+typedef struct Tcl_InterpState_ *Tcl_InterpState;
+typedef struct Tcl_LoadHandle_ *Tcl_LoadHandle;
typedef struct Tcl_Mutex_ *Tcl_Mutex;
typedef struct Tcl_Pid_ *Tcl_Pid;
typedef struct Tcl_RegExp_ *Tcl_RegExp;
@@ -529,18 +496,14 @@ typedef struct Tcl_ThreadId_ *Tcl_ThreadId;
typedef struct Tcl_TimerToken_ *Tcl_TimerToken;
typedef struct Tcl_Trace_ *Tcl_Trace;
typedef struct Tcl_Var_ *Tcl_Var;
-typedef struct Tcl_ChannelTypeVersion_ *Tcl_ChannelTypeVersion;
-typedef struct Tcl_LoadHandle_ *Tcl_LoadHandle;
/*
- * Definition of the interface to procedures implementing threads.
- * A procedure following this definition is given to each call of
- * 'Tcl_CreateThread' and will be called as the main fuction of
- * the new thread created by that call.
+ * Definition of the interface to functions implementing threads. A function
+ * following this definition is given to each call of 'Tcl_CreateThread' and
+ * will be called as the main fuction of the new thread created by that call.
*/
-#ifdef MAC_TCL
-typedef pascal void *(Tcl_ThreadCreateProc) _ANSI_ARGS_((ClientData clientData));
-#elif defined __WIN32__
+
+#if defined __WIN32__
typedef unsigned (__stdcall Tcl_ThreadCreateProc) _ANSI_ARGS_((ClientData clientData));
#else
typedef void (Tcl_ThreadCreateProc) _ANSI_ARGS_((ClientData clientData));
@@ -548,13 +511,11 @@ typedef void (Tcl_ThreadCreateProc) _ANSI_ARGS_((ClientData clientData));
/*
* Threading function return types used for abstracting away platform
- * differences when writing a Tcl_ThreadCreateProc. See the NewThread
- * function in generic/tclThreadTest.c for it's usage.
+ * differences when writing a Tcl_ThreadCreateProc. See the NewThread function
+ * in generic/tclThreadTest.c for it's usage.
*/
-#ifdef MAC_TCL
-# define Tcl_ThreadCreateType pascal void *
-# define TCL_THREAD_CREATE_RETURN return NULL
-#elif defined __WIN32__
+
+#if defined __WIN32__
# define Tcl_ThreadCreateType unsigned __stdcall
# define TCL_THREAD_CREATE_RETURN return 0
#else
@@ -567,68 +528,68 @@ typedef void (Tcl_ThreadCreateProc) _ANSI_ARGS_((ClientData clientData));
* given to Tcl_CreateThread.
*/
-#define TCL_THREAD_STACK_DEFAULT (0) /* Use default size for stack */
-#define TCL_THREAD_NOFLAGS (0000) /* Standard flags, default behaviour */
-#define TCL_THREAD_JOINABLE (0001) /* Mark the thread as joinable */
+#define TCL_THREAD_STACK_DEFAULT (0) /* Use default size for stack. */
+#define TCL_THREAD_NOFLAGS (0000) /* Standard flags, default
+ * behaviour. */
+#define TCL_THREAD_JOINABLE (0001) /* Mark the thread as joinable. */
/*
- * Flag values passed to Tcl_GetRegExpFromObj.
+ * Flag values passed to Tcl_StringCaseMatch.
*/
-#define TCL_REG_BASIC 000000 /* BREs (convenience) */
-#define TCL_REG_EXTENDED 000001 /* EREs */
-#define TCL_REG_ADVF 000002 /* advanced features in EREs */
-#define TCL_REG_ADVANCED 000003 /* AREs (which are also EREs) */
-#define TCL_REG_QUOTE 000004 /* no special characters, none */
-#define TCL_REG_NOCASE 000010 /* ignore case */
-#define TCL_REG_NOSUB 000020 /* don't care about subexpressions */
-#define TCL_REG_EXPANDED 000040 /* expanded format, white space &
- * comments */
-#define TCL_REG_NLSTOP 000100 /* \n doesn't match . or [^ ] */
-#define TCL_REG_NLANCH 000200 /* ^ matches after \n, $ before */
-#define TCL_REG_NEWLINE 000300 /* newlines are line terminators */
-#define TCL_REG_CANMATCH 001000 /* report details on partial/limited
- * matches */
+
+#define TCL_MATCH_NOCASE (1<<0)
/*
- * The following flag is experimental and only intended for use by Expect. It
- * will probably go away in a later release.
+ * Flag values passed to Tcl_GetRegExpFromObj.
*/
-#define TCL_REG_BOSONLY 002000 /* prepend \A to pattern so it only
- * matches at the beginning of the
- * string. */
+#define TCL_REG_BASIC 000000 /* BREs (convenience). */
+#define TCL_REG_EXTENDED 000001 /* EREs. */
+#define TCL_REG_ADVF 000002 /* Advanced features in EREs. */
+#define TCL_REG_ADVANCED 000003 /* AREs (which are also EREs). */
+#define TCL_REG_QUOTE 000004 /* No special characters, none. */
+#define TCL_REG_NOCASE 000010 /* Ignore case. */
+#define TCL_REG_NOSUB 000020 /* Don't care about subexpressions. */
+#define TCL_REG_EXPANDED 000040 /* Expanded format, white space &
+ * comments. */
+#define TCL_REG_NLSTOP 000100 /* \n doesn't match . or [^ ] */
+#define TCL_REG_NLANCH 000200 /* ^ matches after \n, $ before. */
+#define TCL_REG_NEWLINE 000300 /* Newlines are line terminators. */
+#define TCL_REG_CANMATCH 001000 /* Report details on partial/limited
+ * matches. */
/*
* Flags values passed to Tcl_RegExpExecObj.
*/
+
#define TCL_REG_NOTBOL 0001 /* Beginning of string does not match ^. */
#define TCL_REG_NOTEOL 0002 /* End of string does not match $. */
/*
- * Structures filled in by Tcl_RegExpInfo. Note that all offset values are
- * relative to the start of the match string, not the beginning of the
- * entire string.
+ * Structures filled in by Tcl_RegExpInfo. Note that all offset values are
+ * relative to the start of the match string, not the beginning of the entire
+ * string.
*/
typedef struct Tcl_RegExpIndices {
- long start; /* character offset of first character in match */
- long end; /* character offset of first character after the
- * match. */
+ long start; /* Character offset of first character in
+ * match. */
+ long end; /* Character offset of first character after
+ * the match. */
} Tcl_RegExpIndices;
typedef struct Tcl_RegExpInfo {
- int nsubs; /* number of subexpressions in the
- * compiled expression */
- Tcl_RegExpIndices *matches; /* array of nsubs match offset
- * pairs */
- long extendStart; /* The offset at which a subsequent
- * match might begin. */
+ int nsubs; /* Number of subexpressions in the compiled
+ * expression. */
+ Tcl_RegExpIndices *matches; /* Array of nsubs match offset pairs. */
+ long extendStart; /* The offset at which a subsequent match
+ * might begin. */
long reserved; /* Reserved for later use. */
} Tcl_RegExpInfo;
/*
- * Picky compilers complain if this typdef doesn't appear before the
- * struct's reference in tclDecls.h.
+ * Picky compilers complain if this typdef doesn't appear before the struct's
+ * reference in tclDecls.h.
*/
typedef Tcl_StatBuf *Tcl_Stat_;
@@ -636,32 +597,31 @@ typedef struct stat *Tcl_OldStat_;
/*
* When a TCL command returns, the interpreter contains a result from the
- * command. Programmers are strongly encouraged to use one of the
- * procedures Tcl_GetObjResult() or Tcl_GetStringResult() to read the
- * interpreter's result. See the SetResult man page for details. Besides
- * this result, the command procedure returns an integer code, which is
- * one of the following:
+ * command. Programmers are strongly encouraged to use one of the functions
+ * Tcl_GetObjResult() or Tcl_GetStringResult() to read the interpreter's
+ * result. See the SetResult man page for details. Besides this result, the
+ * command function returns an integer code, which is one of the following:
*
- * TCL_OK Command completed normally; the interpreter's
- * result contains the command's result.
- * TCL_ERROR The command couldn't be completed successfully;
- * the interpreter's result describes what went wrong.
- * TCL_RETURN The command requests that the current procedure
- * return; the interpreter's result contains the
- * procedure's return value.
- * TCL_BREAK The command requests that the innermost loop
- * be exited; the interpreter's result is meaningless.
- * TCL_CONTINUE Go on to the next iteration of the current loop;
- * the interpreter's result is meaningless.
+ * TCL_OK Command completed normally; the interpreter's result
+ * contains the command's result.
+ * TCL_ERROR The command couldn't be completed successfully; the
+ * interpreter's result describes what went wrong.
+ * TCL_RETURN The command requests that the current function return;
+ * the interpreter's result contains the function's
+ * return value.
+ * TCL_BREAK The command requests that the innermost loop be
+ * exited; the interpreter's result is meaningless.
+ * TCL_CONTINUE Go on to the next iteration of the current loop; the
+ * interpreter's result is meaningless.
*/
-#define TCL_OK 0
-#define TCL_ERROR 1
-#define TCL_RETURN 2
-#define TCL_BREAK 3
-#define TCL_CONTINUE 4
+#define TCL_OK 0
+#define TCL_ERROR 1
+#define TCL_RETURN 2
+#define TCL_BREAK 3
+#define TCL_CONTINUE 4
-#define TCL_RESULT_SIZE 200
+#define TCL_RESULT_SIZE 200
/*
* Flags to control what substitutions are performed by Tcl_SubstObj():
@@ -672,16 +632,17 @@ typedef struct stat *Tcl_OldStat_;
#define TCL_SUBST_BACKSLASHES 004
#define TCL_SUBST_ALL 007
-
/*
* Argument descriptors for math function callbacks in expressions:
*/
+
typedef enum {
TCL_INT, TCL_DOUBLE, TCL_EITHER, TCL_WIDE_INT
} Tcl_ValueType;
+
typedef struct Tcl_Value {
- Tcl_ValueType type; /* Indicates intValue or doubleValue is
- * valid, or both. */
+ Tcl_ValueType type; /* Indicates intValue or doubleValue is valid,
+ * or both. */
long intValue; /* Integer value. */
double doubleValue; /* Double-precision floating value. */
Tcl_WideInt wideValue; /* Wide (min. 64-bit) integer value. */
@@ -689,13 +650,13 @@ typedef struct Tcl_Value {
/*
* Forward declaration of Tcl_Obj to prevent an error when the forward
- * reference to Tcl_Obj is encountered in the procedure types declared
- * below.
+ * reference to Tcl_Obj is encountered in the function types declared below.
*/
+
struct Tcl_Obj;
/*
- * Procedure types defined by Tcl:
+ * Function types defined by Tcl:
*/
typedef int (Tcl_AppInitProc) _ANSI_ARGS_((Tcl_Interp *interp));
@@ -741,7 +702,9 @@ typedef void (Tcl_NamespaceDeleteProc) _ANSI_ARGS_((ClientData clientData));
typedef int (Tcl_ObjCmdProc) _ANSI_ARGS_((ClientData clientData,
Tcl_Interp *interp, int objc, struct Tcl_Obj * CONST * objv));
typedef int (Tcl_PackageInitProc) _ANSI_ARGS_((Tcl_Interp *interp));
-typedef void (Tcl_PanicProc) _ANSI_ARGS_(TCL_VARARGS(CONST char *, format));
+typedef int (Tcl_PackageUnloadProc) _ANSI_ARGS_((Tcl_Interp *interp,
+ int flags));
+typedef void (Tcl_PanicProc) _ANSI_ARGS_((CONST char *format, ...));
typedef void (Tcl_TcpAcceptProc) _ANSI_ARGS_((ClientData callbackData,
Tcl_Channel chan, char *address, int port));
typedef void (Tcl_TimerProc) _ANSI_ARGS_((ClientData clientData));
@@ -762,37 +725,35 @@ typedef void (Tcl_ServiceModeHookProc) _ANSI_ARGS_((int mode));
typedef ClientData (Tcl_InitNotifierProc) _ANSI_ARGS_((VOID));
typedef void (Tcl_FinalizeNotifierProc) _ANSI_ARGS_((ClientData clientData));
typedef void (Tcl_MainLoopProc) _ANSI_ARGS_((void));
-
+
/*
- * The following structure represents a type of object, which is a
- * particular internal representation for an object plus a set of
- * procedures that provide standard operations on objects of that type.
+ * The following structure represents a type of object, which is a particular
+ * internal representation for an object plus a set of functions that provide
+ * standard operations on objects of that type.
*/
typedef struct Tcl_ObjType {
char *name; /* Name of the type, e.g. "int". */
Tcl_FreeInternalRepProc *freeIntRepProc;
/* Called to free any storage for the type's
- * internal rep. NULL if the internal rep
- * does not need freeing. */
+ * internal rep. NULL if the internal rep does
+ * not need freeing. */
Tcl_DupInternalRepProc *dupIntRepProc;
- /* Called to create a new object as a copy
- * of an existing object. */
+ /* Called to create a new object as a copy of
+ * an existing object. */
Tcl_UpdateStringProc *updateStringProc;
- /* Called to update the string rep from the
+ /* Called to update the string rep from the
* type's internal representation. */
Tcl_SetFromAnyProc *setFromAnyProc;
- /* Called to convert the object's internal
- * rep to this type. Frees the internal rep
- * of the old type. Returns TCL_ERROR on
- * failure. */
+ /* Called to convert the object's internal rep
+ * to this type. Frees the internal rep of the
+ * old type. Returns TCL_ERROR on failure. */
} Tcl_ObjType;
-
/*
- * One of the following structures exists for each object in the Tcl
- * system. An object stores a value as either a string, some internal
- * representation, or both.
+ * One of the following structures exists for each object in the Tcl system.
+ * An object stores a value as either a string, some internal representation,
+ * or both.
*/
typedef struct Tcl_Obj {
@@ -802,98 +763,57 @@ typedef struct Tcl_Obj {
* must be followed by a null byte (i.e., at
* offset length) but may also contain
* embedded null characters. The array's
- * storage is allocated by ckalloc. NULL
- * means the string rep is invalid and must
- * be regenerated from the internal rep.
- * Clients should use Tcl_GetStringFromObj
- * or Tcl_GetString to get a pointer to the
- * byte array as a readonly value. */
+ * storage is allocated by ckalloc. NULL means
+ * the string rep is invalid and must be
+ * regenerated from the internal rep. Clients
+ * should use Tcl_GetStringFromObj or
+ * Tcl_GetString to get a pointer to the byte
+ * array as a readonly value. */
int length; /* The number of bytes at *bytes, not
* including the terminating null. */
Tcl_ObjType *typePtr; /* Denotes the object's type. Always
* corresponds to the type of the object's
- * internal rep. NULL indicates the object
- * has no internal rep (has no type). */
+ * internal rep. NULL indicates the object has
+ * no internal rep (has no type). */
union { /* The internal representation: */
- long longValue; /* - an long integer value */
- double doubleValue; /* - a double-precision floating value */
- VOID *otherValuePtr; /* - another, type-specific value */
- Tcl_WideInt wideValue; /* - a long long value */
- struct { /* - internal rep as two pointers */
+ long longValue; /* - an long integer value. */
+ double doubleValue; /* - a double-precision floating value. */
+ VOID *otherValuePtr; /* - another, type-specific value. */
+ Tcl_WideInt wideValue; /* - a long long value. */
+ struct { /* - internal rep as two pointers. */
VOID *ptr1;
VOID *ptr2;
} twoPtrValue;
+ struct { /* - internal rep as a wide int, tightly
+ * packed fields. */
+ VOID *ptr; /* Pointer to digits. */
+ unsigned long value;/* Alloc, used, and signum packed into a
+ * single word. */
+ } ptrAndLongRep;
} internalRep;
} Tcl_Obj;
-
/*
- * Macros to increment and decrement a Tcl_Obj's reference count, and to
- * test 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.
+ * Macros to increment and decrement a Tcl_Obj's reference count, and to test
+ * 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.
*/
+
void Tcl_IncrRefCount _ANSI_ARGS_((Tcl_Obj *objPtr));
void Tcl_DecrRefCount _ANSI_ARGS_((Tcl_Obj *objPtr));
int Tcl_IsShared _ANSI_ARGS_((Tcl_Obj *objPtr));
-
-#ifdef TCL_MEM_DEBUG
-# define Tcl_IncrRefCount(objPtr) \
- Tcl_DbIncrRefCount(objPtr, __FILE__, __LINE__)
-# define Tcl_DecrRefCount(objPtr) \
- Tcl_DbDecrRefCount(objPtr, __FILE__, __LINE__)
-# define Tcl_IsShared(objPtr) \
- Tcl_DbIsShared(objPtr, __FILE__, __LINE__)
-#else
-# define Tcl_IncrRefCount(objPtr) \
- ++(objPtr)->refCount
- /*
- * Use do/while0 idiom for optimum correctness without compiler warnings
- * http://c2.com/cgi/wiki?TrivialDoWhileLoop
- */
-# define Tcl_DecrRefCount(objPtr) \
- do { if (--(objPtr)->refCount <= 0) TclFreeObj(objPtr); } while(0)
-# define Tcl_IsShared(objPtr) \
- ((objPtr)->refCount > 1)
-#endif
/*
- * Macros and definitions that help to debug the use of Tcl objects.
- * When TCL_MEM_DEBUG is defined, the Tcl_New declarations are
- * overridden to call debugging versions of the object creation procedures.
+ * The following structure contains the state needed by Tcl_SaveResult. No-one
+ * outside of Tcl should access any of these fields. This structure is
+ * typically allocated on the stack.
*/
-#ifdef TCL_MEM_DEBUG
-# define Tcl_NewBooleanObj(val) \
- Tcl_DbNewBooleanObj(val, __FILE__, __LINE__)
-# define Tcl_NewByteArrayObj(bytes, len) \
- Tcl_DbNewByteArrayObj(bytes, len, __FILE__, __LINE__)
-# define Tcl_NewDoubleObj(val) \
- Tcl_DbNewDoubleObj(val, __FILE__, __LINE__)
-# define Tcl_NewIntObj(val) \
- Tcl_DbNewLongObj(val, __FILE__, __LINE__)
-# define Tcl_NewListObj(objc, objv) \
- Tcl_DbNewListObj(objc, objv, __FILE__, __LINE__)
-# define Tcl_NewLongObj(val) \
- Tcl_DbNewLongObj(val, __FILE__, __LINE__)
-# define Tcl_NewObj() \
- Tcl_DbNewObj(__FILE__, __LINE__)
-# define Tcl_NewStringObj(bytes, len) \
- Tcl_DbNewStringObj(bytes, len, __FILE__, __LINE__)
-# define Tcl_NewWideIntObj(val) \
- Tcl_DbNewWideIntObj(val, __FILE__, __LINE__)
-#endif /* TCL_MEM_DEBUG */
-
-
-/*
- * The following structure contains the state needed by
- * Tcl_SaveResult. No-one outside of Tcl should access any of these
- * fields. This structure is typically allocated on the stack.
- */
typedef struct Tcl_SavedResult {
char *result;
Tcl_FreeProc *freeProc;
@@ -905,46 +825,46 @@ typedef struct Tcl_SavedResult {
} Tcl_SavedResult;
/*
- * The following definitions support Tcl's namespace facility.
- * Note: the first five fields must match exactly the fields in a
- * Namespace structure (see tclInt.h).
+ * The following definitions support Tcl's namespace facility. Note: the first
+ * five fields must match exactly the fields in a Namespace structure (see
+ * tclInt.h).
*/
typedef struct Tcl_Namespace {
- char *name; /* The namespace's name within its parent
- * namespace. This contains no ::'s. The
- * name of the global namespace is ""
- * although "::" is an synonym. */
- char *fullName; /* The namespace's fully qualified name.
- * This starts with ::. */
- ClientData clientData; /* Arbitrary value associated with this
+ char *name; /* The namespace's name within its parent
+ * namespace. This contains no ::'s. The name
+ * of the global namespace is "" although "::"
+ * is an synonym. */
+ char *fullName; /* The namespace's fully qualified name. This
+ * starts with ::. */
+ ClientData clientData; /* Arbitrary value associated with this
* namespace. */
- Tcl_NamespaceDeleteProc* deleteProc;
- /* Procedure invoked when deleting the
+ Tcl_NamespaceDeleteProc *deleteProc;
+ /* Function invoked when deleting the
* namespace to, e.g., free clientData. */
- struct Tcl_Namespace* parentPtr;
- /* Points to the namespace that contains
- * this one. NULL if this is the global
+ struct Tcl_Namespace *parentPtr;
+ /* Points to the namespace that contains this
+ * one. NULL if this is the global
* namespace. */
} Tcl_Namespace;
/*
- * The following structure represents a call frame, or activation record.
- * A call frame defines a naming context for a procedure call: its local
- * scope (for local variables) and its namespace scope (used for non-local
- * variables; often the global :: namespace). A call frame can also define
- * the naming context for a namespace eval or namespace inscope command:
- * the namespace in which the command's code should execute. The
- * Tcl_CallFrame structures exist only while procedures or namespace
- * eval/inscope's are being executed, and provide a Tcl call stack.
- *
- * A call frame is initialized and pushed using Tcl_PushCallFrame and
- * popped using Tcl_PopCallFrame. Storage for a Tcl_CallFrame must be
- * provided by the Tcl_PushCallFrame caller, and callers typically allocate
- * them on the C call stack for efficiency. For this reason, Tcl_CallFrame
- * is defined as a structure and not as an opaque token. However, most
- * Tcl_CallFrame fields are hidden since applications should not access
- * them directly; others are declared as "dummyX".
+ * The following structure represents a call frame, or activation record. A
+ * call frame defines a naming context for a procedure call: its local scope
+ * (for local variables) and its namespace scope (used for non-local
+ * variables; often the global :: namespace). A call frame can also define the
+ * naming context for a namespace eval or namespace inscope command: the
+ * namespace in which the command's code should execute. The Tcl_CallFrame
+ * structures exist only while procedures or namespace eval/inscope's are
+ * being executed, and provide a Tcl call stack.
+ *
+ * A call frame is initialized and pushed using Tcl_PushCallFrame and popped
+ * using Tcl_PopCallFrame. Storage for a Tcl_CallFrame must be provided by the
+ * Tcl_PushCallFrame caller, and callers typically allocate them on the C call
+ * stack for efficiency. For this reason, Tcl_CallFrame is defined as a
+ * structure and not as an opaque token. However, most Tcl_CallFrame fields
+ * are hidden since applications should not access them directly; others are
+ * declared as "dummyX".
*
* WARNING!! The structure definition must be kept consistent with the
* CallFrame structure in tclInt.h. If you change one, change the other.
@@ -969,57 +889,56 @@ typedef struct Tcl_CallFrame {
/*
* Information about commands that is returned by Tcl_GetCommandInfo and
- * passed to Tcl_SetCommandInfo. objProc is an objc/objv object-based
- * command procedure while proc is a traditional Tcl argc/argv
- * string-based procedure. Tcl_CreateObjCommand and Tcl_CreateCommand
- * ensure that both objProc and proc are non-NULL and can be called to
- * execute the command. However, it may be faster to call one instead of
- * the other. The member isNativeObjectProc is set to 1 if an
- * object-based procedure was registered by Tcl_CreateObjCommand, and to
- * 0 if a string-based procedure was registered by Tcl_CreateCommand.
- * The other procedure is typically set to a compatibility wrapper that
- * does string-to-object or object-to-string argument conversions then
- * calls the other procedure.
+ * passed to Tcl_SetCommandInfo. objProc is an objc/objv object-based command
+ * function while proc is a traditional Tcl argc/argv string-based function.
+ * Tcl_CreateObjCommand and Tcl_CreateCommand ensure that both objProc and
+ * proc are non-NULL and can be called to execute the command. However, it may
+ * be faster to call one instead of the other. The member isNativeObjectProc
+ * is set to 1 if an object-based function was registered by
+ * Tcl_CreateObjCommand, and to 0 if a string-based function was registered by
+ * Tcl_CreateCommand. The other function is typically set to a compatibility
+ * wrapper that does string-to-object or object-to-string argument conversions
+ * then calls the other function.
*/
typedef struct Tcl_CmdInfo {
- int isNativeObjectProc; /* 1 if objProc was registered by a call to
- * Tcl_CreateObjCommand; 0 otherwise.
- * Tcl_SetCmdInfo does not modify this
- * field. */
- Tcl_ObjCmdProc *objProc; /* Command's object-based procedure. */
- ClientData objClientData; /* ClientData for object proc. */
- Tcl_CmdProc *proc; /* Command's string-based procedure. */
- ClientData clientData; /* ClientData for string proc. */
+ int isNativeObjectProc; /* 1 if objProc was registered by a call to
+ * Tcl_CreateObjCommand; 0 otherwise.
+ * Tcl_SetCmdInfo does not modify this
+ * field. */
+ Tcl_ObjCmdProc *objProc; /* Command's object-based function. */
+ ClientData objClientData; /* ClientData for object proc. */
+ Tcl_CmdProc *proc; /* Command's string-based function. */
+ ClientData clientData; /* ClientData for string proc. */
Tcl_CmdDeleteProc *deleteProc;
- /* Procedure to call when command is
- * deleted. */
- ClientData deleteData; /* Value to pass to deleteProc (usually
- * the same as clientData). */
- Tcl_Namespace *namespacePtr; /* Points to the namespace that contains
- * this command. Note that Tcl_SetCmdInfo
- * will not change a command's namespace;
- * use Tcl_RenameCommand to do that. */
-
+ /* Function to call when command is
+ * deleted. */
+ ClientData deleteData; /* Value to pass to deleteProc (usually the
+ * same as clientData). */
+ Tcl_Namespace *namespacePtr;/* Points to the namespace that contains this
+ * command. Note that Tcl_SetCmdInfo will not
+ * change a command's namespace; use
+ * TclRenameCommand or Tcl_Eval (of 'rename')
+ * to do that. */
} Tcl_CmdInfo;
/*
- * The structure defined below is used to hold dynamic strings. The only
- * field that clients should use is the string field, accessible via the
- * macro Tcl_DStringValue.
+ * The structure defined below is used to hold dynamic strings. The only
+ * fields that clients should use are string and length, accessible via the
+ * macros Tcl_DStringValue and Tcl_DStringLength.
*/
#define TCL_DSTRING_STATIC_SIZE 200
typedef struct Tcl_DString {
- char *string; /* Points to beginning of string: either
+ char *string; /* Points to beginning of string: either
* staticSpace below or a malloced array. */
int length; /* Number of non-NULL characters in the
* string. */
int spaceAvl; /* Total number of bytes available for the
* string and its terminating NULL char. */
char staticSpace[TCL_DSTRING_STATIC_SIZE];
- /* Space to use in common case where string
- * is small. */
+ /* Space to use in common case where string is
+ * small. */
} Tcl_DString;
#define Tcl_DStringLength(dsPtr) ((dsPtr)->length)
@@ -1027,29 +946,34 @@ typedef struct Tcl_DString {
#define Tcl_DStringTrunc Tcl_DStringSetLength
/*
- * Definitions for the maximum number of digits of precision that may
- * be specified in the "tcl_precision" variable, and the number of
- * bytes of buffer space required by Tcl_PrintDouble.
+ * Definitions for the maximum number of digits of precision that may be
+ * specified in the "tcl_precision" variable, and the number of bytes of
+ * buffer space required by Tcl_PrintDouble.
*/
-#define TCL_MAX_PREC 17
-#define TCL_DOUBLE_SPACE (TCL_MAX_PREC+10)
+#define TCL_MAX_PREC 17
+#define TCL_DOUBLE_SPACE (TCL_MAX_PREC+10)
/*
* Definition for a number of bytes of buffer space sufficient to hold the
- * string representation of an integer in base 10 (assuming the existence
- * of 64-bit integers).
+ * string representation of an integer in base 10 (assuming the existence of
+ * 64-bit integers).
*/
#define TCL_INTEGER_SPACE 24
/*
- * Flag that may be passed to Tcl_ConvertElement to force it not to
- * output braces (careful! if you change this flag be sure to change
- * the definitions at the front of tclUtil.c).
+ * Flag values passed to Tcl_ConvertElement.
+ * TCL_DONT_USE_BRACES forces it not to enclose the element in braces, but to
+ * use backslash quoting instead.
+ * TCL_DONT_QUOTE_HASH disables the default quoting of the '#' character. It
+ * is safe to leave the hash unquoted when the element is not the first
+ * element of a list, and this flag can be used by the caller to indicate
+ * that condition.
*/
#define TCL_DONT_USE_BRACES 1
+#define TCL_DONT_QUOTE_HASH 8
/*
* Flag that may be passed to Tcl_GetIndexFromObj to force it to disallow
@@ -1059,26 +983,36 @@ typedef struct Tcl_DString {
#define TCL_EXACT 1
/*
- * Flag values passed to Tcl_RecordAndEval and/or Tcl_EvalObj.
- * WARNING: these bit choices must not conflict with the bit choices
- * for evalFlag bits in tclInt.h!!
+ * Flag values passed to Tcl_RecordAndEval, Tcl_EvalObj, Tcl_EvalObjv.
+ * WARNING: these bit choices must not conflict with the bit choices for
+ * evalFlag bits in tclInt.h!
+ *
+ * Meanings:
+ * TCL_NO_EVAL: Just record this command
+ * TCL_EVAL_GLOBAL: Execute script in global namespace
+ * TCL_EVAL_DIRECT: Do not compile this script
+ * TCL_EVAL_INVOKE: Magical Tcl_EvalObjv mode for aliases/ensembles
+ * o Run in iPtr->lookupNsPtr or global namespace
+ * o Cut out of error traces
+ * o Don't reset the flags controlling ensemble
+ * error message rewriting.
*/
#define TCL_NO_EVAL 0x10000
#define TCL_EVAL_GLOBAL 0x20000
#define TCL_EVAL_DIRECT 0x40000
-#define TCL_EVAL_INVOKE 0x80000
+#define TCL_EVAL_INVOKE 0x80000
/*
- * Special freeProc values that may be passed to Tcl_SetResult (see
- * the man page for details):
+ * Special freeProc values that may be passed to Tcl_SetResult (see the man
+ * page for details):
*/
-#define TCL_VOLATILE ((Tcl_FreeProc *) 1)
-#define TCL_STATIC ((Tcl_FreeProc *) 0)
-#define TCL_DYNAMIC ((Tcl_FreeProc *) 3)
+#define TCL_VOLATILE ((Tcl_FreeProc *) 1)
+#define TCL_STATIC ((Tcl_FreeProc *) 0)
+#define TCL_DYNAMIC ((Tcl_FreeProc *) 3)
/*
- * Flag values passed to variable-related procedures.
+ * Flag values passed to variable-related functions.
*/
#define TCL_GLOBAL_ONLY 1
@@ -1101,7 +1035,15 @@ typedef struct Tcl_DString {
#define TCL_TRACE_RESULT_OBJECT 0x10000
/*
- * Flag values passed to command-related procedures.
+ * Flag values for ensemble commands.
+ */
+
+#define TCL_ENSEMBLE_PREFIX 0x02/* Flag value to say whether to allow
+ * unambiguous prefixes of commands or to
+ * require exact matches for command names. */
+
+/*
+ * Flag values passed to command-related functions.
*/
#define TCL_TRACE_RENAME 0x2000
@@ -1110,32 +1052,34 @@ typedef struct Tcl_DString {
#define TCL_ALLOW_INLINE_COMPILATION 0x20000
/*
- * Flag values passed to Tcl_CreateObjTrace, and used internally
- * by command execution traces. Slots 4,8,16 and 32 are
- * used internally by execution traces (see tclCmdMZ.c)
+ * The TCL_PARSE_PART1 flag is deprecated and has no effect. The part1 is now
+ * always parsed whenever the part2 is NULL. (This is to avoid a common error
+ * when converting code to use the new object based APIs and forgetting to
+ * give the flag)
*/
-#define TCL_TRACE_ENTER_EXEC 1
-#define TCL_TRACE_LEAVE_EXEC 2
-/*
- * The TCL_PARSE_PART1 flag is deprecated and has no effect.
- * The part1 is now always parsed whenever the part2 is NULL.
- * (This is to avoid a common error when converting code to
- * use the new object based APIs and forgetting to give the
- * flag)
- */
#ifndef TCL_NO_DEPRECATED
-# define TCL_PARSE_PART1 0x400
+# define TCL_PARSE_PART1 0x400
#endif
/*
* Types for linked variables:
*/
+
#define TCL_LINK_INT 1
#define TCL_LINK_DOUBLE 2
#define TCL_LINK_BOOLEAN 3
#define TCL_LINK_STRING 4
#define TCL_LINK_WIDE_INT 5
+#define TCL_LINK_CHAR 6
+#define TCL_LINK_UCHAR 7
+#define TCL_LINK_SHORT 8
+#define TCL_LINK_USHORT 9
+#define TCL_LINK_UINT 10
+#define TCL_LINK_LONG 11
+#define TCL_LINK_ULONG 12
+#define TCL_LINK_FLOAT 13
+#define TCL_LINK_WIDE_UINT 14
#define TCL_LINK_READ_ONLY 0x80
/*
@@ -1156,10 +1100,10 @@ typedef void (Tcl_FreeHashEntryProc) _ANSI_ARGS_((Tcl_HashEntry *hPtr));
/*
* This flag controls whether the hash table stores the hash of a key, or
- * recalculates it. There should be no reason for turning this flag off
- * as it is completely binary and source compatible unless you directly
- * access the bucketPtr member of the Tcl_HashTableEntry structure. This
- * member has been removed and the space used to store the hash value.
+ * recalculates it. There should be no reason for turning this flag off as it
+ * is completely binary and source compatible unless you directly access the
+ * bucketPtr member of the Tcl_HashTableEntry structure. This member has been
+ * removed and the space used to store the hash value.
*/
#ifndef TCL_HASH_KEY_STORE_HASH
@@ -1167,160 +1111,152 @@ typedef void (Tcl_FreeHashEntryProc) _ANSI_ARGS_((Tcl_HashEntry *hPtr));
#endif
/*
- * Structure definition for an entry in a hash table. No-one outside
- * Tcl should access any of these fields directly; use the macros
- * defined below.
+ * Structure definition for an entry in a hash table. No-one outside Tcl
+ * should access any of these fields directly; use the macros defined below.
*/
struct Tcl_HashEntry {
- Tcl_HashEntry *nextPtr; /* Pointer to next entry in this
- * hash bucket, or NULL for end of
- * chain. */
- Tcl_HashTable *tablePtr; /* Pointer to table containing entry. */
+ Tcl_HashEntry *nextPtr; /* Pointer to next entry in this hash bucket,
+ * or NULL for end of chain. */
+ Tcl_HashTable *tablePtr; /* Pointer to table containing entry. */
#if TCL_HASH_KEY_STORE_HASH
-# if TCL_PRESERVE_BINARY_COMPATABILITY
- VOID *hash; /* Hash value, stored as pointer to
- * ensure that the offsets of the
- * fields in this structure are not
- * changed. */
-# else
- unsigned int hash; /* Hash value. */
-# endif
+ VOID *hash; /* Hash value, stored as pointer to ensure
+ * that the offsets of the fields in this
+ * structure are not changed. */
#else
- Tcl_HashEntry **bucketPtr; /* Pointer to bucket that points to
- * first entry in this entry's chain:
- * used for deleting the entry. */
+ Tcl_HashEntry **bucketPtr; /* Pointer to bucket that points to first
+ * entry in this entry's chain: used for
+ * deleting the entry. */
#endif
- ClientData clientData; /* Application stores something here
- * with Tcl_SetHashValue. */
- union { /* Key has one of these forms: */
- char *oneWordValue; /* One-word value for key. */
- Tcl_Obj *objPtr; /* Tcl_Obj * key value. */
- int words[1]; /* Multiple integer words for key.
- * The actual size will be as large
- * as necessary for this table's
- * keys. */
- char string[4]; /* String for key. The actual size
- * will be as large as needed to hold
- * the key. */
- } key; /* MUST BE LAST FIELD IN RECORD!! */
+ ClientData clientData; /* Application stores something here with
+ * Tcl_SetHashValue. */
+ union { /* Key has one of these forms: */
+ char *oneWordValue; /* One-word value for key. */
+ Tcl_Obj *objPtr; /* Tcl_Obj * key value. */
+ int words[1]; /* Multiple integer words for key. The actual
+ * size will be as large as necessary for this
+ * table's keys. */
+ char string[4]; /* String for key. The actual size will be as
+ * large as needed to hold the key. */
+ } key; /* MUST BE LAST FIELD IN RECORD!! */
};
/*
* Flags used in Tcl_HashKeyType.
*
- * TCL_HASH_KEY_RANDOMIZE_HASH:
+ * TCL_HASH_KEY_RANDOMIZE_HASH -
* There are some things, pointers for example
* which don't hash well because they do not use
* the lower bits. If this flag is set then the
* hash table will attempt to rectify this by
* randomising the bits and then using the upper
* N bits as the index into the table.
+ * TCL_HASH_KEY_SYSTEM_HASH - If this flag is set then all memory internally
+ * allocated for the hash table that is not for an
+ * entry will use the system heap.
*/
+
#define TCL_HASH_KEY_RANDOMIZE_HASH 0x1
+#define TCL_HASH_KEY_SYSTEM_HASH 0x2
/*
- * Structure definition for the methods associated with a hash table
- * key type.
+ * Structure definition for the methods associated with a hash table key type.
*/
+
#define TCL_HASH_KEY_TYPE_VERSION 1
struct Tcl_HashKeyType {
int version; /* Version of the table. If this structure is
* extended in future then the version can be
* used to distinguish between different
- * structures.
- */
-
+ * structures. */
int flags; /* Flags, see above for details. */
-
- /* Calculates a hash value for the key. If this is NULL then the pointer
- * itself is used as a hash value.
- */
Tcl_HashKeyProc *hashKeyProc;
-
- /* Compares two keys and returns zero if they do not match, and non-zero
- * if they do. If this is NULL then the pointers are compared.
- */
+ /* Calculates a hash value for the key. If
+ * this is NULL then the pointer itself is
+ * used as a hash value. */
Tcl_CompareHashKeysProc *compareKeysProc;
-
- /* Called to allocate memory for a new entry, i.e. if the key is a
- * string then this could allocate a single block which contains enough
- * space for both the entry and the string. Only the key field of the
- * allocated Tcl_HashEntry structure needs to be filled in. If something
- * else needs to be done to the key, i.e. incrementing a reference count
- * then that should be done by this function. If this is NULL then Tcl_Alloc
- * is used to allocate enough space for a Tcl_HashEntry and the key pointer
- * is assigned to key.oneWordValue.
- */
+ /* Compares two keys and returns zero if they
+ * do not match, and non-zero if they do. If
+ * this is NULL then the pointers are
+ * compared. */
Tcl_AllocHashEntryProc *allocEntryProc;
-
- /* Called to free memory associated with an entry. If something else needs
- * to be done to the key, i.e. decrementing a reference count then that
- * should be done by this function. If this is NULL then Tcl_Free is used
- * to free the Tcl_HashEntry.
- */
+ /* Called to allocate memory for a new entry,
+ * i.e. if the key is a string then this could
+ * allocate a single block which contains
+ * enough space for both the entry and the
+ * string. Only the key field of the allocated
+ * Tcl_HashEntry structure needs to be filled
+ * in. If something else needs to be done to
+ * the key, i.e. incrementing a reference
+ * count then that should be done by this
+ * function. If this is NULL then Tcl_Alloc is
+ * used to allocate enough space for a
+ * Tcl_HashEntry and the key pointer is
+ * assigned to key.oneWordValue. */
Tcl_FreeHashEntryProc *freeEntryProc;
+ /* Called to free memory associated with an
+ * entry. If something else needs to be done
+ * to the key, i.e. decrementing a reference
+ * count then that should be done by this
+ * function. If this is NULL then Tcl_Free is
+ * used to free the Tcl_HashEntry. */
};
/*
- * Structure definition for a hash table. Must be in tcl.h so clients
- * can allocate space for these structures, but clients should never
- * access any fields in this structure.
+ * Structure definition for a hash table. Must be in tcl.h so clients can
+ * allocate space for these structures, but clients should never access any
+ * fields in this structure.
*/
#define TCL_SMALL_HASH_TABLE 4
struct Tcl_HashTable {
- Tcl_HashEntry **buckets; /* Pointer to bucket array. Each
- * element points to first entry in
- * bucket's hash chain, or NULL. */
+ Tcl_HashEntry **buckets; /* Pointer to bucket array. Each element
+ * points to first entry in bucket's hash
+ * chain, or NULL. */
Tcl_HashEntry *staticBuckets[TCL_SMALL_HASH_TABLE];
- /* Bucket array used for small tables
- * (to avoid mallocs and frees). */
- int numBuckets; /* Total number of buckets allocated
- * at **bucketPtr. */
- int numEntries; /* Total number of entries present
- * in table. */
- int rebuildSize; /* Enlarge table when numEntries gets
- * to be this large. */
- int downShift; /* Shift count used in hashing
- * function. Designed to use high-
- * order bits of randomized keys. */
- int mask; /* Mask value used in hashing
- * function. */
- int keyType; /* Type of keys used in this table.
- * It's either TCL_CUSTOM_KEYS,
- * TCL_STRING_KEYS, TCL_ONE_WORD_KEYS,
- * or an integer giving the number of
- * ints that is the size of the key.
- */
-#if TCL_PRESERVE_BINARY_COMPATABILITY
+ /* Bucket array used for small tables (to
+ * avoid mallocs and frees). */
+ int numBuckets; /* Total number of buckets allocated at
+ * **bucketPtr. */
+ int numEntries; /* Total number of entries present in
+ * table. */
+ int rebuildSize; /* Enlarge table when numEntries gets to be
+ * this large. */
+ int downShift; /* Shift count used in hashing function.
+ * Designed to use high-order bits of
+ * randomized keys. */
+ int mask; /* Mask value used in hashing function. */
+ int keyType; /* Type of keys used in this table. It's
+ * either TCL_CUSTOM_KEYS, TCL_STRING_KEYS,
+ * TCL_ONE_WORD_KEYS, or an integer giving the
+ * number of ints that is the size of the
+ * key. */
Tcl_HashEntry *(*findProc) _ANSI_ARGS_((Tcl_HashTable *tablePtr,
CONST char *key));
Tcl_HashEntry *(*createProc) _ANSI_ARGS_((Tcl_HashTable *tablePtr,
CONST char *key, int *newPtr));
-#endif
- Tcl_HashKeyType *typePtr; /* Type of the keys used in the
- * Tcl_HashTable. */
+ Tcl_HashKeyType *typePtr; /* Type of the keys used in the
+ * Tcl_HashTable. */
};
/*
- * Structure definition for information used to keep track of searches
- * through hash tables:
+ * Structure definition for information used to keep track of searches through
+ * hash tables:
*/
typedef struct Tcl_HashSearch {
- Tcl_HashTable *tablePtr; /* Table being searched. */
- int nextIndex; /* Index of next bucket to be
- * enumerated after present one. */
- Tcl_HashEntry *nextEntryPtr; /* Next entry to be enumerated in the
- * the current bucket. */
+ Tcl_HashTable *tablePtr; /* Table being searched. */
+ int nextIndex; /* Index of next bucket to be enumerated after
+ * present one. */
+ Tcl_HashEntry *nextEntryPtr;/* Next entry to be enumerated in the current
+ * bucket. */
} Tcl_HashSearch;
/*
* Acceptable key types for hash tables:
*
- * TCL_STRING_KEYS: The keys are strings, they are copied into
- * the entry.
+ * TCL_STRING_KEYS: The keys are strings, they are copied into the
+ * entry.
* TCL_ONE_WORD_KEYS: The keys are pointers, the pointer is stored
* in the entry.
* TCL_CUSTOM_TYPE_KEYS: The keys are arbitrary types which are copied
@@ -1328,69 +1264,39 @@ typedef struct Tcl_HashSearch {
* TCL_CUSTOM_PTR_KEYS: The keys are pointers to arbitrary types, the
* pointer is stored in the entry.
*
- * While maintaining binary compatability the above have to be distinct
- * values as they are used to differentiate between old versions of the
- * hash table which don't have a typePtr and new ones which do. Once binary
- * compatability is discarded in favour of making more wide spread changes
- * TCL_STRING_KEYS can be the same as TCL_CUSTOM_TYPE_KEYS, and
- * TCL_ONE_WORD_KEYS can be the same as TCL_CUSTOM_PTR_KEYS because they
- * simply determine how the key is accessed from the entry and not the
- * behaviour.
+ * While maintaining binary compatability the above have to be distinct values
+ * as they are used to differentiate between old versions of the hash table
+ * which don't have a typePtr and new ones which do. Once binary compatability
+ * is discarded in favour of making more wide spread changes TCL_STRING_KEYS
+ * can be the same as TCL_CUSTOM_TYPE_KEYS, and TCL_ONE_WORD_KEYS can be the
+ * same as TCL_CUSTOM_PTR_KEYS because they simply determine how the key is
+ * accessed from the entry and not the behaviour.
*/
#define TCL_STRING_KEYS 0
#define TCL_ONE_WORD_KEYS 1
-
-#if TCL_PRESERVE_BINARY_COMPATABILITY
-# define TCL_CUSTOM_TYPE_KEYS -2
-# define TCL_CUSTOM_PTR_KEYS -1
-#else
-# define TCL_CUSTOM_TYPE_KEYS TCL_STRING_KEYS
-# define TCL_CUSTOM_PTR_KEYS TCL_ONE_WORD_KEYS
-#endif
+#define TCL_CUSTOM_TYPE_KEYS -2
+#define TCL_CUSTOM_PTR_KEYS -1
/*
- * Macros for clients to use to access fields of hash entries:
+ * Structure definition for information used to keep track of searches through
+ * dictionaries. These fields should not be accessed by code outside
+ * tclDictObj.c
*/
-#define Tcl_GetHashValue(h) ((h)->clientData)
-#define Tcl_SetHashValue(h, value) ((h)->clientData = (ClientData) (value))
-#if TCL_PRESERVE_BINARY_COMPATABILITY
-# define Tcl_GetHashKey(tablePtr, h) \
- ((char *) (((tablePtr)->keyType == TCL_ONE_WORD_KEYS || \
- (tablePtr)->keyType == TCL_CUSTOM_PTR_KEYS) \
- ? (h)->key.oneWordValue \
- : (h)->key.string))
-#else
-# define Tcl_GetHashKey(tablePtr, h) \
- ((char *) (((tablePtr)->keyType == TCL_ONE_WORD_KEYS) \
- ? (h)->key.oneWordValue \
- : (h)->key.string))
-#endif
-
-/*
- * Macros to use for clients to use to invoke find and create procedures
- * for hash tables:
- */
+typedef struct {
+ void *next; /* Search position for underlying hash
+ * table. */
+ int epoch; /* Epoch marker for dictionary being searched,
+ * or -1 if search has terminated. */
+ Tcl_Dict dictionaryPtr; /* Reference to dictionary being searched. */
+} Tcl_DictSearch;
-#if TCL_PRESERVE_BINARY_COMPATABILITY
-# define Tcl_FindHashEntry(tablePtr, key) \
- (*((tablePtr)->findProc))(tablePtr, key)
-# define Tcl_CreateHashEntry(tablePtr, key, newPtr) \
- (*((tablePtr)->createProc))(tablePtr, key, newPtr)
-#else /* !TCL_PRESERVE_BINARY_COMPATABILITY */
/*
- * Macro to use new extended version of Tcl_InitHashTable.
+ * Flag values to pass to Tcl_DoOneEvent to disable searches for some kinds of
+ * events:
*/
-# define Tcl_InitHashTable(tablePtr, keyType) \
- Tcl_InitHashTableEx(tablePtr, keyType, NULL)
-#endif /* TCL_PRESERVE_BINARY_COMPATABILITY */
-
-/*
- * Flag values to pass to Tcl_DoOneEvent to disable searches
- * for some kinds of events:
- */
#define TCL_DONT_WAIT (1<<1)
#define TCL_WINDOW_EVENTS (1<<2)
#define TCL_FILE_EVENTS (1<<3)
@@ -1399,17 +1305,16 @@ typedef struct Tcl_HashSearch {
#define TCL_ALL_EVENTS (~TCL_DONT_WAIT)
/*
- * The following structure defines a generic event for the Tcl event
- * system. These are the things that are queued in calls to Tcl_QueueEvent
- * and serviced later by Tcl_DoOneEvent. There can be many different
- * kinds of events with different fields, corresponding to window events,
- * timer events, etc. The structure for a particular event consists of
- * a Tcl_Event header followed by additional information specific to that
- * event.
+ * The following structure defines a generic event for the Tcl event system.
+ * These are the things that are queued in calls to Tcl_QueueEvent and
+ * serviced later by Tcl_DoOneEvent. There can be many different kinds of
+ * events with different fields, corresponding to window events, timer events,
+ * etc. The structure for a particular event consists of a Tcl_Event header
+ * followed by additional information specific to that event.
*/
struct Tcl_Event {
- Tcl_EventProc *proc; /* Procedure to call to service this event. */
+ Tcl_EventProc *proc; /* Function to call to service this event. */
struct Tcl_Event *nextPtr; /* Next in list of pending events, or NULL. */
};
@@ -1430,10 +1335,9 @@ typedef enum {
#define TCL_SERVICE_ALL 1
/*
- * The following structure keeps is used to hold a time value, either as
- * an absolute time (the number of seconds from the epoch) or as an
- * elapsed time. On Unix systems the epoch is Midnight Jan 1, 1970 GMT.
- * On Macintosh systems the epoch is Midnight Jan 1, 1904 GMT.
+ * The following structure keeps is used to hold a time value, either as an
+ * absolute time (the number of seconds from the epoch) or as an elapsed time.
+ * On Unix systems the epoch is Midnight Jan 1, 1970 GMT.
*/
typedef struct Tcl_Time {
@@ -1445,20 +1349,30 @@ typedef void (Tcl_SetTimerProc) _ANSI_ARGS_((Tcl_Time *timePtr));
typedef int (Tcl_WaitForEventProc) _ANSI_ARGS_((Tcl_Time *timePtr));
/*
- * Bits to pass to Tcl_CreateFileHandler and Tcl_CreateChannelHandler
- * to indicate what sorts of events are of interest:
+ * TIP #233 (Virtualized Time)
*/
-#define TCL_READABLE (1<<1)
-#define TCL_WRITABLE (1<<2)
-#define TCL_EXCEPTION (1<<3)
+
+typedef void (Tcl_GetTimeProc) _ANSI_ARGS_((Tcl_Time *timebuf,
+ ClientData clientData));
+typedef void (Tcl_ScaleTimeProc) _ANSI_ARGS_((Tcl_Time *timebuf,
+ ClientData clientData));
+
+/*
+ * Bits to pass to Tcl_CreateFileHandler and Tcl_CreateChannelHandler to
+ * indicate what sorts of events are of interest:
+ */
+
+#define TCL_READABLE (1<<1)
+#define TCL_WRITABLE (1<<2)
+#define TCL_EXCEPTION (1<<3)
/*
- * Flag values to pass to Tcl_OpenCommandChannel to indicate the
- * disposition of the stdio handles. TCL_STDIN, TCL_STDOUT, TCL_STDERR,
- * are also used in Tcl_GetStdChannel.
+ * Flag values to pass to Tcl_OpenCommandChannel to indicate the disposition
+ * of the stdio handles. TCL_STDIN, TCL_STDOUT, TCL_STDERR, are also used in
+ * Tcl_GetStdChannel.
*/
-#define TCL_STDIN (1<<1)
+#define TCL_STDIN (1<<1)
#define TCL_STDOUT (1<<2)
#define TCL_STDERR (1<<3)
#define TCL_ENFORCE_MODE (1<<4)
@@ -1467,27 +1381,29 @@ typedef int (Tcl_WaitForEventProc) _ANSI_ARGS_((Tcl_Time *timePtr));
* Bits passed to Tcl_DriverClose2Proc to indicate which side of a channel
* should be closed.
*/
-#define TCL_CLOSE_READ (1<<1)
-#define TCL_CLOSE_WRITE (1<<2)
+
+#define TCL_CLOSE_READ (1<<1)
+#define TCL_CLOSE_WRITE (1<<2)
/*
- * Value to use as the closeProc for a channel that supports the
- * close2Proc interface.
+ * Value to use as the closeProc for a channel that supports the close2Proc
+ * interface.
*/
-#define TCL_CLOSE2PROC ((Tcl_DriverCloseProc *)1)
+#define TCL_CLOSE2PROC ((Tcl_DriverCloseProc *) 1)
/*
- * Channel version tag. This was introduced in 8.3.2/8.4.
+ * Channel version tag. This was introduced in 8.3.2/8.4.
*/
#define TCL_CHANNEL_VERSION_1 ((Tcl_ChannelTypeVersion) 0x1)
#define TCL_CHANNEL_VERSION_2 ((Tcl_ChannelTypeVersion) 0x2)
#define TCL_CHANNEL_VERSION_3 ((Tcl_ChannelTypeVersion) 0x3)
#define TCL_CHANNEL_VERSION_4 ((Tcl_ChannelTypeVersion) 0x4)
+#define TCL_CHANNEL_VERSION_5 ((Tcl_ChannelTypeVersion) 0x5)
/*
- * TIP #218: Channel Actions, Ids for Tcl_DriverThreadActionProc
+ * TIP #218: Channel Actions, Ids for Tcl_DriverThreadActionProc.
*/
#define TCL_CHANNEL_THREAD_INSERT (0)
@@ -1511,7 +1427,7 @@ typedef int (Tcl_DriverSeekProc) _ANSI_ARGS_((ClientData instanceData,
long offset, int mode, int *errorCodePtr));
typedef int (Tcl_DriverSetOptionProc) _ANSI_ARGS_((
ClientData instanceData, Tcl_Interp *interp,
- CONST char *optionName, CONST char *value));
+ CONST char *optionName, CONST char *value));
typedef int (Tcl_DriverGetOptionProc) _ANSI_ARGS_((
ClientData instanceData, Tcl_Interp *interp,
CONST84 char *optionName, Tcl_DString *dsPtr));
@@ -1520,125 +1436,111 @@ typedef void (Tcl_DriverWatchProc) _ANSI_ARGS_((
typedef int (Tcl_DriverGetHandleProc) _ANSI_ARGS_((
ClientData instanceData, int direction,
ClientData *handlePtr));
-typedef int (Tcl_DriverFlushProc) _ANSI_ARGS_((
- ClientData instanceData));
+typedef int (Tcl_DriverFlushProc) _ANSI_ARGS_((ClientData instanceData));
typedef int (Tcl_DriverHandlerProc) _ANSI_ARGS_((
ClientData instanceData, int interestMask));
typedef Tcl_WideInt (Tcl_DriverWideSeekProc) _ANSI_ARGS_((
ClientData instanceData, Tcl_WideInt offset,
int mode, int *errorCodePtr));
-
- /* TIP #218, Channel Thread Actions */
-typedef void (Tcl_DriverThreadActionProc) _ANSI_ARGS_ ((
- ClientData instanceData, int action));
-
/*
- * The following declarations either map ckalloc and ckfree to
- * malloc and free, or they map them to procedures with all sorts
- * of debugging hooks defined in tclCkalloc.c.
+ * TIP #218, Channel Thread Actions
*/
-#ifdef TCL_MEM_DEBUG
-
-# define ckalloc(x) Tcl_DbCkalloc(x, __FILE__, __LINE__)
-# define ckfree(x) Tcl_DbCkfree(x, __FILE__, __LINE__)
-# define ckrealloc(x,y) Tcl_DbCkrealloc((x), (y),__FILE__, __LINE__)
-# define attemptckalloc(x) Tcl_AttemptDbCkalloc(x, __FILE__, __LINE__)
-# define attemptckrealloc(x,y) Tcl_AttemptDbCkrealloc((x), (y), __FILE__, __LINE__)
-#else /* !TCL_MEM_DEBUG */
-
+typedef void (Tcl_DriverThreadActionProc) _ANSI_ARGS_ ((
+ ClientData instanceData, int action));
/*
- * If we are not using the debugging allocator, we should call the
- * Tcl_Alloc, et al. routines in order to guarantee that every module
- * is using the same memory allocator both inside and outside of the
- * Tcl library.
+ * TIP #208, File Truncation (etc.)
*/
-# define ckalloc(x) Tcl_Alloc(x)
-# define ckfree(x) Tcl_Free(x)
-# define ckrealloc(x,y) Tcl_Realloc(x,y)
-# define attemptckalloc(x) Tcl_AttemptAlloc(x)
-# define attemptckrealloc(x,y) Tcl_AttemptRealloc(x,y)
-# define Tcl_InitMemory(x)
-# define Tcl_DumpActiveMemory(x)
-# define Tcl_ValidateAllMemory(x,y)
-
-#endif /* !TCL_MEM_DEBUG */
+typedef int (Tcl_DriverTruncateProc) _ANSI_ARGS_((
+ ClientData instanceData, Tcl_WideInt length));
/*
* struct Tcl_ChannelType:
*
- * One such structure exists for each type (kind) of channel.
- * It collects together in one place all the functions that are
- * part of the specific channel type.
+ * One such structure exists for each type (kind) of channel. It collects
+ * together in one place all the functions that are part of the specific
+ * channel type.
*
- * It is recommend that the Tcl_Channel* functions are used to access
- * elements of this structure, instead of direct accessing.
+ * It is recommend that the Tcl_Channel* functions are used to access elements
+ * of this structure, instead of direct accessing.
*/
typedef struct Tcl_ChannelType {
- char *typeName; /* The name of the channel type in Tcl
- * commands. This storage is owned by
- * channel type. */
- Tcl_ChannelTypeVersion version; /* Version of the channel type. */
- Tcl_DriverCloseProc *closeProc; /* Procedure to call to close the
- * channel, or TCL_CLOSE2PROC if the
- * close2Proc should be used
- * instead. */
- Tcl_DriverInputProc *inputProc; /* Procedure to call for input
- * on channel. */
- Tcl_DriverOutputProc *outputProc; /* Procedure to call for output
- * on channel. */
- Tcl_DriverSeekProc *seekProc; /* Procedure to call to seek
- * on the channel. May be NULL. */
+ char *typeName; /* The name of the channel type in Tcl
+ * commands. This storage is owned by channel
+ * type. */
+ Tcl_ChannelTypeVersion version;
+ /* Version of the channel type. */
+ Tcl_DriverCloseProc *closeProc;
+ /* Function to call to close the channel, or
+ * TCL_CLOSE2PROC if the close2Proc should be
+ * used instead. */
+ Tcl_DriverInputProc *inputProc;
+ /* Function to call for input on channel. */
+ Tcl_DriverOutputProc *outputProc;
+ /* Function to call for output on channel. */
+ Tcl_DriverSeekProc *seekProc;
+ /* Function to call to seek on the channel.
+ * May be NULL. */
Tcl_DriverSetOptionProc *setOptionProc;
- /* Set an option on a channel. */
+ /* Set an option on a channel. */
Tcl_DriverGetOptionProc *getOptionProc;
- /* Get an option from a channel. */
- Tcl_DriverWatchProc *watchProc; /* Set up the notifier to watch
- * for events on this channel. */
+ /* Get an option from a channel. */
+ Tcl_DriverWatchProc *watchProc;
+ /* Set up the notifier to watch for events on
+ * this channel. */
Tcl_DriverGetHandleProc *getHandleProc;
- /* Get an OS handle from the channel
- * or NULL if not supported. */
- Tcl_DriverClose2Proc *close2Proc; /* Procedure to call to close the
- * channel if the device supports
- * closing the read & write sides
- * independently. */
+ /* Get an OS handle from the channel or NULL
+ * if not supported. */
+ Tcl_DriverClose2Proc *close2Proc;
+ /* Function to call to close the channel if
+ * the device supports closing the read &
+ * write sides independently. */
Tcl_DriverBlockModeProc *blockModeProc;
- /* Set blocking mode for the
- * raw channel. May be NULL. */
+ /* Set blocking mode for the raw channel. May
+ * be NULL. */
/*
- * Only valid in TCL_CHANNEL_VERSION_2 channels or later
+ * Only valid in TCL_CHANNEL_VERSION_2 channels or later.
*/
- Tcl_DriverFlushProc *flushProc; /* Procedure to call to flush a
- * channel. May be NULL. */
- Tcl_DriverHandlerProc *handlerProc; /* Procedure to call to handle a
- * channel event. This will be passed
- * up the stacked channel chain. */
+ Tcl_DriverFlushProc *flushProc;
+ /* Function to call to flush a channel. May be
+ * NULL. */
+ Tcl_DriverHandlerProc *handlerProc;
+ /* Function to call to handle a channel event.
+ * This will be passed up the stacked channel
+ * chain. */
/*
- * Only valid in TCL_CHANNEL_VERSION_3 channels or later
+ * Only valid in TCL_CHANNEL_VERSION_3 channels or later.
*/
Tcl_DriverWideSeekProc *wideSeekProc;
- /* Procedure to call to seek
- * on the channel which can
- * handle 64-bit offsets. May be
- * NULL, and must be NULL if
- * seekProc is NULL. */
-
- /*
- * Only valid in TCL_CHANNEL_VERSION_4 channels or later
- * TIP #218, Channel Thread Actions
- */
- Tcl_DriverThreadActionProc *threadActionProc;
- /* Procedure to call to notify
- * the driver of thread specific
- * activity for a channel.
- * May be NULL. */
+ /* Function to call to seek on the channel
+ * which can handle 64-bit offsets. May be
+ * NULL, and must be NULL if seekProc is
+ * NULL. */
+ /*
+ * Only valid in TCL_CHANNEL_VERSION_4 channels or later.
+ * TIP #218, Channel Thread Actions.
+ */
+ Tcl_DriverThreadActionProc *threadActionProc;
+ /* Function to call to notify the driver of
+ * thread specific activity for a channel. May
+ * be NULL. */
+
+ /*
+ * Only valid in TCL_CHANNEL_VERSION_5 channels or later.
+ * TIP #208, File Truncation.
+ */
+ Tcl_DriverTruncateProc *truncateProc;
+ /* Function to call to truncate the underlying
+ * file to a particular length. May be NULL if
+ * the channel does not support truncation. */
} Tcl_ChannelType;
/*
- * The following flags determine whether the blockModeProc above should
- * set the channel into blocking or nonblocking mode. They are passed
- * as arguments to the blockModeProc procedure in the above structure.
+ * The following flags determine whether the blockModeProc above should set
+ * the channel into blocking or nonblocking mode. They are passed as arguments
+ * to the blockModeProc function in the above structure.
*/
+
#define TCL_MODE_BLOCKING 0 /* Put channel into blocking mode. */
#define TCL_MODE_NONBLOCKING 1 /* Put channel into nonblocking
* mode. */
@@ -1653,23 +1555,20 @@ typedef enum Tcl_PathType {
TCL_PATH_VOLUME_RELATIVE
} Tcl_PathType;
-/*
- * The following structure is used to pass glob type data amongst
- * the various glob routines and Tcl_FSMatchInDirectory.
+/*
+ * The following structure is used to pass glob type data amongst the various
+ * glob routines and Tcl_FSMatchInDirectory.
*/
+
typedef struct Tcl_GlobTypeData {
- /* Corresponds to bcdpfls as in 'find -t' */
- int type;
- /* Corresponds to file permissions */
- int perm;
- /* Acceptable mac type */
- Tcl_Obj* macType;
- /* Acceptable mac creator */
- Tcl_Obj* macCreator;
+ int type; /* Corresponds to bcdpfls as in 'find -t'. */
+ int perm; /* Corresponds to file permissions. */
+ Tcl_Obj *macType; /* Acceptable Mac type. */
+ Tcl_Obj *macCreator; /* Acceptable Mac creator. */
} Tcl_GlobTypeData;
/*
- * type and permission definitions for glob command
+ * Type and permission definitions for glob command.
*/
#define TCL_GLOB_TYPE_BLOCK (1<<0)
@@ -1688,65 +1587,69 @@ typedef struct Tcl_GlobTypeData {
#define TCL_GLOB_PERM_X (1<<4)
/*
+ * Flags for the unload callback function.
+ */
+
+#define TCL_UNLOAD_DETACH_FROM_INTERPRETER (1<<0)
+#define TCL_UNLOAD_DETACH_FROM_PROCESS (1<<1)
+
+/*
* Typedefs for the various filesystem operations:
*/
typedef int (Tcl_FSStatProc) _ANSI_ARGS_((Tcl_Obj *pathPtr, Tcl_StatBuf *buf));
typedef int (Tcl_FSAccessProc) _ANSI_ARGS_((Tcl_Obj *pathPtr, int mode));
-typedef Tcl_Channel (Tcl_FSOpenFileChannelProc)
- _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *pathPtr,
- int mode, int permissions));
-typedef int (Tcl_FSMatchInDirectoryProc) _ANSI_ARGS_((Tcl_Interp* interp,
- Tcl_Obj *result, Tcl_Obj *pathPtr, CONST char *pattern,
+typedef Tcl_Channel (Tcl_FSOpenFileChannelProc) _ANSI_ARGS_((
+ Tcl_Interp *interp, Tcl_Obj *pathPtr, int mode, int permissions));
+typedef int (Tcl_FSMatchInDirectoryProc) _ANSI_ARGS_((Tcl_Interp *interp,
+ Tcl_Obj *result, Tcl_Obj *pathPtr, CONST char *pattern,
Tcl_GlobTypeData * types));
-typedef Tcl_Obj* (Tcl_FSGetCwdProc) _ANSI_ARGS_((Tcl_Interp *interp));
+typedef Tcl_Obj * (Tcl_FSGetCwdProc) _ANSI_ARGS_((Tcl_Interp *interp));
typedef int (Tcl_FSChdirProc) _ANSI_ARGS_((Tcl_Obj *pathPtr));
-typedef int (Tcl_FSLstatProc) _ANSI_ARGS_((Tcl_Obj *pathPtr,
- Tcl_StatBuf *buf));
+typedef int (Tcl_FSLstatProc) _ANSI_ARGS_((Tcl_Obj *pathPtr,
+ Tcl_StatBuf *buf));
typedef int (Tcl_FSCreateDirectoryProc) _ANSI_ARGS_((Tcl_Obj *pathPtr));
typedef int (Tcl_FSDeleteFileProc) _ANSI_ARGS_((Tcl_Obj *pathPtr));
typedef int (Tcl_FSCopyDirectoryProc) _ANSI_ARGS_((Tcl_Obj *srcPathPtr,
- Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr));
+ Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr));
typedef int (Tcl_FSCopyFileProc) _ANSI_ARGS_((Tcl_Obj *srcPathPtr,
- Tcl_Obj *destPathPtr));
+ Tcl_Obj *destPathPtr));
typedef int (Tcl_FSRemoveDirectoryProc) _ANSI_ARGS_((Tcl_Obj *pathPtr,
- int recursive, Tcl_Obj **errorPtr));
+ int recursive, Tcl_Obj **errorPtr));
typedef int (Tcl_FSRenameFileProc) _ANSI_ARGS_((Tcl_Obj *srcPathPtr,
- Tcl_Obj *destPathPtr));
+ Tcl_Obj *destPathPtr));
typedef void (Tcl_FSUnloadFileProc) _ANSI_ARGS_((Tcl_LoadHandle loadHandle));
-typedef Tcl_Obj* (Tcl_FSListVolumesProc) _ANSI_ARGS_((void));
+typedef Tcl_Obj * (Tcl_FSListVolumesProc) _ANSI_ARGS_((void));
/* We have to declare the utime structure here. */
struct utimbuf;
-typedef int (Tcl_FSUtimeProc) _ANSI_ARGS_((Tcl_Obj *pathPtr,
- struct utimbuf *tval));
-typedef int (Tcl_FSNormalizePathProc) _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_Obj *pathPtr, int nextCheckpoint));
+typedef int (Tcl_FSUtimeProc) _ANSI_ARGS_((Tcl_Obj *pathPtr,
+ struct utimbuf *tval));
+typedef int (Tcl_FSNormalizePathProc) _ANSI_ARGS_((Tcl_Interp *interp,
+ Tcl_Obj *pathPtr, int nextCheckpoint));
typedef int (Tcl_FSFileAttrsGetProc) _ANSI_ARGS_((Tcl_Interp *interp,
- int index, Tcl_Obj *pathPtr,
- Tcl_Obj **objPtrRef));
-typedef CONST char** (Tcl_FSFileAttrStringsProc) _ANSI_ARGS_((Tcl_Obj *pathPtr,
- Tcl_Obj** objPtrRef));
+ int index, Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef));
+typedef CONST char ** (Tcl_FSFileAttrStringsProc) _ANSI_ARGS_((
+ Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef));
typedef int (Tcl_FSFileAttrsSetProc) _ANSI_ARGS_((Tcl_Interp *interp,
- int index, Tcl_Obj *pathPtr,
- Tcl_Obj *objPtr));
-typedef Tcl_Obj* (Tcl_FSLinkProc) _ANSI_ARGS_((Tcl_Obj *pathPtr,
- Tcl_Obj *toPtr, int linkType));
-typedef int (Tcl_FSLoadFileProc) _ANSI_ARGS_((Tcl_Interp * interp,
- Tcl_Obj *pathPtr,
- Tcl_LoadHandle *handlePtr,
- Tcl_FSUnloadFileProc **unloadProcPtr));
-typedef int (Tcl_FSPathInFilesystemProc) _ANSI_ARGS_((Tcl_Obj *pathPtr,
- ClientData *clientDataPtr));
-typedef Tcl_Obj* (Tcl_FSFilesystemPathTypeProc)
- _ANSI_ARGS_((Tcl_Obj *pathPtr));
-typedef Tcl_Obj* (Tcl_FSFilesystemSeparatorProc)
- _ANSI_ARGS_((Tcl_Obj *pathPtr));
+ int index, Tcl_Obj *pathPtr, Tcl_Obj *objPtr));
+typedef Tcl_Obj * (Tcl_FSLinkProc) _ANSI_ARGS_((Tcl_Obj *pathPtr,
+ Tcl_Obj *toPtr, int linkType));
+typedef int (Tcl_FSLoadFileProc) _ANSI_ARGS_((Tcl_Interp * interp,
+ Tcl_Obj *pathPtr, Tcl_LoadHandle *handlePtr,
+ Tcl_FSUnloadFileProc **unloadProcPtr));
+typedef int (Tcl_FSPathInFilesystemProc) _ANSI_ARGS_((Tcl_Obj *pathPtr,
+ ClientData *clientDataPtr));
+typedef Tcl_Obj * (Tcl_FSFilesystemPathTypeProc) _ANSI_ARGS_((
+ Tcl_Obj *pathPtr));
+typedef Tcl_Obj * (Tcl_FSFilesystemSeparatorProc) _ANSI_ARGS_((
+ Tcl_Obj *pathPtr));
typedef void (Tcl_FSFreeInternalRepProc) _ANSI_ARGS_((ClientData clientData));
-typedef ClientData (Tcl_FSDupInternalRepProc)
- _ANSI_ARGS_((ClientData clientData));
-typedef Tcl_Obj* (Tcl_FSInternalToNormalizedProc)
- _ANSI_ARGS_((ClientData clientData));
-typedef ClientData (Tcl_FSCreateInternalRepProc) _ANSI_ARGS_((Tcl_Obj *pathPtr));
+typedef ClientData (Tcl_FSDupInternalRepProc) _ANSI_ARGS_((
+ ClientData clientData));
+typedef Tcl_Obj * (Tcl_FSInternalToNormalizedProc) _ANSI_ARGS_((
+ ClientData clientData));
+typedef ClientData (Tcl_FSCreateInternalRepProc) _ANSI_ARGS_((
+ Tcl_Obj *pathPtr));
typedef struct Tcl_FSVersion_ *Tcl_FSVersion;
@@ -1764,207 +1667,181 @@ typedef struct Tcl_FSVersion_ *Tcl_FSVersion;
/*
* struct Tcl_Filesystem:
*
- * One such structure exists for each type (kind) of filesystem.
- * It collects together in one place all the functions that are
- * part of the specific filesystem. Tcl always accesses the
- * filesystem through one of these structures.
- *
- * Not all entries need be non-NULL; any which are NULL are simply
- * ignored. However, a complete filesystem should provide all of
- * these functions. The explanations in the structure show
- * the importance of each function.
+ * One such structure exists for each type (kind) of filesystem. It collects
+ * together in one place all the functions that are part of the specific
+ * filesystem. Tcl always accesses the filesystem through one of these
+ * structures.
+ *
+ * Not all entries need be non-NULL; any which are NULL are simply ignored.
+ * However, a complete filesystem should provide all of these functions. The
+ * explanations in the structure show the importance of each function.
*/
typedef struct Tcl_Filesystem {
- CONST char *typeName; /* The name of the filesystem. */
- int structureLength; /* Length of this structure, so future
- * binary compatibility can be assured. */
- Tcl_FSVersion version;
- /* Version of the filesystem type. */
+ CONST char *typeName; /* The name of the filesystem. */
+ int structureLength; /* Length of this structure, so future binary
+ * compatibility can be assured. */
+ Tcl_FSVersion version; /* Version of the filesystem type. */
Tcl_FSPathInFilesystemProc *pathInFilesystemProc;
- /* Function to check whether a path is in
- * this filesystem. This is the most
- * important filesystem procedure. */
+ /* Function to check whether a path is in this
+ * filesystem. This is the most important
+ * filesystem function. */
Tcl_FSDupInternalRepProc *dupInternalRepProc;
- /* Function to duplicate internal fs rep. May
- * be NULL (but then fs is less efficient). */
+ /* Function to duplicate internal fs rep. May
+ * be NULL (but then fs is less efficient). */
Tcl_FSFreeInternalRepProc *freeInternalRepProc;
- /* Function to free internal fs rep. Must
- * be implemented, if internal representations
- * need freeing, otherwise it can be NULL. */
+ /* Function to free internal fs rep. Must be
+ * implemented if internal representations
+ * need freeing, otherwise it can be NULL. */
Tcl_FSInternalToNormalizedProc *internalToNormalizedProc;
- /* Function to convert internal representation
- * to a normalized path. Only required if
- * the fs creates pure path objects with no
- * string/path representation. */
+ /* Function to convert internal representation
+ * to a normalized path. Only required if the
+ * fs creates pure path objects with no
+ * string/path representation. */
Tcl_FSCreateInternalRepProc *createInternalRepProc;
- /* Function to create a filesystem-specific
- * internal representation. May be NULL
- * if paths have no internal representation,
- * or if the Tcl_FSPathInFilesystemProc
- * for this filesystem always immediately
- * creates an internal representation for
- * paths it accepts. */
- Tcl_FSNormalizePathProc *normalizePathProc;
- /* Function to normalize a path. Should
- * be implemented for all filesystems
- * which can have multiple string
- * representations for the same path
- * object. */
+ /* Function to create a filesystem-specific
+ * internal representation. May be NULL if
+ * paths have no internal representation, or
+ * if the Tcl_FSPathInFilesystemProc for this
+ * filesystem always immediately creates an
+ * internal representation for paths it
+ * accepts. */
+ Tcl_FSNormalizePathProc *normalizePathProc;
+ /* Function to normalize a path. Should be
+ * implemented for all filesystems which can
+ * have multiple string representations for
+ * the same path object. */
Tcl_FSFilesystemPathTypeProc *filesystemPathTypeProc;
- /* Function to determine the type of a
- * path in this filesystem. May be NULL. */
+ /* Function to determine the type of a path in
+ * this filesystem. May be NULL. */
Tcl_FSFilesystemSeparatorProc *filesystemSeparatorProc;
- /* Function to return the separator
- * character(s) for this filesystem. Must
- * be implemented. */
- Tcl_FSStatProc *statProc;
- /*
- * Function to process a 'Tcl_FSStat()'
- * call. Must be implemented for any
- * reasonable filesystem.
- */
- Tcl_FSAccessProc *accessProc;
- /*
- * Function to process a 'Tcl_FSAccess()'
- * call. Must be implemented for any
- * reasonable filesystem.
- */
- Tcl_FSOpenFileChannelProc *openFileChannelProc;
- /*
- * Function to process a
- * 'Tcl_FSOpenFileChannel()' call. Must be
- * implemented for any reasonable
- * filesystem.
- */
- Tcl_FSMatchInDirectoryProc *matchInDirectoryProc;
- /* Function to process a
- * 'Tcl_FSMatchInDirectory()'. If not
- * implemented, then glob and recursive
- * copy functionality will be lacking in
- * the filesystem. */
- Tcl_FSUtimeProc *utimeProc;
- /* Function to process a
- * 'Tcl_FSUtime()' call. Required to
- * allow setting (not reading) of times
- * with 'file mtime', 'file atime' and
- * the open-r/open-w/fcopy implementation
- * of 'file copy'. */
- Tcl_FSLinkProc *linkProc;
- /* Function to process a
- * 'Tcl_FSLink()' call. Should be
- * implemented only if the filesystem supports
- * links (reading or creating). */
- Tcl_FSListVolumesProc *listVolumesProc;
- /* Function to list any filesystem volumes
- * added by this filesystem. Should be
- * implemented only if the filesystem adds
- * volumes at the head of the filesystem. */
+ /* Function to return the separator
+ * character(s) for this filesystem. Must be
+ * implemented. */
+ Tcl_FSStatProc *statProc; /* Function to process a 'Tcl_FSStat()' call.
+ * Must be implemented for any reasonable
+ * filesystem. */
+ Tcl_FSAccessProc *accessProc;
+ /* Function to process a 'Tcl_FSAccess()'
+ * call. Must be implemented for any
+ * reasonable filesystem. */
+ Tcl_FSOpenFileChannelProc *openFileChannelProc;
+ /* Function to process a
+ * 'Tcl_FSOpenFileChannel()' call. Must be
+ * implemented for any reasonable
+ * filesystem. */
+ Tcl_FSMatchInDirectoryProc *matchInDirectoryProc;
+ /* Function to process a
+ * 'Tcl_FSMatchInDirectory()'. If not
+ * implemented, then glob and recursive copy
+ * functionality will be lacking in the
+ * filesystem. */
+ Tcl_FSUtimeProc *utimeProc; /* Function to process a 'Tcl_FSUtime()' call.
+ * Required to allow setting (not reading) of
+ * times with 'file mtime', 'file atime' and
+ * the open-r/open-w/fcopy implementation of
+ * 'file copy'. */
+ Tcl_FSLinkProc *linkProc; /* Function to process a 'Tcl_FSLink()' call.
+ * Should be implemented only if the
+ * filesystem supports links (reading or
+ * creating). */
+ Tcl_FSListVolumesProc *listVolumesProc;
+ /* Function to list any filesystem volumes
+ * added by this filesystem. Should be
+ * implemented only if the filesystem adds
+ * volumes at the head of the filesystem. */
Tcl_FSFileAttrStringsProc *fileAttrStringsProc;
- /* Function to list all attributes strings
- * which are valid for this filesystem.
- * If not implemented the filesystem will
- * not support the 'file attributes' command.
- * This allows arbitrary additional information
- * to be attached to files in the filesystem. */
+ /* Function to list all attributes strings
+ * which are valid for this filesystem. If not
+ * implemented the filesystem will not support
+ * the 'file attributes' command. This allows
+ * arbitrary additional information to be
+ * attached to files in the filesystem. */
Tcl_FSFileAttrsGetProc *fileAttrsGetProc;
- /* Function to process a
- * 'Tcl_FSFileAttrsGet()' call, used by
- * 'file attributes'. */
+ /* Function to process a
+ * 'Tcl_FSFileAttrsGet()' call, used by 'file
+ * attributes'. */
Tcl_FSFileAttrsSetProc *fileAttrsSetProc;
- /* Function to process a
- * 'Tcl_FSFileAttrsSet()' call, used by
- * 'file attributes'. */
- Tcl_FSCreateDirectoryProc *createDirectoryProc;
- /* Function to process a
- * 'Tcl_FSCreateDirectory()' call. Should
- * be implemented unless the FS is
- * read-only. */
- Tcl_FSRemoveDirectoryProc *removeDirectoryProc;
- /* Function to process a
- * 'Tcl_FSRemoveDirectory()' call. Should
- * be implemented unless the FS is
- * read-only. */
- Tcl_FSDeleteFileProc *deleteFileProc;
- /* Function to process a
- * 'Tcl_FSDeleteFile()' call. Should
- * be implemented unless the FS is
- * read-only. */
- Tcl_FSCopyFileProc *copyFileProc;
- /* Function to process a
- * 'Tcl_FSCopyFile()' call. If not
- * implemented Tcl will fall back
- * on open-r, open-w and fcopy as
- * a copying mechanism, for copying
- * actions initiated in Tcl (not C). */
- Tcl_FSRenameFileProc *renameFileProc;
- /* Function to process a
- * 'Tcl_FSRenameFile()' call. If not
- * implemented, Tcl will fall back on
- * a copy and delete mechanism, for
- * rename actions initiated in Tcl (not C). */
- Tcl_FSCopyDirectoryProc *copyDirectoryProc;
- /* Function to process a
- * 'Tcl_FSCopyDirectory()' call. If
- * not implemented, Tcl will fall back
- * on a recursive create-dir, file copy
- * mechanism, for copying actions
- * initiated in Tcl (not C). */
- Tcl_FSLstatProc *lstatProc;
- /* Function to process a
- * 'Tcl_FSLstat()' call. If not implemented,
- * Tcl will attempt to use the 'statProc'
- * defined above instead. */
- Tcl_FSLoadFileProc *loadFileProc;
- /* Function to process a
- * 'Tcl_FSLoadFile()' call. If not
- * implemented, Tcl will fall back on
- * a copy to native-temp followed by a
- * Tcl_FSLoadFile on that temporary copy. */
- Tcl_FSGetCwdProc *getCwdProc;
- /*
- * Function to process a 'Tcl_FSGetCwd()'
- * call. Most filesystems need not
- * implement this. It will usually only be
- * called once, if 'getcwd' is called
- * before 'chdir'. May be NULL.
- */
- Tcl_FSChdirProc *chdirProc;
- /*
- * Function to process a 'Tcl_FSChdir()'
- * call. If filesystems do not implement
- * this, it will be emulated by a series of
- * directory access checks. Otherwise,
- * virtual filesystems which do implement
- * it need only respond with a positive
- * return result if the dirName is a valid
- * directory in their filesystem. They
- * need not remember the result, since that
- * will be automatically remembered for use
- * by GetCwd. Real filesystems should
- * carry out the correct action (i.e. call
- * the correct system 'chdir' api). If not
- * implemented, then 'cd' and 'pwd' will
- * fail inside the filesystem.
- */
+ /* Function to process a
+ * 'Tcl_FSFileAttrsSet()' call, used by 'file
+ * attributes'. */
+ Tcl_FSCreateDirectoryProc *createDirectoryProc;
+ /* Function to process a
+ * 'Tcl_FSCreateDirectory()' call. Should be
+ * implemented unless the FS is read-only. */
+ Tcl_FSRemoveDirectoryProc *removeDirectoryProc;
+ /* Function to process a
+ * 'Tcl_FSRemoveDirectory()' call. Should be
+ * implemented unless the FS is read-only. */
+ Tcl_FSDeleteFileProc *deleteFileProc;
+ /* Function to process a 'Tcl_FSDeleteFile()'
+ * call. Should be implemented unless the FS
+ * is read-only. */
+ Tcl_FSCopyFileProc *copyFileProc;
+ /* Function to process a 'Tcl_FSCopyFile()'
+ * call. If not implemented Tcl will fall back
+ * on open-r, open-w and fcopy as a copying
+ * mechanism, for copying actions initiated in
+ * Tcl (not C). */
+ Tcl_FSRenameFileProc *renameFileProc;
+ /* Function to process a 'Tcl_FSRenameFile()'
+ * call. If not implemented, Tcl will fall
+ * back on a copy and delete mechanism, for
+ * rename actions initiated in Tcl (not C). */
+ Tcl_FSCopyDirectoryProc *copyDirectoryProc;
+ /* Function to process a
+ * 'Tcl_FSCopyDirectory()' call. If not
+ * implemented, Tcl will fall back on a
+ * recursive create-dir, file copy mechanism,
+ * for copying actions initiated in Tcl (not
+ * C). */
+ Tcl_FSLstatProc *lstatProc; /* Function to process a 'Tcl_FSLstat()' call.
+ * If not implemented, Tcl will attempt to use
+ * the 'statProc' defined above instead. */
+ Tcl_FSLoadFileProc *loadFileProc;
+ /* Function to process a 'Tcl_FSLoadFile()'
+ * call. If not implemented, Tcl will fall
+ * back on a copy to native-temp followed by a
+ * Tcl_FSLoadFile on that temporary copy. */
+ Tcl_FSGetCwdProc *getCwdProc;
+ /* Function to process a 'Tcl_FSGetCwd()'
+ * call. Most filesystems need not implement
+ * this. It will usually only be called once,
+ * if 'getcwd' is called before 'chdir'. May
+ * be NULL. */
+ Tcl_FSChdirProc *chdirProc; /* Function to process a 'Tcl_FSChdir()' call.
+ * If filesystems do not implement this, it
+ * will be emulated by a series of directory
+ * access checks. Otherwise, virtual
+ * filesystems which do implement it need only
+ * respond with a positive return result if
+ * the dirName is a valid directory in their
+ * filesystem. They need not remember the
+ * result, since that will be automatically
+ * remembered for use by GetCwd. Real
+ * filesystems should carry out the correct
+ * action (i.e. call the correct system
+ * 'chdir' api). If not implemented, then 'cd'
+ * and 'pwd' will fail inside the
+ * filesystem. */
} Tcl_Filesystem;
/*
- * The following definitions are used as values for the 'linkAction' flag
- * to Tcl_FSLink, or the linkProc of any filesystem. Any combination
- * of flags can be given. For link creation, the linkProc should create
- * a link which matches any of the types given.
- *
- * TCL_CREATE_SYMBOLIC_LINK: Create a symbolic or soft link.
- * TCL_CREATE_HARD_LINK: Create a hard link.
+ * The following definitions are used as values for the 'linkAction' flag to
+ * Tcl_FSLink, or the linkProc of any filesystem. Any combination of flags can
+ * be given. For link creation, the linkProc should create a link which
+ * matches any of the types given.
+ *
+ * TCL_CREATE_SYMBOLIC_LINK - Create a symbolic or soft link.
+ * TCL_CREATE_HARD_LINK - Create a hard link.
*/
-#define TCL_CREATE_SYMBOLIC_LINK 0x01
-#define TCL_CREATE_HARD_LINK 0x02
+#define TCL_CREATE_SYMBOLIC_LINK 0x01
+#define TCL_CREATE_HARD_LINK 0x02
/*
- * The following structure represents the Notifier functions that
- * you can override with the Tcl_SetNotifier call.
+ * The following structure represents the Notifier functions that you can
+ * override with the Tcl_SetNotifier call.
*/
typedef struct Tcl_NotifierProcs {
@@ -1979,163 +1856,159 @@ typedef struct Tcl_NotifierProcs {
} Tcl_NotifierProcs;
/*
- * The following structure represents a user-defined encoding. It collects
+ * The following structure represents a user-defined encoding. It collects
* together all the functions that are used by the specific encoding.
*/
typedef struct Tcl_EncodingType {
- CONST char *encodingName; /* The name of the encoding, e.g. "euc-jp".
+ CONST char *encodingName; /* The name of the encoding, e.g. "euc-jp".
* This name is the unique key for this
* encoding type. */
Tcl_EncodingConvertProc *toUtfProc;
- /* Procedure to convert from external
- * encoding into UTF-8. */
+ /* Function to convert from external encoding
+ * into UTF-8. */
Tcl_EncodingConvertProc *fromUtfProc;
- /* Procedure to convert from UTF-8 into
+ /* Function to convert from UTF-8 into
* external encoding. */
Tcl_EncodingFreeProc *freeProc;
- /* If non-NULL, procedure to call when this
+ /* If non-NULL, function to call when this
* encoding is deleted. */
ClientData clientData; /* Arbitrary value associated with encoding
- * type. Passed to conversion procedures. */
+ * type. Passed to conversion functions. */
int nullSize; /* Number of zero bytes that signify
- * end-of-string in this encoding. This
- * number is used to determine the source
- * string length when the srcLen argument is
- * negative. Must be 1 or 2. */
-} Tcl_EncodingType;
+ * end-of-string in this encoding. This number
+ * is used to determine the source string
+ * length when the srcLen argument is
+ * negative. Must be 1 or 2. */
+} Tcl_EncodingType;
/*
* The following definitions are used as values for the conversion control
* flags argument when converting text from one character set to another:
*
- * TCL_ENCODING_START: Signifies that the source buffer is the first
+ * TCL_ENCODING_START - Signifies that the source buffer is the first
* block in a (potentially multi-block) input
- * stream. Tells the conversion procedure to
- * reset to an initial state and perform any
+ * stream. Tells the conversion function to reset
+ * to an initial state and perform any
* initialization that needs to occur before the
- * first byte is converted. If the source
- * buffer contains the entire input stream to be
+ * first byte is converted. If the source buffer
+ * contains the entire input stream to be
* converted, this flag should be set.
- *
- * TCL_ENCODING_END: Signifies that the source buffer is the last
+ * TCL_ENCODING_END - Signifies that the source buffer is the last
* block in a (potentially multi-block) input
- * stream. Tells the conversion routine to
+ * stream. Tells the conversion routine to
* perform any finalization that needs to occur
* after the last byte is converted and then to
- * reset to an initial state. If the source
+ * reset to an initial state. If the source
* buffer contains the entire input stream to be
* converted, this flag should be set.
- *
- * TCL_ENCODING_STOPONERROR: If set, then the converter will return
- * immediately upon encountering an invalid
- * byte sequence or a source character that has
- * no mapping in the target encoding. If clear,
- * then the converter will skip the problem,
- * substituting one or more "close" characters
- * in the destination buffer and then continue
- * to sonvert the source.
+ * TCL_ENCODING_STOPONERROR - If set, then the converter will return
+ * immediately upon encountering an invalid byte
+ * sequence or a source character that has no
+ * mapping in the target encoding. If clear, then
+ * the converter will skip the problem,
+ * substituting one or more "close" characters in
+ * the destination buffer and then continue to
+ * convert the source.
*/
+
#define TCL_ENCODING_START 0x01
#define TCL_ENCODING_END 0x02
#define TCL_ENCODING_STOPONERROR 0x04
/*
- * The following data structures and declarations are for the new Tcl
- * parser.
+ * The following data structures and declarations are for the new Tcl parser.
*/
/*
- * For each word of a command, and for each piece of a word such as a
- * variable reference, one of the following structures is created to
- * describe the token.
+ * For each word of a command, and for each piece of a word such as a variable
+ * reference, one of the following structures is created to describe the
+ * token.
*/
typedef struct Tcl_Token {
- int type; /* Type of token, such as TCL_TOKEN_WORD;
- * see below for valid types. */
+ int type; /* Type of token, such as TCL_TOKEN_WORD; see
+ * below for valid types. */
CONST char *start; /* First character in token. */
int size; /* Number of bytes in token. */
- int numComponents; /* If this token is composed of other
- * tokens, this field tells how many of
- * them there are (including components of
- * components, etc.). The component tokens
- * immediately follow this one. */
+ int numComponents; /* If this token is composed of other tokens,
+ * this field tells how many of them there are
+ * (including components of components, etc.).
+ * The component tokens immediately follow
+ * this one. */
} Tcl_Token;
/*
- * Type values defined for Tcl_Token structures. These values are
- * defined as mask bits so that it's easy to check for collections of
- * types.
+ * Type values defined for Tcl_Token structures. These values are defined as
+ * mask bits so that it's easy to check for collections of types.
*
* TCL_TOKEN_WORD - The token describes one word of a command,
- * from the first non-blank character of
- * the word (which may be " or {) up to but
- * not including the space, semicolon, or
- * bracket that terminates the word.
- * NumComponents counts the total number of
- * sub-tokens that make up the word. This
- * includes, for example, sub-tokens of
- * TCL_TOKEN_VARIABLE tokens.
- * TCL_TOKEN_SIMPLE_WORD - This token is just like TCL_TOKEN_WORD
- * except that the word is guaranteed to
- * consist of a single TCL_TOKEN_TEXT
- * sub-token.
- * TCL_TOKEN_TEXT - The token describes a range of literal
- * text that is part of a word.
- * NumComponents is always 0.
- * TCL_TOKEN_BS - The token describes a backslash sequence
- * that must be collapsed. NumComponents
- * is always 0.
+ * from the first non-blank character of the word
+ * (which may be " or {) up to but not including
+ * the space, semicolon, or bracket that
+ * terminates the word. NumComponents counts the
+ * total number of sub-tokens that make up the
+ * word. This includes, for example, sub-tokens
+ * of TCL_TOKEN_VARIABLE tokens.
+ * TCL_TOKEN_SIMPLE_WORD - This token is just like TCL_TOKEN_WORD except
+ * that the word is guaranteed to consist of a
+ * single TCL_TOKEN_TEXT sub-token.
+ * TCL_TOKEN_TEXT - The token describes a range of literal text
+ * that is part of a word. NumComponents is
+ * always 0.
+ * TCL_TOKEN_BS - The token describes a backslash sequence that
+ * must be collapsed. NumComponents is always 0.
* TCL_TOKEN_COMMAND - The token describes a command whose result
- * must be substituted into the word. The
- * token includes the enclosing brackets.
- * NumComponents is always 0.
- * TCL_TOKEN_VARIABLE - The token describes a variable
- * substitution, including the dollar sign,
- * variable name, and array index (if there
- * is one) up through the right
- * parentheses. NumComponents tells how
- * many additional tokens follow to
- * represent the variable name. The first
- * token will be a TCL_TOKEN_TEXT token
- * that describes the variable name. If
- * the variable is an array reference then
- * there will be one or more additional
- * tokens, of type TCL_TOKEN_TEXT,
+ * must be substituted into the word. The token
+ * includes the enclosing brackets. NumComponents
+ * is always 0.
+ * TCL_TOKEN_VARIABLE - The token describes a variable substitution,
+ * including the dollar sign, variable name, and
+ * array index (if there is one) up through the
+ * right parentheses. NumComponents tells how
+ * many additional tokens follow to represent the
+ * variable name. The first token will be a
+ * TCL_TOKEN_TEXT token that describes the
+ * variable name. If the variable is an array
+ * reference then there will be one or more
+ * additional tokens, of type TCL_TOKEN_TEXT,
* TCL_TOKEN_BS, TCL_TOKEN_COMMAND, and
- * TCL_TOKEN_VARIABLE, that describe the
- * array index; numComponents counts the
- * total number of nested tokens that make
- * up the variable reference, including
- * sub-tokens of TCL_TOKEN_VARIABLE tokens.
- * TCL_TOKEN_SUB_EXPR - The token describes one subexpression of a
- * expression, from the first non-blank
- * character of the subexpression up to but not
- * including the space, brace, or bracket
- * that terminates the subexpression.
- * NumComponents counts the total number of
- * following subtokens that make up the
- * subexpression; this includes all subtokens
- * for any nested TCL_TOKEN_SUB_EXPR tokens.
- * For example, a numeric value used as a
+ * TCL_TOKEN_VARIABLE, that describe the array
+ * index; numComponents counts the total number
+ * of nested tokens that make up the variable
+ * reference, including sub-tokens of
+ * TCL_TOKEN_VARIABLE tokens.
+ * TCL_TOKEN_SUB_EXPR - The token describes one subexpression of an
+ * expression, from the first non-blank character
+ * of the subexpression up to but not including
+ * the space, brace, or bracket that terminates
+ * the subexpression. NumComponents counts the
+ * total number of following subtokens that make
+ * up the subexpression; this includes all
+ * subtokens for any nested TCL_TOKEN_SUB_EXPR
+ * tokens. For example, a numeric value used as a
* primitive operand is described by a
* TCL_TOKEN_SUB_EXPR token followed by a
* TCL_TOKEN_TEXT token. A binary subexpression
* is described by a TCL_TOKEN_SUB_EXPR token
- * followed by the TCL_TOKEN_OPERATOR token
- * for the operator, then TCL_TOKEN_SUB_EXPR
- * tokens for the left then the right operands.
+ * followed by the TCL_TOKEN_OPERATOR token for
+ * the operator, then TCL_TOKEN_SUB_EXPR tokens
+ * for the left then the right operands.
* TCL_TOKEN_OPERATOR - The token describes one expression operator.
* An operator might be the name of a math
* function such as "abs". A TCL_TOKEN_OPERATOR
* token is always preceeded by one
* TCL_TOKEN_SUB_EXPR token for the operator's
- * subexpression, and is followed by zero or
- * more TCL_TOKEN_SUB_EXPR tokens for the
- * operator's operands. NumComponents is
- * always 0.
+ * subexpression, and is followed by zero or more
+ * TCL_TOKEN_SUB_EXPR tokens for the operator's
+ * operands. NumComponents is always 0.
+ * TCL_TOKEN_EXPAND_WORD - This token is just like TCL_TOKEN_WORD except
+ * that it marks a word that began with the
+ * literal character prefix "{*}". This word is
+ * marked to be expanded - that is, broken into
+ * words after substitution is complete.
*/
+
#define TCL_TOKEN_WORD 1
#define TCL_TOKEN_SIMPLE_WORD 2
#define TCL_TOKEN_TEXT 4
@@ -2144,11 +2017,11 @@ typedef struct Tcl_Token {
#define TCL_TOKEN_VARIABLE 32
#define TCL_TOKEN_SUB_EXPR 64
#define TCL_TOKEN_OPERATOR 128
+#define TCL_TOKEN_EXPAND_WORD 256
/*
- * Parsing error types. On any parsing error, one of these values
- * will be stored in the error field of the Tcl_Parse structure
- * defined below.
+ * Parsing error types. On any parsing error, one of these values will be
+ * stored in the error field of the Tcl_Parse structure defined below.
*/
#define TCL_PARSE_SUCCESS 0
@@ -2163,32 +2036,32 @@ typedef struct Tcl_Token {
#define TCL_PARSE_BAD_NUMBER 9
/*
- * A structure of the following type is filled in by Tcl_ParseCommand.
- * It describes a single command parsed from an input string.
+ * A structure of the following type is filled in by Tcl_ParseCommand. It
+ * describes a single command parsed from an input string.
*/
#define NUM_STATIC_TOKENS 20
typedef struct Tcl_Parse {
- CONST char *commentStart; /* Pointer to # that begins the first of
- * one or more comments preceding the
- * command. */
+ CONST char *commentStart; /* Pointer to # that begins the first of one
+ * or more comments preceding the command. */
int commentSize; /* Number of bytes in comments (up through
- * newline character that terminates the
- * last comment). If there were no
- * comments, this field is 0. */
- CONST char *commandStart; /* First character in first word of command. */
- int commandSize; /* Number of bytes in command, including
- * first character of first word, up
- * through the terminating newline,
- * close bracket, or semicolon. */
- int numWords; /* Total number of words in command. May
- * be 0. */
- Tcl_Token *tokenPtr; /* Pointer to first token representing
- * the words of the command. Initially
- * points to staticTokens, but may change
- * to point to malloc-ed space if command
- * exceeds space in staticTokens. */
+ * newline character that terminates the last
+ * comment). If there were no comments, this
+ * field is 0. */
+ CONST char *commandStart; /* First character in first word of
+ * command. */
+ int commandSize; /* Number of bytes in command, including first
+ * character of first word, up through the
+ * terminating newline, close bracket, or
+ * semicolon. */
+ int numWords; /* Total number of words in command. May be
+ * 0. */
+ Tcl_Token *tokenPtr; /* Pointer to first token representing the
+ * words of the command. Initially points to
+ * staticTokens, but may change to point to
+ * malloc-ed space if command exceeds space in
+ * staticTokens. */
int numTokens; /* Total number of tokens in command. */
int tokensAvailable; /* Total number of tokens available at
* *tokenPtr. */
@@ -2196,81 +2069,75 @@ typedef struct Tcl_Parse {
* above. */
/*
- * The fields below are intended only for the private use of the
- * parser. They should not be used by procedures that invoke
- * Tcl_ParseCommand.
+ * The fields below are intended only for the private use of the parser.
+ * They should not be used by functions that invoke Tcl_ParseCommand.
*/
CONST char *string; /* The original command string passed to
* Tcl_ParseCommand. */
- CONST char *end; /* Points to the character just after the
- * last one in the command string. */
- Tcl_Interp *interp; /* Interpreter to use for error reporting,
- * or NULL. */
+ CONST char *end; /* Points to the character just after the last
+ * one in the command string. */
+ Tcl_Interp *interp; /* Interpreter to use for error reporting, or
+ * NULL. */
CONST char *term; /* Points to character in string that
- * terminated most recent token. Filled in
- * by ParseTokens. If an error occurs,
- * points to beginning of region where the
- * error occurred (e.g. the open brace if
- * the close brace is missing). */
+ * terminated most recent token. Filled in by
+ * ParseTokens. If an error occurs, points to
+ * beginning of region where the error
+ * occurred (e.g. the open brace if the close
+ * brace is missing). */
int incomplete; /* This field is set to 1 by Tcl_ParseCommand
* if the command appears to be incomplete.
* This information is used by
* Tcl_CommandComplete. */
Tcl_Token staticTokens[NUM_STATIC_TOKENS];
- /* Initial space for tokens for command.
- * This space should be large enough to
- * accommodate most commands; dynamic
- * space is allocated for very large
- * commands that don't fit here. */
+ /* Initial space for tokens for command. This
+ * space should be large enough to accommodate
+ * most commands; dynamic space is allocated
+ * for very large commands that don't fit
+ * here. */
} Tcl_Parse;
/*
* The following definitions are the error codes returned by the conversion
* routines:
*
- * TCL_OK: All characters were converted.
- *
- * TCL_CONVERT_NOSPACE: The output buffer would not have been large
+ * TCL_OK - All characters were converted.
+ * TCL_CONVERT_NOSPACE - The output buffer would not have been large
* enough for all of the converted data; as many
* characters as could fit were converted though.
- *
- * TCL_CONVERT_MULTIBYTE: The last few bytes in the source string were
+ * TCL_CONVERT_MULTIBYTE - The last few bytes in the source string were
* the beginning of a multibyte sequence, but
* more bytes were needed to complete this
- * sequence. A subsequent call to the conversion
+ * sequence. A subsequent call to the conversion
* routine should pass the beginning of this
* unconverted sequence plus additional bytes
- * from the source stream to properly convert
- * the formerly split-up multibyte sequence.
- *
- * TCL_CONVERT_SYNTAX: The source stream contained an invalid
- * character sequence. This may occur if the
+ * from the source stream to properly convert the
+ * formerly split-up multibyte sequence.
+ * TCL_CONVERT_SYNTAX - The source stream contained an invalid
+ * character sequence. This may occur if the
* input stream has been damaged or if the input
- * encoding method was misidentified. This error
+ * encoding method was misidentified. This error
* is reported only if TCL_ENCODING_STOPONERROR
* was specified.
- *
- * TCL_CONVERT_UNKNOWN: The source string contained a character
- * that could not be represented in the target
- * encoding. This error is reported only if
+ * TCL_CONVERT_UNKNOWN - The source string contained a character that
+ * could not be represented in the target
+ * encoding. This error is reported only if
* TCL_ENCODING_STOPONERROR was specified.
*/
-#define TCL_CONVERT_MULTIBYTE -1
-#define TCL_CONVERT_SYNTAX -2
-#define TCL_CONVERT_UNKNOWN -3
-#define TCL_CONVERT_NOSPACE -4
+#define TCL_CONVERT_MULTIBYTE -1
+#define TCL_CONVERT_SYNTAX -2
+#define TCL_CONVERT_UNKNOWN -3
+#define TCL_CONVERT_NOSPACE -4
/*
* 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). (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 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.
*/
#ifndef TCL_UTF_MAX
@@ -2278,15 +2145,15 @@ typedef struct Tcl_Parse {
#endif
/*
- * This represents a Unicode character. Any changes to this should
- * also be reflected in regcustom.h.
+ * This represents a Unicode character. Any changes to this should also be
+ * reflected in regcustom.h.
*/
#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 value must be reflected correctly in regcustom.h and
+ * 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
+ * value must be reflected correctly in regcustom.h and
* in tclEncoding.c.
* XXX: Tcl is currently UCS-2 and planning UTF-16 for the Unicode
* XXX: string rep that Tcl_UniChar represents. Changing the size
@@ -2297,50 +2164,62 @@ typedef unsigned int Tcl_UniChar;
typedef unsigned short Tcl_UniChar;
#endif
+/*
+ * TIP #59: The following structure is used in calls 'Tcl_RegisterConfig' to
+ * provide the system with the embedded configuration data.
+ */
+
+typedef struct Tcl_Config {
+ CONST char *key; /* Configuration key to register. ASCII
+ * encoded, thus UTF-8. */
+ CONST char *value; /* The value associated with the key. System
+ * encoding. */
+} Tcl_Config;
/*
- * Deprecated Tcl procedures:
+ * Flags for TIP#143 limits, detailing which limits are active in an
+ * interpreter. Used for Tcl_{Add,Remove}LimitHandler type argument.
*/
-#ifndef TCL_NO_DEPRECATED
-# define Tcl_EvalObj(interp,objPtr) \
- Tcl_EvalObjEx((interp),(objPtr),0)
-# define Tcl_GlobalEvalObj(interp,objPtr) \
- Tcl_EvalObjEx((interp),(objPtr),TCL_EVAL_GLOBAL)
-#endif
+#define TCL_LIMIT_COMMANDS 0x01
+#define TCL_LIMIT_TIME 0x02
/*
- * These function have been renamed. The old names are deprecated, but we
- * define these macros for backwards compatibilty.
+ * Structure containing information about a limit handler to be called when a
+ * command- or time-limit is exceeded by an interpreter.
*/
-#define Tcl_Ckalloc Tcl_Alloc
-#define Tcl_Ckfree Tcl_Free
-#define Tcl_Ckrealloc Tcl_Realloc
-#define Tcl_Return Tcl_SetResult
-#define Tcl_TildeSubst Tcl_TranslateFileName
-#define panic Tcl_Panic
-#define panicVA Tcl_PanicVA
+
+typedef void (Tcl_LimitHandlerProc) _ANSI_ARGS_((ClientData clientData,
+ Tcl_Interp *interp));
+typedef void (Tcl_LimitHandlerDeleteProc) _ANSI_ARGS_((ClientData clientData));
+
+typedef struct mp_int mp_int;
+#define MP_INT_DECLARED
+typedef unsigned int mp_digit;
+#define MP_DIGIT_DECLARED
/*
- * The following constant is used to test for older versions of Tcl
- * in the stubs tables.
+ * The following constant is used to test for older versions of Tcl in the
+ * stubs tables.
*
* Jan Nijtman's plus patch uses 0xFCA1BACF, so we need to pick a different
* value since the stubs tables don't match.
*/
-#define TCL_STUB_MAGIC ((int)0xFCA3BACF)
+#define TCL_STUB_MAGIC ((int) 0xFCA3BACF)
/*
* The following function is required to be defined in all stubs aware
- * extensions. The function is actually implemented in the stub
- * library, not the main Tcl library, although there is a trivial
- * implementation in the main library in case an extension is statically
- * linked into an application.
+ * extensions. The function is actually implemented in the stub library, not
+ * the main Tcl library, although there is a trivial implementation in the
+ * main library in case an extension is statically linked into an application.
*/
EXTERN CONST char * Tcl_InitStubs _ANSI_ARGS_((Tcl_Interp *interp,
CONST char *version, int exact));
+EXTERN CONST char * TclTomMathInitializeStubs _ANSI_ARGS_((
+ Tcl_Interp *interp, CONST char *version,
+ int epoch, int revision));
#ifndef USE_TCL_STUBS
@@ -2349,49 +2228,211 @@ EXTERN CONST char * Tcl_InitStubs _ANSI_ARGS_((Tcl_Interp *interp,
*/
#define Tcl_InitStubs(interp, version, exact) \
- Tcl_PkgRequire(interp, "Tcl", version, exact)
+ Tcl_PkgInitStubsCheck(interp, version, exact)
#endif
+ /*
+ * TODO - tommath stubs export goes here!
+ */
+
/*
- * Include the public function declarations that are accessible via
- * the stubs table.
+ * Public functions that are not accessible via the stubs table.
+ * Tcl_GetMemoryInfo is needed for AOLserver. [Bug 1868171]
*/
-#include "tclDecls.h"
+EXTERN void Tcl_Main _ANSI_ARGS_((int argc, char **argv,
+ Tcl_AppInitProc *appInitProc));
+EXTERN CONST char * Tcl_PkgInitStubsCheck _ANSI_ARGS_((Tcl_Interp *interp,
+ CONST char *version, int exact));
+#if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)
+EXTERN void Tcl_GetMemoryInfo _ANSI_ARGS_((Tcl_DString *dsPtr));
+#endif
/*
- * Include platform specific public function declarations that are
- * accessible via the stubs table.
+ * Include the public function declarations that are accessible via the stubs
+ * table.
*/
+#include "tclDecls.h"
+
/*
- * tclPlatDecls.h can't be included here on the Mac, as we need
- * Mac specific headers to define the Mac types used in this file,
- * but these Mac haders conflict with a number of tk types
- * and thus can't be included in the globally read tcl.h
- * This header was originally added here as a fix for bug 5241
- * (stub link error for symbols in TclPlatStubs table), as a work-
- * around for the bug on the mac, tclMac.h is included immediately
- * after tcl.h in the tcl precompiled header (with DLLEXPORT set).
+ * Include platform specific public function declarations that are accessible
+ * via the stubs table.
*/
-#if !defined(MAC_TCL)
#include "tclPlatDecls.h"
+
+/*
+ * The following declarations either map ckalloc and ckfree to malloc and
+ * free, or they map them to functions with all sorts of debugging hooks
+ * defined in tclCkalloc.c.
+ */
+
+#ifdef TCL_MEM_DEBUG
+
+# define ckalloc(x) Tcl_DbCkalloc(x, __FILE__, __LINE__)
+# define ckfree(x) Tcl_DbCkfree(x, __FILE__, __LINE__)
+# define ckrealloc(x,y) Tcl_DbCkrealloc((x), (y),__FILE__, __LINE__)
+# define attemptckalloc(x) Tcl_AttemptDbCkalloc(x, __FILE__, __LINE__)
+# define attemptckrealloc(x,y) Tcl_AttemptDbCkrealloc((x), (y), __FILE__, __LINE__)
+
+#else /* !TCL_MEM_DEBUG */
+
+/*
+ * If we are not using the debugging allocator, we should call the Tcl_Alloc,
+ * et al. routines in order to guarantee that every module is using the same
+ * memory allocator both inside and outside of the Tcl library.
+ */
+
+# define ckalloc(x) Tcl_Alloc(x)
+# define ckfree(x) Tcl_Free(x)
+# define ckrealloc(x,y) Tcl_Realloc(x,y)
+# define attemptckalloc(x) Tcl_AttemptAlloc(x)
+# define attemptckrealloc(x,y) Tcl_AttemptRealloc(x,y)
+# undef Tcl_InitMemory
+# define Tcl_InitMemory(x)
+# undef Tcl_DumpActiveMemory
+# define Tcl_DumpActiveMemory(x)
+# undef Tcl_ValidateAllMemory
+# define Tcl_ValidateAllMemory(x,y)
+
+#endif /* !TCL_MEM_DEBUG */
+
+#ifdef TCL_MEM_DEBUG
+# define Tcl_IncrRefCount(objPtr) \
+ Tcl_DbIncrRefCount(objPtr, __FILE__, __LINE__)
+# define Tcl_DecrRefCount(objPtr) \
+ Tcl_DbDecrRefCount(objPtr, __FILE__, __LINE__)
+# define Tcl_IsShared(objPtr) \
+ Tcl_DbIsShared(objPtr, __FILE__, __LINE__)
+#else
+# define Tcl_IncrRefCount(objPtr) \
+ ++(objPtr)->refCount
+ /*
+ * Use do/while0 idiom for optimum correctness without compiler warnings.
+ * http://c2.com/cgi/wiki?TrivialDoWhileLoop
+ */
+# define Tcl_DecrRefCount(objPtr) \
+ do { if (--(objPtr)->refCount <= 0) TclFreeObj(objPtr); } while(0)
+# define Tcl_IsShared(objPtr) \
+ ((objPtr)->refCount > 1)
#endif
/*
- * Public functions that are not accessible via the stubs table.
+ * Macros and definitions that help to debug the use of Tcl objects. When
+ * TCL_MEM_DEBUG is defined, the Tcl_New declarations are overridden to call
+ * debugging versions of the object creation functions.
*/
-EXTERN void Tcl_Main _ANSI_ARGS_((int argc, char **argv,
- Tcl_AppInitProc *appInitProc));
+#ifdef TCL_MEM_DEBUG
+# undef Tcl_NewBignumObj
+# define Tcl_NewBignumObj(val) \
+ Tcl_DbNewBignumObj(val, __FILE__, __LINE__)
+# undef Tcl_NewBooleanObj
+# define Tcl_NewBooleanObj(val) \
+ Tcl_DbNewBooleanObj(val, __FILE__, __LINE__)
+# undef Tcl_NewByteArrayObj
+# define Tcl_NewByteArrayObj(bytes, len) \
+ Tcl_DbNewByteArrayObj(bytes, len, __FILE__, __LINE__)
+# undef Tcl_NewDoubleObj
+# define Tcl_NewDoubleObj(val) \
+ Tcl_DbNewDoubleObj(val, __FILE__, __LINE__)
+# undef Tcl_NewIntObj
+# define Tcl_NewIntObj(val) \
+ Tcl_DbNewLongObj(val, __FILE__, __LINE__)
+# undef Tcl_NewListObj
+# define Tcl_NewListObj(objc, objv) \
+ Tcl_DbNewListObj(objc, objv, __FILE__, __LINE__)
+# undef Tcl_NewLongObj
+# define Tcl_NewLongObj(val) \
+ Tcl_DbNewLongObj(val, __FILE__, __LINE__)
+# undef Tcl_NewObj
+# define Tcl_NewObj() \
+ Tcl_DbNewObj(__FILE__, __LINE__)
+# undef Tcl_NewStringObj
+# define Tcl_NewStringObj(bytes, len) \
+ Tcl_DbNewStringObj(bytes, len, __FILE__, __LINE__)
+# undef Tcl_NewWideIntObj
+# define Tcl_NewWideIntObj(val) \
+ Tcl_DbNewWideIntObj(val, __FILE__, __LINE__)
+#endif /* TCL_MEM_DEBUG */
+
+/*
+ * Macros for clients to use to access fields of hash entries:
+ */
+
+#define Tcl_GetHashValue(h) ((h)->clientData)
+#define Tcl_SetHashValue(h, value) ((h)->clientData = (ClientData) (value))
+#define Tcl_GetHashKey(tablePtr, h) \
+ ((char *) (((tablePtr)->keyType == TCL_ONE_WORD_KEYS || \
+ (tablePtr)->keyType == TCL_CUSTOM_PTR_KEYS) \
+ ? (h)->key.oneWordValue \
+ : (h)->key.string))
+
+/*
+ * Macros to use for clients to use to invoke find and create functions for
+ * hash tables:
+ */
+
+#undef Tcl_FindHashEntry
+#define Tcl_FindHashEntry(tablePtr, key) \
+ (*((tablePtr)->findProc))(tablePtr, key)
+#undef Tcl_CreateHashEntry
+#define Tcl_CreateHashEntry(tablePtr, key, newPtr) \
+ (*((tablePtr)->createProc))(tablePtr, key, newPtr)
+
+/*
+ * Macros that eliminate the overhead of the thread synchronization functions
+ * when compiling without thread support.
+ */
+
+#ifndef TCL_THREADS
+#undef Tcl_MutexLock
+#define Tcl_MutexLock(mutexPtr)
+#undef Tcl_MutexUnlock
+#define Tcl_MutexUnlock(mutexPtr)
+#undef Tcl_MutexFinalize
+#define Tcl_MutexFinalize(mutexPtr)
+#undef Tcl_ConditionNotify
+#define Tcl_ConditionNotify(condPtr)
+#undef Tcl_ConditionWait
+#define Tcl_ConditionWait(condPtr, mutexPtr, timePtr)
+#undef Tcl_ConditionFinalize
+#define Tcl_ConditionFinalize(condPtr)
+#endif /* TCL_THREADS */
+
+#ifndef TCL_NO_DEPRECATED
+ /*
+ * Deprecated Tcl functions:
+ */
+
+# 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.
+ */
+
+# define Tcl_Ckalloc Tcl_Alloc
+# define Tcl_Ckfree Tcl_Free
+# define Tcl_Ckrealloc Tcl_Realloc
+# define Tcl_Return Tcl_SetResult
+# define Tcl_TildeSubst Tcl_TranslateFileName
+# define panic Tcl_Panic
+# define panicVA Tcl_PanicVA
+#endif
/*
- * Convenience declaration of Tcl_AppInit for backwards compatibility.
- * This function is not *implemented* by the tcl library, so the storage
- * class is neither DLLEXPORT nor DLLIMPORT
+ * Convenience declaration of Tcl_AppInit for backwards compatibility. This
+ * function is not *implemented* by the tcl library, so the storage class is
+ * neither DLLEXPORT nor DLLIMPORT.
*/
#undef TCL_STORAGE_CLASS
diff --git a/generic/tclAlloc.c b/generic/tclAlloc.c
index 5022618..7647b4d 100644
--- a/generic/tclAlloc.c
+++ b/generic/tclAlloc.c
@@ -1,10 +1,10 @@
-/*
+/*
* tclAlloc.c --
*
- * This is a very fast storage allocator. It allocates blocks of a
- * small number of different sizes, and keeps free lists of each size.
- * Blocks that don't exactly fit are passed up to the next larger size.
- * Blocks over a certain size are directly allocated from the system.
+ * This is a very fast storage allocator. It allocates blocks of a small
+ * number of different sizes, and keeps free lists of each size. Blocks
+ * that don't exactly fit are passed up to the next larger size. Blocks
+ * over a certain size are directly allocated from the system.
*
* Copyright (c) 1983 Regents of the University of California.
* Copyright (c) 1996-1997 Sun Microsystems, Inc.
@@ -12,8 +12,8 @@
*
* Portions contributed by Chris Kingsley, Jack Jansen and Ray Johnson.
*
- * 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.
*/
/*
@@ -21,10 +21,8 @@
* that has significantly reduced lock contention.
*/
-#if !defined(TCL_THREADS) || !defined(USE_THREAD_ALLOC) || defined(TCL_MEM_DEBUG)
-
#include "tclInt.h"
-#include "tclPort.h"
+#if !defined(TCL_THREADS) || !defined(USE_THREAD_ALLOC)
#if USE_TCLALLOC
@@ -35,58 +33,49 @@
#endif
/*
- * We should really make use of AC_CHECK_TYPE(caddr_t)
- * here, but it can wait until Tcl uses config.h properly.
- */
-#if defined(MAC_TCL) || defined(_MSC_VER) || defined(__MINGW32__) || defined(__BORLANDC__)
-typedef unsigned long caddr_t;
-#endif
-
-/*
- * Alignment for allocated memory.
+ * We should really make use of AC_CHECK_TYPE(caddr_t) here, but it can wait
+ * until Tcl uses config.h properly.
*/
-#if defined(__APPLE__)
-#define ALLOCALIGN 16
-#else
-#define ALLOCALIGN 8
+#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__BORLANDC__)
+typedef unsigned long caddr_t;
#endif
/*
- * The overhead on a block is at least 8 bytes. When free, this space
- * contains a pointer to the next free block, and the bottom two bits must
- * be zero. When in use, the first byte is set to MAGIC, and the second
- * byte is the size index. The remaining bytes are for alignment.
- * If range checking is enabled then a second word holds the size of the
- * requested block, less 1, rounded up to a multiple of sizeof(RMAGIC).
- * The order of elements is critical: ov_magic must overlay the low order
- * bits of ov_next, and ov_magic can not be a valid ov_next bit pattern.
+ * The overhead on a block is at least 8 bytes. When free, this space contains
+ * a pointer to the next free block, and the bottom two bits must be zero.
+ * When in use, the first byte is set to MAGIC, and the second byte is the
+ * size index. The remaining bytes are for alignment. If range checking is
+ * enabled then a second word holds the size of the requested block, less 1,
+ * rounded up to a multiple of sizeof(RMAGIC). The order of elements is
+ * critical: ov.magic must overlay the low order bits of ov.next, and ov.magic
+ * can not be a valid ov.next bit pattern.
*/
union overhead {
- union overhead *ov_next; /* when free */
- unsigned char ov_padding[ALLOCALIGN];/* align struct to ALLOCALIGN bytes */
+ union overhead *next; /* when free */
+ unsigned char padding[TCL_ALLOCALIGN]; /* align struct to TCL_ALLOCALIGN bytes */
struct {
- unsigned char ovu_magic0; /* magic number */
- unsigned char ovu_index; /* bucket # */
- unsigned char ovu_unused; /* unused */
- unsigned char ovu_magic1; /* other magic number */
+ unsigned char magic0; /* magic number */
+ unsigned char index; /* bucket # */
+ unsigned char unused; /* unused */
+ unsigned char magic1; /* other magic number */
#ifdef RCHECK
- unsigned short ovu_rmagic; /* range magic number */
- unsigned long ovu_size; /* actual block size */
- unsigned short ovu_unused2; /* padding to 8-byte align */
+ unsigned short rmagic; /* range magic number */
+ unsigned long size; /* actual block size */
+ unsigned short unused2; /* padding to 8-byte align */
#endif
} ovu;
-#define ov_magic0 ovu.ovu_magic0
-#define ov_magic1 ovu.ovu_magic1
-#define ov_index ovu.ovu_index
-#define ov_rmagic ovu.ovu_rmagic
-#define ov_size ovu.ovu_size
+#define overMagic0 ovu.magic0
+#define overMagic1 ovu.magic1
+#define bucketIndex ovu.index
+#define rangeCheckMagic ovu.rmagic
+#define realBlockSize ovu.size
};
-#define MAGIC 0xef /* magic # on accounting info */
-#define RMAGIC 0x5555 /* magic # on range info */
+#define MAGIC 0xef /* magic # on accounting info */
+#define RMAGIC 0x5555 /* magic # on range info */
#ifdef RCHECK
#define RSLOP sizeof (unsigned short)
@@ -97,38 +86,45 @@ union overhead {
#define OVERHEAD (sizeof(union overhead) + RSLOP)
/*
- * nextf[i] is the pointer to the next free block of size 2^(i+3). The
+ * Macro to make it easier to refer to the end-of-block guard magic.
+ */
+
+#define BLOCK_END(overPtr) \
+ (*(unsigned short *)((caddr_t)((overPtr) + 1) + (overPtr)->realBlockSize))
+
+/*
+ * nextf[i] is the pointer to the next free block of size 2^(i+3). The
* smallest allocatable block is MINBLOCK bytes. The overhead information
* precedes the data area returned to the user.
*/
-#define MINBLOCK ((sizeof(union overhead) + (ALLOCALIGN-1)) & ~(ALLOCALIGN-1))
+#define MINBLOCK ((sizeof(union overhead) + (TCL_ALLOCALIGN-1)) & ~(TCL_ALLOCALIGN-1))
#define NBUCKETS (13 - (MINBLOCK >> 4))
#define MAXMALLOC (1<<(NBUCKETS+2))
-static union overhead *nextf[NBUCKETS];
+static union overhead *nextf[NBUCKETS];
-/*
- * The following structure is used to keep track of all system memory
- * currently owned by Tcl. When finalizing, all this memory will
- * be returned to the system.
+/*
+ * The following structure is used to keep track of all system memory
+ * currently owned by Tcl. When finalizing, all this memory will be returned
+ * to the system.
*/
struct block {
struct block *nextPtr; /* Linked list. */
- struct block *prevPtr; /* Linked list for big blocks, ensures 8-byte
+ struct block *prevPtr; /* Linked list for big blocks, ensures 8-byte
* alignment for suballocated blocks. */
};
-static struct block *blockList; /* Tracks the suballocated blocks. */
-static struct block bigBlocks = { /* Big blocks aren't suballocated. */
+static struct block *blockList; /* Tracks the suballocated blocks. */
+static struct block bigBlocks={ /* Big blocks aren't suballocated. */
&bigBlocks, &bigBlocks
};
/*
- * The allocator is protected by a special mutex that must be
- * explicitly initialized. Futhermore, because Tcl_Alloc may be
- * used before anything else in Tcl, we make this module self-initializing
- * after all with the allocInit variable.
+ * The allocator is protected by a special mutex that must be explicitly
+ * initialized. Futhermore, because Tcl_Alloc may be used before anything else
+ * in Tcl, we make this module self-initializing after all with the allocInit
+ * variable.
*/
#ifdef TCL_THREADS
@@ -136,21 +132,20 @@ static Tcl_Mutex *allocMutexPtr;
#endif
static int allocInit = 0;
-
#ifdef MSTATS
/*
- * nmalloc[i] is the difference between the number of mallocs and frees
- * for a given block size.
+ * numMallocs[i] is the difference between the number of mallocs and frees for
+ * a given block size.
*/
-static unsigned int nmalloc[NBUCKETS+1];
+static unsigned int numMallocs[NBUCKETS+1];
#include <stdio.h>
#endif
#if defined(DEBUG) || defined(RCHECK)
-#define ASSERT(p) if (!(p)) panic(# p)
-#define RANGE_ASSERT(p) if (!(p)) panic(# p)
+#define ASSERT(p) if (!(p)) Tcl_Panic(# p)
+#define RANGE_ASSERT(p) if (!(p)) Tcl_Panic(# p)
#else
#define ASSERT(p)
#define RANGE_ASSERT(p)
@@ -160,8 +155,7 @@ static unsigned int nmalloc[NBUCKETS+1];
* Prototypes for functions used only in this file.
*/
-static void MoreCore _ANSI_ARGS_((int bucket));
-
+static void MoreCore(int bucket);
/*
*-------------------------------------------------------------------------
@@ -180,7 +174,7 @@ static void MoreCore _ANSI_ARGS_((int bucket));
*/
void
-TclInitAlloc()
+TclInitAlloc(void)
{
if (!allocInit) {
allocInit = 1;
@@ -195,27 +189,26 @@ TclInitAlloc()
*
* TclFinalizeAllocSubsystem --
*
- * Release all resources being used by this subsystem, including
- * aggressively freeing all memory allocated by TclpAlloc() that
- * has not yet been released with TclpFree().
- *
- * After this function is called, all memory allocated with
- * TclpAlloc() should be considered unusable.
+ * Release all resources being used by this subsystem, including
+ * aggressively freeing all memory allocated by TclpAlloc() that has not
+ * yet been released with TclpFree().
+ *
+ * After this function is called, all memory allocated with TclpAlloc()
+ * should be considered unusable.
*
* Results:
* None.
*
* Side effects:
- * This subsystem is self-initializing, since memory can be
- * allocated before Tcl is formally initialized. After this call,
- * this subsystem has been reset to its initial state and is
- * usable again.
+ * This subsystem is self-initializing, since memory can be allocated
+ * before Tcl is formally initialized. After this call, this subsystem
+ * has been reset to its initial state and is usable again.
*
*-------------------------------------------------------------------------
*/
void
-TclFinalizeAllocSubsystem()
+TclFinalizeAllocSubsystem(void)
{
unsigned int i;
struct block *blockPtr, *nextPtr;
@@ -235,14 +228,14 @@ TclFinalizeAllocSubsystem()
bigBlocks.nextPtr = &bigBlocks;
bigBlocks.prevPtr = &bigBlocks;
- for (i = 0; i < NBUCKETS; i++) {
+ for (i=0 ; i<NBUCKETS ; i++) {
nextf[i] = NULL;
#ifdef MSTATS
- nmalloc[i] = 0;
+ numMallocs[i] = 0;
#endif
}
#ifdef MSTATS
- nmalloc[i] = 0;
+ numMallocs[i] = 0;
#endif
Tcl_MutexUnlock(allocMutexPtr);
}
@@ -264,30 +257,32 @@ TclFinalizeAllocSubsystem()
*/
char *
-TclpAlloc(nbytes)
- unsigned int nbytes; /* Number of bytes to allocate. */
+TclpAlloc(
+ unsigned int numBytes) /* Number of bytes to allocate. */
{
- register union overhead *op;
+ register union overhead *overPtr;
register long bucket;
- register unsigned amt;
+ register unsigned amount;
struct block *bigBlockPtr = NULL;
if (!allocInit) {
/*
- * We have to make the "self initializing" because Tcl_Alloc
- * may be used before any other part of Tcl. E.g., see
- * main() for tclsh!
+ * We have to make the "self initializing" because Tcl_Alloc may be
+ * used before any other part of Tcl. E.g., see main() for tclsh!
*/
+
TclInitAlloc();
}
Tcl_MutexLock(allocMutexPtr);
+
/*
- * First the simple case: we simple allocate big blocks directly
+ * First the simple case: we simple allocate big blocks directly.
*/
- if (nbytes >= MAXMALLOC - OVERHEAD) {
- if (nbytes <= UINT_MAX - OVERHEAD - sizeof(struct block)) {
- bigBlockPtr = (struct block *) TclpSysAlloc((unsigned)
- (sizeof(struct block) + OVERHEAD + nbytes), 0);
+
+ if (numBytes >= MAXMALLOC - OVERHEAD) {
+ if (numBytes <= UINT_MAX - OVERHEAD -sizeof(struct block)) {
+ bigBlockPtr = (struct block *) TclpSysAlloc((unsigned)
+ (sizeof(struct block) + OVERHEAD + numBytes), 0);
}
if (bigBlockPtr == NULL) {
Tcl_MutexUnlock(allocMutexPtr);
@@ -298,74 +293,83 @@ TclpAlloc(nbytes)
bigBlockPtr->prevPtr = &bigBlocks;
bigBlockPtr->nextPtr->prevPtr = bigBlockPtr;
- op = (union overhead *) (bigBlockPtr + 1);
- op->ov_magic0 = op->ov_magic1 = MAGIC;
- op->ov_index = 0xff;
+ overPtr = (union overhead *) (bigBlockPtr + 1);
+ overPtr->overMagic0 = overPtr->overMagic1 = MAGIC;
+ overPtr->bucketIndex = 0xff;
#ifdef MSTATS
- nmalloc[NBUCKETS]++;
+ numMallocs[NBUCKETS]++;
#endif
+
#ifdef RCHECK
/*
- * Record allocated size of block and
- * bound space with magic numbers.
+ * Record allocated size of block and bound space with magic numbers.
*/
- op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
- op->ov_rmagic = RMAGIC;
- *(unsigned short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
+
+ overPtr->realBlockSize = (numBytes + RSLOP - 1) & ~(RSLOP - 1);
+ overPtr->rangeCheckMagic = RMAGIC;
+ BLOCK_END(overPtr) = RMAGIC;
#endif
+
Tcl_MutexUnlock(allocMutexPtr);
- return (void *)(op+1);
+ return (void *)(overPtr+1);
}
+
/*
- * Convert amount of memory requested into closest block size
- * stored in hash buckets which satisfies request.
- * Account for space used per block for accounting.
+ * Convert amount of memory requested into closest block size stored in
+ * hash buckets which satisfies request. Account for space used per block
+ * for accounting.
*/
- amt = MINBLOCK; /* size of first bucket */
+ amount = MINBLOCK; /* size of first bucket */
bucket = MINBLOCK >> 4;
- while (nbytes + OVERHEAD > amt) {
- amt <<= 1;
- if (amt == 0) {
+ while (numBytes + OVERHEAD > amount) {
+ amount <<= 1;
+ if (amount == 0) {
Tcl_MutexUnlock(allocMutexPtr);
- return (NULL);
+ return NULL;
}
bucket++;
}
- ASSERT( bucket < NBUCKETS );
+ ASSERT(bucket < NBUCKETS);
/*
- * If nothing in hash bucket right now,
- * request more memory from the system.
+ * If nothing in hash bucket right now, request more memory from the
+ * system.
*/
- if ((op = nextf[bucket]) == NULL) {
+
+ if ((overPtr = nextf[bucket]) == NULL) {
MoreCore(bucket);
- if ((op = nextf[bucket]) == NULL) {
+ if ((overPtr = nextf[bucket]) == NULL) {
Tcl_MutexUnlock(allocMutexPtr);
- return (NULL);
+ return NULL;
}
}
+
/*
* Remove from linked list
*/
- nextf[bucket] = op->ov_next;
- op->ov_magic0 = op->ov_magic1 = MAGIC;
- op->ov_index = (unsigned char) bucket;
+
+ nextf[bucket] = overPtr->next;
+ overPtr->overMagic0 = overPtr->overMagic1 = MAGIC;
+ overPtr->bucketIndex = (unsigned char) bucket;
+
#ifdef MSTATS
- nmalloc[bucket]++;
+ numMallocs[bucket]++;
#endif
+
#ifdef RCHECK
/*
- * Record allocated size of block and
- * bound space with magic numbers.
+ * Record allocated size of block and bound space with magic numbers.
*/
- op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
- op->ov_rmagic = RMAGIC;
- *(unsigned short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
+
+ overPtr->realBlockSize = (numBytes + RSLOP - 1) & ~(RSLOP - 1);
+ overPtr->rangeCheckMagic = RMAGIC;
+ BLOCK_END(overPtr) = RMAGIC;
#endif
+
Tcl_MutexUnlock(allocMutexPtr);
- return ((char *)(op + 1));
+ return ((char *)(overPtr + 1));
}
/*
@@ -387,28 +391,29 @@ TclpAlloc(nbytes)
*/
static void
-MoreCore(bucket)
- int bucket; /* What bucket to allocat to. */
+MoreCore(
+ int bucket) /* What bucket to allocat to. */
{
- register union overhead *op;
- register long sz; /* size of desired block */
- long amt; /* amount to allocate */
- int nblks; /* how many blocks we get */
+ register union overhead *overPtr;
+ register long size; /* size of desired block */
+ long amount; /* amount to allocate */
+ int numBlocks; /* how many blocks we get */
struct block *blockPtr;
/*
- * sbrk_size <= 0 only for big, FLUFFY, requests (about
- * 2^30 bytes on a VAX, I think) or for a negative arg.
+ * sbrk_size <= 0 only for big, FLUFFY, requests (about 2^30 bytes on a
+ * VAX, I think) or for a negative arg.
*/
- sz = 1 << (bucket + 3);
- ASSERT(sz > 0);
- amt = MAXMALLOC;
- nblks = amt / sz;
- ASSERT(nblks*sz == amt);
+ size = 1 << (bucket + 3);
+ ASSERT(size > 0);
- blockPtr = (struct block *) TclpSysAlloc((unsigned)
- (sizeof(struct block) + amt), 1);
+ amount = MAXMALLOC;
+ numBlocks = amount / size;
+ ASSERT(numBlocks*size == amount);
+
+ blockPtr = (struct block *) TclpSysAlloc((unsigned)
+ (sizeof(struct block) + amount), 1);
/* no more room! */
if (blockPtr == NULL) {
return;
@@ -416,18 +421,18 @@ MoreCore(bucket)
blockPtr->nextPtr = blockList;
blockList = blockPtr;
- op = (union overhead *) (blockPtr + 1);
-
+ overPtr = (union overhead *) (blockPtr + 1);
+
/*
- * Add new memory allocated to that on
- * free list for this hash bucket.
+ * Add new memory allocated to that on free list for this hash bucket.
*/
- nextf[bucket] = op;
- while (--nblks > 0) {
- op->ov_next = (union overhead *)((caddr_t)op + sz);
- op = (union overhead *)((caddr_t)op + sz);
+
+ nextf[bucket] = overPtr;
+ while (--numBlocks > 0) {
+ overPtr->next = (union overhead *)((caddr_t)overPtr + size);
+ overPtr = (union overhead *)((caddr_t)overPtr + size);
}
- op->ov_next = (union overhead *)NULL;
+ overPtr->next = NULL;
}
/*
@@ -447,47 +452,51 @@ MoreCore(bucket)
*/
void
-TclpFree(cp)
- char *cp; /* Pointer to memory to free. */
-{
+TclpFree(
+ char *oldPtr) /* Pointer to memory to free. */
+{
register long size;
- register union overhead *op;
+ register union overhead *overPtr;
struct block *bigBlockPtr;
- if (cp == NULL) {
+ if (oldPtr == NULL) {
return;
}
Tcl_MutexLock(allocMutexPtr);
- op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
+ overPtr = (union overhead *)((caddr_t)oldPtr - sizeof (union overhead));
- ASSERT(op->ov_magic0 == MAGIC); /* make sure it was in use */
- ASSERT(op->ov_magic1 == MAGIC);
- if (op->ov_magic0 != MAGIC || op->ov_magic1 != MAGIC) {
+ ASSERT(overPtr->overMagic0 == MAGIC); /* make sure it was in use */
+ ASSERT(overPtr->overMagic1 == MAGIC);
+ if (overPtr->overMagic0 != MAGIC || overPtr->overMagic1 != MAGIC) {
Tcl_MutexUnlock(allocMutexPtr);
return;
}
- RANGE_ASSERT(op->ov_rmagic == RMAGIC);
- RANGE_ASSERT(*(unsigned short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC);
- size = op->ov_index;
- if ( size == 0xff ) {
+ RANGE_ASSERT(overPtr->rangeCheckMagic == RMAGIC);
+ RANGE_ASSERT(BLOCK_END(overPtr) == RMAGIC);
+ size = overPtr->bucketIndex;
+ if (size == 0xff) {
#ifdef MSTATS
- nmalloc[NBUCKETS]--;
+ numMallocs[NBUCKETS]--;
#endif
- bigBlockPtr = (struct block *) op - 1;
+
+ bigBlockPtr = (struct block *) overPtr - 1;
bigBlockPtr->prevPtr->nextPtr = bigBlockPtr->nextPtr;
bigBlockPtr->nextPtr->prevPtr = bigBlockPtr->prevPtr;
TclpSysFree(bigBlockPtr);
+
Tcl_MutexUnlock(allocMutexPtr);
return;
}
ASSERT(size < NBUCKETS);
- op->ov_next = nextf[size]; /* also clobbers ov_magic */
- nextf[size] = op;
+ overPtr->next = nextf[size]; /* also clobbers overMagic */
+ nextf[size] = overPtr;
+
#ifdef MSTATS
- nmalloc[size]--;
+ numMallocs[size]--;
#endif
+
Tcl_MutexUnlock(allocMutexPtr);
}
@@ -508,34 +517,34 @@ TclpFree(cp)
*/
char *
-TclpRealloc(cp, nbytes)
- char *cp; /* Pointer to alloced block. */
- unsigned int nbytes; /* New size of memory. */
-{
+TclpRealloc(
+ char *oldPtr, /* Pointer to alloced block. */
+ unsigned int numBytes) /* New size of memory. */
+{
int i;
- union overhead *op;
+ union overhead *overPtr;
struct block *bigBlockPtr;
int expensive;
- unsigned long maxsize;
+ unsigned long maxSize;
- if (cp == NULL) {
- return (TclpAlloc(nbytes));
+ if (oldPtr == NULL) {
+ return TclpAlloc(numBytes);
}
Tcl_MutexLock(allocMutexPtr);
- op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
+ overPtr = (union overhead *)((caddr_t)oldPtr - sizeof (union overhead));
- ASSERT(op->ov_magic0 == MAGIC); /* make sure it was in use */
- ASSERT(op->ov_magic1 == MAGIC);
- if (op->ov_magic0 != MAGIC || op->ov_magic1 != MAGIC) {
+ ASSERT(overPtr->overMagic0 == MAGIC); /* make sure it was in use */
+ ASSERT(overPtr->overMagic1 == MAGIC);
+ if (overPtr->overMagic0 != MAGIC || overPtr->overMagic1 != MAGIC) {
Tcl_MutexUnlock(allocMutexPtr);
return NULL;
}
- RANGE_ASSERT(op->ov_rmagic == RMAGIC);
- RANGE_ASSERT(*(unsigned short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC);
- i = op->ov_index;
+ RANGE_ASSERT(overPtr->rangeCheckMagic == RMAGIC);
+ RANGE_ASSERT(BLOCK_END(overPtr) == RMAGIC);
+ i = overPtr->bucketIndex;
/*
* If the block isn't in a bin, just realloc it.
@@ -543,11 +552,11 @@ TclpRealloc(cp, nbytes)
if (i == 0xff) {
struct block *prevPtr, *nextPtr;
- bigBlockPtr = (struct block *) op - 1;
+ bigBlockPtr = (struct block *) overPtr - 1;
prevPtr = bigBlockPtr->prevPtr;
nextPtr = bigBlockPtr->nextPtr;
- bigBlockPtr = (struct block *) TclpSysRealloc(bigBlockPtr,
- sizeof(struct block) + OVERHEAD + nbytes);
+ bigBlockPtr = (struct block *) TclpSysRealloc(bigBlockPtr,
+ sizeof(struct block) + OVERHEAD + numBytes);
if (bigBlockPtr == NULL) {
Tcl_MutexUnlock(allocMutexPtr);
return NULL;
@@ -555,63 +564,69 @@ TclpRealloc(cp, nbytes)
if (prevPtr->nextPtr != bigBlockPtr) {
/*
- * If the block has moved, splice the new block into the list where
- * the old block used to be.
+ * If the block has moved, splice the new block into the list
+ * where the old block used to be.
*/
prevPtr->nextPtr = bigBlockPtr;
nextPtr->prevPtr = bigBlockPtr;
}
- op = (union overhead *) (bigBlockPtr + 1);
+ overPtr = (union overhead *) (bigBlockPtr + 1);
+
#ifdef MSTATS
- nmalloc[NBUCKETS]++;
+ numMallocs[NBUCKETS]++;
#endif
+
#ifdef RCHECK
/*
* Record allocated size of block and update magic number bounds.
*/
- op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
- *(unsigned short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
+ overPtr->realBlockSize = (numBytes + RSLOP - 1) & ~(RSLOP - 1);
+ BLOCK_END(overPtr) = RMAGIC;
#endif
+
Tcl_MutexUnlock(allocMutexPtr);
- return (char *)(op+1);
+ return (char *)(overPtr+1);
}
- maxsize = 1 << (i+3);
+ maxSize = 1 << (i+3);
expensive = 0;
- if ( nbytes + OVERHEAD > maxsize ) {
+ if (numBytes+OVERHEAD > maxSize) {
expensive = 1;
- } else if ( i > 0 && nbytes + OVERHEAD < (maxsize/2) ) {
+ } else if (i>0 && numBytes+OVERHEAD < maxSize/2) {
expensive = 1;
}
if (expensive) {
- void *newp;
+ void *newPtr;
Tcl_MutexUnlock(allocMutexPtr);
- newp = TclpAlloc(nbytes);
- if ( newp == NULL ) {
+ newPtr = TclpAlloc(numBytes);
+ if (newPtr == NULL) {
return NULL;
}
- maxsize -= OVERHEAD;
- if ( maxsize < nbytes )
- nbytes = maxsize;
- memcpy((VOID *) newp, (VOID *) cp, (size_t) nbytes);
- TclpFree(cp);
- return newp;
+ maxSize -= OVERHEAD;
+ if (maxSize < numBytes) {
+ numBytes = maxSize;
+ }
+ memcpy(newPtr, oldPtr, (size_t) numBytes);
+ TclpFree(oldPtr);
+ return newPtr;
}
-
+
/*
* Ok, we don't have to copy, it fits as-is
*/
+
#ifdef RCHECK
- op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
- *(unsigned short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
+ overPtr->realBlockSize = (numBytes + RSLOP - 1) & ~(RSLOP - 1);
+ BLOCK_END(overPtr) = RMAGIC;
#endif
+
Tcl_MutexUnlock(allocMutexPtr);
- return(cp);
+ return(oldPtr);
}
/*
@@ -619,9 +634,9 @@ TclpRealloc(cp, nbytes)
*
* mstats --
*
- * Prints two lines of numbers, one showing the length of the
- * free list for each size category, the second showing the
- * number of mallocs - frees for each size category.
+ * Prints two lines of numbers, one showing the length of the free list
+ * for each size category, the second showing the number of mallocs -
+ * frees for each size category.
*
* Results:
* None.
@@ -634,35 +649,39 @@ TclpRealloc(cp, nbytes)
#ifdef MSTATS
void
-mstats(s)
- char *s; /* Where to write info. */
+mstats(
+ char *s) /* Where to write info. */
{
register int i, j;
- register union overhead *p;
- int totfree = 0,
- totused = 0;
+ register union overhead *overPtr;
+ int totalFree = 0, totalUsed = 0;
Tcl_MutexLock(allocMutexPtr);
+
fprintf(stderr, "Memory allocation statistics %s\nTclpFree:\t", s);
for (i = 0; i < NBUCKETS; i++) {
- for (j = 0, p = nextf[i]; p; p = p->ov_next, j++)
+ for (j=0, overPtr=nextf[i]; overPtr; overPtr=overPtr->next, j++) {
fprintf(stderr, " %d", j);
- totfree += j * (1 << (i + 3));
+ }
+ totalFree += j * (1 << (i + 3));
}
+
fprintf(stderr, "\nused:\t");
for (i = 0; i < NBUCKETS; i++) {
- fprintf(stderr, " %d", nmalloc[i]);
- totused += nmalloc[i] * (1 << (i + 3));
+ fprintf(stderr, " %d", numMallocs[i]);
+ totalUsed += numMallocs[i] * (1 << (i + 3));
}
+
fprintf(stderr, "\n\tTotal small in use: %d, total free: %d\n",
- totused, totfree);
- fprintf(stderr, "\n\tNumber of big (>%d) blocks in use: %d\n",
- MAXMALLOC, nmalloc[NBUCKETS]);
+ totalUsed, totalFree);
+ fprintf(stderr, "\n\tNumber of big (>%d) blocks in use: %d\n",
+ MAXMALLOC, numMallocs[NBUCKETS]);
+
Tcl_MutexUnlock(allocMutexPtr);
}
#endif
-#else /* !USE_TCLALLOC */
+#else /* !USE_TCLALLOC */
/*
*----------------------------------------------------------------------
@@ -681,10 +700,10 @@ mstats(s)
*/
char *
-TclpAlloc(nbytes)
- unsigned int nbytes; /* Number of bytes to allocate. */
+TclpAlloc(
+ unsigned int numBytes) /* Number of bytes to allocate. */
{
- return (char*) malloc(nbytes);
+ return (char*) malloc(numBytes);
}
/*
@@ -704,10 +723,10 @@ TclpAlloc(nbytes)
*/
void
-TclpFree(cp)
- char *cp; /* Pointer to memory to free. */
-{
- free(cp);
+TclpFree(
+ char *oldPtr) /* Pointer to memory to free. */
+{
+ free(oldPtr);
return;
}
@@ -728,12 +747,20 @@ TclpFree(cp)
*/
char *
-TclpRealloc(cp, nbytes)
- char *cp; /* Pointer to alloced block. */
- unsigned int nbytes; /* New size of memory. */
-{
- return (char*) realloc(cp, nbytes);
+TclpRealloc(
+ char *oldPtr, /* Pointer to alloced block. */
+ unsigned int numBytes) /* New size of memory. */
+{
+ return (char*) realloc(oldPtr, numBytes);
}
#endif /* !USE_TCLALLOC */
#endif /* !TCL_THREADS */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclAsync.c b/generic/tclAsync.c
index 98087c5..ca18f5e 100644
--- a/generic/tclAsync.c
+++ b/generic/tclAsync.c
@@ -1,91 +1,78 @@
-/*
+/*
* tclAsync.c --
*
- * This file provides low-level support needed to invoke signal
- * handlers in a safe way. The code here doesn't actually handle
- * signals, though. This code is based on proposals made by
- * Mark Diekhans and Don Libes.
+ * This file provides low-level support needed to invoke signal handlers
+ * in a safe way. The code here doesn't actually handle signals, though.
+ * This code is based on proposals made by Mark Diekhans and Don Libes.
*
* Copyright (c) 1993 The Regents of the University of California.
* Copyright (c) 1994 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * 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 "tclPort.h"
/* Forward declaration */
struct ThreadSpecificData;
/*
- * One of the following structures exists for each asynchronous
- * handler:
+ * One of the following structures exists for each asynchronous handler:
*/
typedef struct AsyncHandler {
- int ready; /* Non-zero means this handler should
- * be invoked in the next call to
- * Tcl_AsyncInvoke. */
- struct AsyncHandler *nextPtr; /* Next in list of all handlers for
- * the process. */
- Tcl_AsyncProc *proc; /* Procedure to call when handler
- * is invoked. */
- ClientData clientData; /* Value to pass to handler when it
- * is invoked. */
+ int ready; /* Non-zero means this handler should be
+ * invoked in the next call to
+ * Tcl_AsyncInvoke. */
+ struct AsyncHandler *nextPtr;
+ /* Next in list of all handlers for the
+ * process. */
+ Tcl_AsyncProc *proc; /* Procedure to call when handler is
+ * invoked. */
+ ClientData clientData; /* Value to pass to handler when it is
+ * invoked. */
struct ThreadSpecificData *originTsd;
- /* Used in Tcl_AsyncMark to modify thread-
- * specific data from outside the thread
- * it is associated to. */
- Tcl_ThreadId originThrdId; /* Origin thread where this token was
- * created and where it will be
- * yielded. */
+ /* Used in Tcl_AsyncMark to modify thread-
+ * specific data from outside the thread it is
+ * associated to. */
+ Tcl_ThreadId originThrdId; /* Origin thread where this token was created
+ * and where it will be yielded. */
} AsyncHandler;
-
typedef struct ThreadSpecificData {
/*
- * The variables below maintain a list of all existing handlers
- * specific to the calling thread.
- */
- AsyncHandler *firstHandler; /* First handler defined for process,
- * or NULL if none. */
- AsyncHandler *lastHandler; /* Last handler or NULL. */
-
- /*
- * The variable below is set to 1 whenever a handler becomes ready and
- * it is cleared to zero whenever Tcl_AsyncInvoke is called. It can be
- * checked elsewhere in the application by calling Tcl_AsyncReady to see
- * if Tcl_AsyncInvoke should be invoked.
+ * The variables below maintain a list of all existing handlers specific
+ * to the calling thread.
*/
-
- int asyncReady;
-
- /*
- * The variable below indicates whether Tcl_AsyncInvoke is currently
- * working. If so then we won't set asyncReady again until
- * Tcl_AsyncInvoke returns.
- */
-
- int asyncActive;
-
- Tcl_Mutex asyncMutex; /* Thread-specific AsyncHandler linked-list lock */
-
+ AsyncHandler *firstHandler; /* First handler defined for process, or NULL
+ * if none. */
+ AsyncHandler *lastHandler; /* Last handler or NULL. */
+ int asyncReady; /* This is set to 1 whenever a handler becomes
+ * ready and it is cleared to zero whenever
+ * Tcl_AsyncInvoke is called. It can be
+ * checked elsewhere in the application by
+ * calling Tcl_AsyncReady to see if
+ * Tcl_AsyncInvoke should be invoked. */
+ int asyncActive; /* Indicates whether Tcl_AsyncInvoke is
+ * currently working. If so then we won't set
+ * asyncReady again until Tcl_AsyncInvoke
+ * returns. */
+ Tcl_Mutex asyncMutex; /* Thread-specific AsyncHandler linked-list
+ * lock */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
-
/*
*----------------------------------------------------------------------
*
* TclFinalizeAsync --
*
- * Finalizes the mutex in the thread local data structure for the
- * async subsystem.
+ * Finalizes the mutex in the thread local data structure for the async
+ * subsystem.
*
* Results:
- * None.
+ * None.
*
* Side effects:
* Forgets knowledge of the mutex should it have been created.
@@ -94,7 +81,7 @@ static Tcl_ThreadDataKey dataKey;
*/
void
-TclFinalizeAsync()
+TclFinalizeAsync(void)
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
@@ -109,12 +96,12 @@ TclFinalizeAsync()
* Tcl_AsyncCreate --
*
* This procedure creates the data structures for an asynchronous
- * handler, so that no memory has to be allocated when the handler
- * is activated.
+ * handler, so that no memory has to be allocated when the handler is
+ * activated.
*
* Results:
- * The return value is a token for the handler, which can be used
- * to activate it later on.
+ * The return value is a token for the handler, which can be used to
+ * activate it later on.
*
* Side effects:
* Information about the handler is recorded.
@@ -123,10 +110,10 @@ TclFinalizeAsync()
*/
Tcl_AsyncHandler
-Tcl_AsyncCreate(proc, clientData)
- Tcl_AsyncProc *proc; /* Procedure to call when handler
- * is invoked. */
- ClientData clientData; /* Argument to pass to handler. */
+Tcl_AsyncCreate(
+ Tcl_AsyncProc *proc, /* Procedure to call when handler is
+ * invoked. */
+ ClientData clientData) /* Argument to pass to handler. */
{
AsyncHandler *asyncPtr;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
@@ -155,10 +142,10 @@ Tcl_AsyncCreate(proc, clientData)
*
* Tcl_AsyncMark --
*
- * This procedure is called to request that an asynchronous handler
- * be invoked as soon as possible. It's typically called from
- * an interrupt handler, where it isn't safe to do anything that
- * depends on or modifies application state.
+ * This procedure is called to request that an asynchronous handler be
+ * invoked as soon as possible. It's typically called from an interrupt
+ * handler, where it isn't safe to do anything that depends on or
+ * modifies application state.
*
* Results:
* None.
@@ -170,8 +157,8 @@ Tcl_AsyncCreate(proc, clientData)
*/
void
-Tcl_AsyncMark(async)
- Tcl_AsyncHandler async; /* Token for handler. */
+Tcl_AsyncMark(
+ Tcl_AsyncHandler async) /* Token for handler. */
{
AsyncHandler *token = (AsyncHandler *) async;
@@ -189,13 +176,12 @@ Tcl_AsyncMark(async)
*
* Tcl_AsyncInvoke --
*
- * This procedure is called at a "safe" time at background level
- * to invoke any active asynchronous handlers.
+ * This procedure is called at a "safe" time at background level to
+ * invoke any active asynchronous handlers.
*
* Results:
- * The return value is a normal Tcl result, which is intended to
- * replace the code argument as the current completion code for
- * interp.
+ * The return value is a normal Tcl result, which is intended to replace
+ * the code argument as the current completion code for interp.
*
* Side effects:
* Depends on the handlers that are active.
@@ -204,14 +190,13 @@ Tcl_AsyncMark(async)
*/
int
-Tcl_AsyncInvoke(interp, code)
- Tcl_Interp *interp; /* If invoked from Tcl_Eval just after
- * completing a command, points to
- * interpreter. Otherwise it is
- * NULL. */
- int code; /* If interp is non-NULL, this gives
- * completion code from command that
- * just completed. */
+Tcl_AsyncInvoke(
+ Tcl_Interp *interp, /* If invoked from Tcl_Eval just after
+ * completing a command, points to
+ * interpreter. Otherwise it is NULL. */
+ int code) /* If interp is non-NULL, this gives
+ * completion code from command that just
+ * completed. */
{
AsyncHandler *asyncPtr;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
@@ -229,13 +214,12 @@ Tcl_AsyncInvoke(interp, code)
}
/*
- * Make one or more passes over the list of handlers, invoking
- * at most one handler in each pass. After invoking a handler,
- * go back to the start of the list again so that (a) if a new
- * higher-priority handler gets marked while executing a lower
- * priority handler, we execute the higher-priority handler
- * next, and (b) if a handler gets deleted during the execution
- * of a handler, then the list structure may change so it isn't
+ * Make one or more passes over the list of handlers, invoking at most one
+ * handler in each pass. After invoking a handler, go back to the start of
+ * the list again so that (a) if a new higher-priority handler gets marked
+ * while executing a lower priority handler, we execute the higher-
+ * priority handler next, and (b) if a handler gets deleted during the
+ * execution of a handler, then the list structure may change so it isn't
* safe to continue down the list anyway.
*/
@@ -264,8 +248,8 @@ Tcl_AsyncInvoke(interp, code)
*
* Tcl_AsyncDelete --
*
- * Frees up all the state for an asynchronous handler. The handler
- * should never be used again.
+ * Frees up all the state for an asynchronous handler. The handler should
+ * never be used again.
*
* Results:
* None.
@@ -284,8 +268,8 @@ Tcl_AsyncInvoke(interp, code)
*/
void
-Tcl_AsyncDelete(async)
- Tcl_AsyncHandler async; /* Token for handler to delete. */
+Tcl_AsyncDelete(
+ Tcl_AsyncHandler async) /* Token for handler to delete. */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
AsyncHandler *asyncPtr = (AsyncHandler *) async;
@@ -296,7 +280,7 @@ Tcl_AsyncDelete(async)
*/
if (asyncPtr->originThrdId != Tcl_GetCurrentThread()) {
- panic("Tcl_AsyncDelete: async handler deleted by the wrong thread");
+ Tcl_Panic("Tcl_AsyncDelete: async handler deleted by the wrong thread");
}
/*
@@ -314,7 +298,7 @@ Tcl_AsyncDelete(async)
thisPtr = thisPtr->nextPtr;
}
if (thisPtr == NULL) {
- panic("Tcl_AsyncDelete: cannot find async handler");
+ Tcl_Panic("Tcl_AsyncDelete: cannot find async handler");
}
if (asyncPtr == tsdPtr->firstHandler) {
tsdPtr->firstHandler = asyncPtr->nextPtr;
@@ -334,13 +318,13 @@ Tcl_AsyncDelete(async)
*
* Tcl_AsyncReady --
*
- * This procedure can be used to tell whether Tcl_AsyncInvoke
- * needs to be called. This procedure is the external interface
- * for checking the thread-specific asyncReady variable.
+ * This procedure can be used to tell whether Tcl_AsyncInvoke needs to be
+ * called. This procedure is the external interface for checking the
+ * thread-specific asyncReady variable.
*
* Results:
- * The return value is 1 whenever a handler is ready and is 0
- * when no handlers are ready.
+ * The return value is 1 whenever a handler is ready and is 0 when no
+ * handlers are ready.
*
* Side effects:
* None.
@@ -349,8 +333,23 @@ Tcl_AsyncDelete(async)
*/
int
-Tcl_AsyncReady()
+Tcl_AsyncReady(void)
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
return tsdPtr->asyncReady;
}
+
+int *
+TclGetAsyncReadyPtr(void)
+{
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ return &(tsdPtr->asyncReady);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index c5c914e..954b2b3 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -1,9 +1,9 @@
-/*
+/*
* tclBasic.c --
*
* Contains the basic facilities for TCL command interpretation,
- * including interpreter creation and deletion, command creation
- * and deletion, and command/script execution.
+ * including interpreter creation and deletion, command creation and
+ * deletion, and command/script execution.
*
* Copyright (c) 1987-1994 The Regents of the University of California.
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
@@ -11,270 +11,353 @@
* Copyright (c) 2001, 2002 by Kevin B. Kenny. All rights reserved.
* Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
*
- * 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.
*/
#include "tclInt.h"
#include "tclCompile.h"
-#ifndef TCL_GENERIC_ONLY
-# include "tclPort.h"
-#endif
+#include <float.h>
+#include <limits.h>
+#include <math.h>
+#include "tommath.h"
/*
- * Static procedures in this file:
+ * Determine whether we're using IEEE floating point
*/
-static char * CallCommandTraces _ANSI_ARGS_((Interp *iPtr,
- Command *cmdPtr, CONST char *oldName,
- CONST char* newName, int flags));
-static void DeleteInterpProc _ANSI_ARGS_((Tcl_Interp *interp));
-static void ProcessUnexpectedResult _ANSI_ARGS_((
- Tcl_Interp *interp, int returnCode));
-static int StringTraceProc _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp* interp,
- int level,
- CONST char* command,
- Tcl_Command commandInfo,
- int objc,
- Tcl_Obj *CONST objv[]));
-static void StringTraceDeleteProc _ANSI_ARGS_((ClientData clientData));
-
-#ifdef TCL_TIP280
-/* TIP #280 - Modified token based evaluation, with line information */
-static int EvalEx _ANSI_ARGS_((Tcl_Interp *interp, CONST char *script,
- int numBytes, int flags, int line,
- int* clNextOuter, CONST char* outerScript));
-
-static int EvalTokensStandard _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_Token *tokenPtr,
- int count, int line,
- int* clNextOuter, CONST char* outerScript));
+#if (FLT_RADIX == 2) && (DBL_MANT_DIG == 53) && (DBL_MAX_EXP == 1024)
+# define IEEE_FLOATING_POINT
+/* Largest odd integer that can be represented exactly in a double */
+# define MAX_EXACT 9007199254740991.0
#endif
+/*
+ * The following structure defines the client data for a math function
+ * registered with Tcl_CreateMathFunc
+ */
+
+typedef struct OldMathFuncData {
+ Tcl_MathProc *proc; /* Handler function */
+ int numArgs; /* Number of args expected */
+ Tcl_ValueType *argTypes; /* Types of the args */
+ ClientData clientData; /* Client data for the handler function */
+} OldMathFuncData;
+
+/*
+ * Static functions in this file:
+ */
+
+static char * CallCommandTraces(Interp *iPtr, Command *cmdPtr,
+ const char *oldName, const char *newName, int flags);
+static int CheckDoubleResult(Tcl_Interp *interp, double dResult);
+static void DeleteInterpProc(Tcl_Interp *interp);
+static void DeleteOpCmdClientData(ClientData clientData);
+static Tcl_Obj *GetCommandSource(Interp *iPtr, const char *command,
+ int numChars, int objc, Tcl_Obj *const objv[]);
+static void ProcessUnexpectedResult(Tcl_Interp *interp, int returnCode);
+static int OldMathFuncProc(ClientData clientData, Tcl_Interp *interp,
+ int argc, Tcl_Obj *const *objv);
+static void OldMathFuncDeleteProc(ClientData clientData);
+static int ExprAbsFunc(ClientData clientData, Tcl_Interp *interp,
+ int argc, Tcl_Obj *const *objv);
+static int ExprBinaryFunc(ClientData clientData, Tcl_Interp *interp,
+ int argc, Tcl_Obj *const *objv);
+static int ExprBoolFunc(ClientData clientData, Tcl_Interp *interp,
+ int argc, Tcl_Obj *const *objv);
+static int ExprCeilFunc(ClientData clientData, Tcl_Interp *interp,
+ int argc, Tcl_Obj *const *objv);
+static int ExprDoubleFunc(ClientData clientData, Tcl_Interp *interp,
+ int argc, Tcl_Obj *const *objv);
+static int ExprEntierFunc(ClientData clientData, Tcl_Interp *interp,
+ int argc, Tcl_Obj *const *objv);
+static int ExprFloorFunc(ClientData clientData, Tcl_Interp *interp,
+ int argc, Tcl_Obj *const *objv);
+static int ExprIntFunc(ClientData clientData, Tcl_Interp *interp,
+ int argc, Tcl_Obj *const *objv);
+static int ExprIsqrtFunc(ClientData clientData, Tcl_Interp *interp,
+ int argc, Tcl_Obj *const *objv);
+static int ExprRandFunc(ClientData clientData, Tcl_Interp *interp,
+ int argc, Tcl_Obj *const *objv);
+static int ExprRoundFunc(ClientData clientData, Tcl_Interp *interp,
+ int argc, Tcl_Obj *const *objv);
+static int ExprSqrtFunc(ClientData clientData, Tcl_Interp *interp,
+ int argc, Tcl_Obj *const *objv);
+static int ExprSrandFunc(ClientData clientData, Tcl_Interp *interp,
+ int argc, Tcl_Obj *const *objv);
+static int ExprUnaryFunc(ClientData clientData, Tcl_Interp *interp,
+ int argc, Tcl_Obj *const *objv);
+static int ExprWideFunc(ClientData clientData, Tcl_Interp *interp,
+ int argc, Tcl_Obj *const *objv);
+static void MathFuncWrongNumArgs(Tcl_Interp *interp, int expected,
+ int actual, Tcl_Obj *const *objv);
#ifdef USE_DTRACE
static int DTraceObjCmd(ClientData dummy, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]);
+ Tcl_Obj *const objv[]);
#endif
extern TclStubs tclStubs;
/*
- * The following structure defines the commands in the Tcl core.
+ * The following structure define the commands in the Tcl core.
*/
typedef struct {
- char *name; /* Name of object-based command. */
- Tcl_CmdProc *proc; /* String-based procedure for command. */
- Tcl_ObjCmdProc *objProc; /* Object-based procedure for command. */
- CompileProc *compileProc; /* Procedure called to compile command. */
- int isSafe; /* If non-zero, command will be present
- * in safe interpreter. Otherwise it will
- * be hidden. */
+ const char *name; /* Name of object-based command. */
+ Tcl_ObjCmdProc *objProc; /* Object-based function for command. */
+ CompileProc *compileProc; /* Function called to compile command. */
+ int isSafe; /* If non-zero, command will be present in
+ * safe interpreter. Otherwise it will be
+ * hidden. */
} CmdInfo;
/*
- * The built-in commands, and the procedures that implement them:
+ * The built-in commands, and the functions that implement them:
*/
-static CmdInfo builtInCmds[] = {
- /*
- * Commands in the generic core. Note that at least one of the proc or
- * objProc members should be non-NULL. This avoids infinitely recursive
- * calls between TclInvokeObjectCommand and TclInvokeStringCommand if a
- * command name is computed at runtime and results in the name of a
- * compiled command.
- */
-
- {"append", (Tcl_CmdProc *) NULL, Tcl_AppendObjCmd,
- TclCompileAppendCmd, 1},
- {"array", (Tcl_CmdProc *) NULL, Tcl_ArrayObjCmd,
- (CompileProc *) NULL, 1},
- {"binary", (Tcl_CmdProc *) NULL, Tcl_BinaryObjCmd,
- (CompileProc *) NULL, 1},
- {"break", (Tcl_CmdProc *) NULL, Tcl_BreakObjCmd,
- TclCompileBreakCmd, 1},
- {"case", (Tcl_CmdProc *) NULL, Tcl_CaseObjCmd,
- (CompileProc *) NULL, 1},
- {"catch", (Tcl_CmdProc *) NULL, Tcl_CatchObjCmd,
- TclCompileCatchCmd, 1},
- {"clock", (Tcl_CmdProc *) NULL, Tcl_ClockObjCmd,
- (CompileProc *) NULL, 1},
- {"concat", (Tcl_CmdProc *) NULL, Tcl_ConcatObjCmd,
- (CompileProc *) NULL, 1},
- {"continue", (Tcl_CmdProc *) NULL, Tcl_ContinueObjCmd,
- TclCompileContinueCmd, 1},
- {"encoding", (Tcl_CmdProc *) NULL, Tcl_EncodingObjCmd,
- (CompileProc *) NULL, 0},
- {"error", (Tcl_CmdProc *) NULL, Tcl_ErrorObjCmd,
- (CompileProc *) NULL, 1},
- {"eval", (Tcl_CmdProc *) NULL, Tcl_EvalObjCmd,
- (CompileProc *) NULL, 1},
- {"exit", (Tcl_CmdProc *) NULL, Tcl_ExitObjCmd,
- (CompileProc *) NULL, 0},
- {"expr", (Tcl_CmdProc *) NULL, Tcl_ExprObjCmd,
- TclCompileExprCmd, 1},
- {"fcopy", (Tcl_CmdProc *) NULL, Tcl_FcopyObjCmd,
- (CompileProc *) NULL, 1},
- {"fileevent", (Tcl_CmdProc *) NULL, Tcl_FileEventObjCmd,
- (CompileProc *) NULL, 1},
- {"for", (Tcl_CmdProc *) NULL, Tcl_ForObjCmd,
- TclCompileForCmd, 1},
- {"foreach", (Tcl_CmdProc *) NULL, Tcl_ForeachObjCmd,
- TclCompileForeachCmd, 1},
- {"format", (Tcl_CmdProc *) NULL, Tcl_FormatObjCmd,
- (CompileProc *) NULL, 1},
- {"global", (Tcl_CmdProc *) NULL, Tcl_GlobalObjCmd,
- (CompileProc *) NULL, 1},
- {"if", (Tcl_CmdProc *) NULL, Tcl_IfObjCmd,
- TclCompileIfCmd, 1},
- {"incr", (Tcl_CmdProc *) NULL, Tcl_IncrObjCmd,
- TclCompileIncrCmd, 1},
- {"info", (Tcl_CmdProc *) NULL, Tcl_InfoObjCmd,
- (CompileProc *) NULL, 1},
- {"join", (Tcl_CmdProc *) NULL, Tcl_JoinObjCmd,
- (CompileProc *) NULL, 1},
- {"lappend", (Tcl_CmdProc *) NULL, Tcl_LappendObjCmd,
- TclCompileLappendCmd, 1},
- {"lindex", (Tcl_CmdProc *) NULL, Tcl_LindexObjCmd,
- TclCompileLindexCmd, 1},
- {"linsert", (Tcl_CmdProc *) NULL, Tcl_LinsertObjCmd,
- (CompileProc *) NULL, 1},
- {"list", (Tcl_CmdProc *) NULL, Tcl_ListObjCmd,
- TclCompileListCmd, 1},
- {"llength", (Tcl_CmdProc *) NULL, Tcl_LlengthObjCmd,
- TclCompileLlengthCmd, 1},
- {"load", (Tcl_CmdProc *) NULL, Tcl_LoadObjCmd,
- (CompileProc *) NULL, 0},
- {"lrange", (Tcl_CmdProc *) NULL, Tcl_LrangeObjCmd,
- (CompileProc *) NULL, 1},
- {"lreplace", (Tcl_CmdProc *) NULL, Tcl_LreplaceObjCmd,
- (CompileProc *) NULL, 1},
- {"lsearch", (Tcl_CmdProc *) NULL, Tcl_LsearchObjCmd,
- (CompileProc *) NULL, 1},
- {"lset", (Tcl_CmdProc *) NULL, Tcl_LsetObjCmd,
- TclCompileLsetCmd, 1},
- {"lsort", (Tcl_CmdProc *) NULL, Tcl_LsortObjCmd,
- (CompileProc *) NULL, 1},
- {"namespace", (Tcl_CmdProc *) NULL, Tcl_NamespaceObjCmd,
- (CompileProc *) NULL, 1},
- {"package", (Tcl_CmdProc *) NULL, Tcl_PackageObjCmd,
- (CompileProc *) NULL, 1},
- {"proc", (Tcl_CmdProc *) NULL, Tcl_ProcObjCmd,
- (CompileProc *) NULL, 1},
- {"regexp", (Tcl_CmdProc *) NULL, Tcl_RegexpObjCmd,
- TclCompileRegexpCmd, 1},
- {"regsub", (Tcl_CmdProc *) NULL, Tcl_RegsubObjCmd,
- (CompileProc *) NULL, 1},
- {"rename", (Tcl_CmdProc *) NULL, Tcl_RenameObjCmd,
- (CompileProc *) NULL, 1},
- {"return", (Tcl_CmdProc *) NULL, Tcl_ReturnObjCmd,
- TclCompileReturnCmd, 1},
- {"scan", (Tcl_CmdProc *) NULL, Tcl_ScanObjCmd,
- (CompileProc *) NULL, 1},
- {"set", (Tcl_CmdProc *) NULL, Tcl_SetObjCmd,
- TclCompileSetCmd, 1},
- {"split", (Tcl_CmdProc *) NULL, Tcl_SplitObjCmd,
- (CompileProc *) NULL, 1},
- {"string", (Tcl_CmdProc *) NULL, Tcl_StringObjCmd,
- TclCompileStringCmd, 1},
- {"subst", (Tcl_CmdProc *) NULL, Tcl_SubstObjCmd,
- (CompileProc *) NULL, 1},
- {"switch", (Tcl_CmdProc *) NULL, Tcl_SwitchObjCmd,
- (CompileProc *) NULL, 1},
- {"trace", (Tcl_CmdProc *) NULL, Tcl_TraceObjCmd,
- (CompileProc *) NULL, 1},
- {"unset", (Tcl_CmdProc *) NULL, Tcl_UnsetObjCmd,
- (CompileProc *) NULL, 1},
- {"uplevel", (Tcl_CmdProc *) NULL, Tcl_UplevelObjCmd,
- (CompileProc *) NULL, 1},
- {"upvar", (Tcl_CmdProc *) NULL, Tcl_UpvarObjCmd,
- (CompileProc *) NULL, 1},
- {"variable", (Tcl_CmdProc *) NULL, Tcl_VariableObjCmd,
- (CompileProc *) NULL, 1},
- {"while", (Tcl_CmdProc *) NULL, Tcl_WhileObjCmd,
- TclCompileWhileCmd, 1},
-
- /*
- * Commands in the UNIX core:
- */
-
-#ifndef TCL_GENERIC_ONLY
- {"after", (Tcl_CmdProc *) NULL, Tcl_AfterObjCmd,
- (CompileProc *) NULL, 1},
- {"cd", (Tcl_CmdProc *) NULL, Tcl_CdObjCmd,
- (CompileProc *) NULL, 0},
- {"close", (Tcl_CmdProc *) NULL, Tcl_CloseObjCmd,
- (CompileProc *) NULL, 1},
- {"eof", (Tcl_CmdProc *) NULL, Tcl_EofObjCmd,
- (CompileProc *) NULL, 1},
- {"fblocked", (Tcl_CmdProc *) NULL, Tcl_FblockedObjCmd,
- (CompileProc *) NULL, 1},
- {"fconfigure", (Tcl_CmdProc *) NULL, Tcl_FconfigureObjCmd,
- (CompileProc *) NULL, 0},
- {"file", (Tcl_CmdProc *) NULL, Tcl_FileObjCmd,
- (CompileProc *) NULL, 0},
- {"flush", (Tcl_CmdProc *) NULL, Tcl_FlushObjCmd,
- (CompileProc *) NULL, 1},
- {"gets", (Tcl_CmdProc *) NULL, Tcl_GetsObjCmd,
- (CompileProc *) NULL, 1},
- {"glob", (Tcl_CmdProc *) NULL, Tcl_GlobObjCmd,
- (CompileProc *) NULL, 0},
- {"open", (Tcl_CmdProc *) NULL, Tcl_OpenObjCmd,
- (CompileProc *) NULL, 0},
- {"pid", (Tcl_CmdProc *) NULL, Tcl_PidObjCmd,
- (CompileProc *) NULL, 1},
- {"puts", (Tcl_CmdProc *) NULL, Tcl_PutsObjCmd,
- (CompileProc *) NULL, 1},
- {"pwd", (Tcl_CmdProc *) NULL, Tcl_PwdObjCmd,
- (CompileProc *) NULL, 0},
- {"read", (Tcl_CmdProc *) NULL, Tcl_ReadObjCmd,
- (CompileProc *) NULL, 1},
- {"seek", (Tcl_CmdProc *) NULL, Tcl_SeekObjCmd,
- (CompileProc *) NULL, 1},
- {"socket", (Tcl_CmdProc *) NULL, Tcl_SocketObjCmd,
- (CompileProc *) NULL, 0},
- {"tell", (Tcl_CmdProc *) NULL, Tcl_TellObjCmd,
- (CompileProc *) NULL, 1},
- {"time", (Tcl_CmdProc *) NULL, Tcl_TimeObjCmd,
- (CompileProc *) NULL, 1},
- {"update", (Tcl_CmdProc *) NULL, Tcl_UpdateObjCmd,
- (CompileProc *) NULL, 1},
- {"vwait", (Tcl_CmdProc *) NULL, Tcl_VwaitObjCmd,
- (CompileProc *) NULL, 1},
-
-#ifdef MAC_TCL
- {"beep", (Tcl_CmdProc *) NULL, Tcl_BeepObjCmd,
- (CompileProc *) NULL, 0},
- {"echo", Tcl_EchoCmd, (Tcl_ObjCmdProc *) NULL,
- (CompileProc *) NULL, 0},
- {"ls", (Tcl_CmdProc *) NULL, Tcl_LsObjCmd,
- (CompileProc *) NULL, 0},
- {"resource", (Tcl_CmdProc *) NULL, Tcl_ResourceObjCmd,
- (CompileProc *) NULL, 1},
- {"source", (Tcl_CmdProc *) NULL, Tcl_MacSourceObjCmd,
- (CompileProc *) NULL, 0},
-#else
- {"exec", (Tcl_CmdProc *) NULL, Tcl_ExecObjCmd,
- (CompileProc *) NULL, 0},
- {"source", (Tcl_CmdProc *) NULL, Tcl_SourceObjCmd,
- (CompileProc *) NULL, 0},
-#endif /* MAC_TCL */
-
-#endif /* TCL_GENERIC_ONLY */
- {NULL, (Tcl_CmdProc *) NULL, (Tcl_ObjCmdProc *) NULL,
- (CompileProc *) NULL, 0}
+static const CmdInfo builtInCmds[] = {
+ /*
+ * Commands in the generic core.
+ */
+
+ {"append", Tcl_AppendObjCmd, TclCompileAppendCmd, 1},
+ {"apply", Tcl_ApplyObjCmd, NULL, 1},
+ {"array", Tcl_ArrayObjCmd, NULL, 1},
+ {"binary", Tcl_BinaryObjCmd, NULL, 1},
+ {"break", Tcl_BreakObjCmd, TclCompileBreakCmd, 1},
+#ifndef EXCLUDE_OBSOLETE_COMMANDS
+ {"case", Tcl_CaseObjCmd, NULL, 1},
+#endif
+ {"catch", Tcl_CatchObjCmd, TclCompileCatchCmd, 1},
+ {"concat", Tcl_ConcatObjCmd, NULL, 1},
+ {"continue", Tcl_ContinueObjCmd, TclCompileContinueCmd, 1},
+ {"error", Tcl_ErrorObjCmd, NULL, 1},
+ {"eval", Tcl_EvalObjCmd, NULL, 1},
+ {"expr", Tcl_ExprObjCmd, TclCompileExprCmd, 1},
+ {"for", Tcl_ForObjCmd, TclCompileForCmd, 1},
+ {"foreach", Tcl_ForeachObjCmd, TclCompileForeachCmd, 1},
+ {"format", Tcl_FormatObjCmd, NULL, 1},
+ {"global", Tcl_GlobalObjCmd, TclCompileGlobalCmd, 1},
+ {"if", Tcl_IfObjCmd, TclCompileIfCmd, 1},
+ {"incr", Tcl_IncrObjCmd, TclCompileIncrCmd, 1},
+ {"join", Tcl_JoinObjCmd, NULL, 1},
+ {"lappend", Tcl_LappendObjCmd, TclCompileLappendCmd, 1},
+ {"lassign", Tcl_LassignObjCmd, TclCompileLassignCmd, 1},
+ {"lindex", Tcl_LindexObjCmd, TclCompileLindexCmd, 1},
+ {"linsert", Tcl_LinsertObjCmd, NULL, 1},
+ {"list", Tcl_ListObjCmd, TclCompileListCmd, 1},
+ {"llength", Tcl_LlengthObjCmd, TclCompileLlengthCmd, 1},
+ {"lrange", Tcl_LrangeObjCmd, NULL, 1},
+ {"lrepeat", Tcl_LrepeatObjCmd, NULL, 1},
+ {"lreplace", Tcl_LreplaceObjCmd, NULL, 1},
+ {"lreverse", Tcl_LreverseObjCmd, NULL, 1},
+ {"lsearch", Tcl_LsearchObjCmd, NULL, 1},
+ {"lset", Tcl_LsetObjCmd, TclCompileLsetCmd, 1},
+ {"lsort", Tcl_LsortObjCmd, NULL, 1},
+ {"namespace", Tcl_NamespaceObjCmd, TclCompileNamespaceCmd, 1},
+ {"package", Tcl_PackageObjCmd, NULL, 1},
+ {"proc", Tcl_ProcObjCmd, NULL, 1},
+ {"regexp", Tcl_RegexpObjCmd, TclCompileRegexpCmd, 1},
+ {"regsub", Tcl_RegsubObjCmd, NULL, 1},
+ {"rename", Tcl_RenameObjCmd, NULL, 1},
+ {"return", Tcl_ReturnObjCmd, TclCompileReturnCmd, 1},
+ {"scan", Tcl_ScanObjCmd, NULL, 1},
+ {"set", Tcl_SetObjCmd, TclCompileSetCmd, 1},
+ {"split", Tcl_SplitObjCmd, NULL, 1},
+ {"subst", Tcl_SubstObjCmd, NULL, 1},
+ {"switch", Tcl_SwitchObjCmd, TclCompileSwitchCmd, 1},
+ {"trace", Tcl_TraceObjCmd, NULL, 1},
+ {"unset", Tcl_UnsetObjCmd, NULL, 1},
+ {"uplevel", Tcl_UplevelObjCmd, NULL, 1},
+ {"upvar", Tcl_UpvarObjCmd, TclCompileUpvarCmd, 1},
+ {"variable", Tcl_VariableObjCmd, TclCompileVariableCmd, 1},
+ {"while", Tcl_WhileObjCmd, TclCompileWhileCmd, 1},
+
+ /*
+ * Commands in the OS-interface. Note that many of these are unsafe.
+ */
+
+ {"after", Tcl_AfterObjCmd, NULL, 1},
+ {"cd", Tcl_CdObjCmd, NULL, 0},
+ {"close", Tcl_CloseObjCmd, NULL, 1},
+ {"eof", Tcl_EofObjCmd, NULL, 1},
+ {"encoding", Tcl_EncodingObjCmd, NULL, 0},
+ {"exec", Tcl_ExecObjCmd, NULL, 0},
+ {"exit", Tcl_ExitObjCmd, NULL, 0},
+ {"fblocked", Tcl_FblockedObjCmd, NULL, 1},
+ {"fconfigure", Tcl_FconfigureObjCmd, NULL, 0},
+ {"fcopy", Tcl_FcopyObjCmd, NULL, 1},
+ {"file", Tcl_FileObjCmd, NULL, 0},
+ {"fileevent", Tcl_FileEventObjCmd, NULL, 1},
+ {"flush", Tcl_FlushObjCmd, NULL, 1},
+ {"gets", Tcl_GetsObjCmd, NULL, 1},
+ {"glob", Tcl_GlobObjCmd, NULL, 0},
+ {"load", Tcl_LoadObjCmd, NULL, 0},
+ {"open", Tcl_OpenObjCmd, NULL, 0},
+ {"pid", Tcl_PidObjCmd, NULL, 1},
+ {"puts", Tcl_PutsObjCmd, NULL, 1},
+ {"pwd", Tcl_PwdObjCmd, NULL, 0},
+ {"read", Tcl_ReadObjCmd, NULL, 1},
+ {"seek", Tcl_SeekObjCmd, NULL, 1},
+ {"socket", Tcl_SocketObjCmd, NULL, 0},
+ {"source", Tcl_SourceObjCmd, NULL, 0},
+ {"tell", Tcl_TellObjCmd, NULL, 1},
+ {"time", Tcl_TimeObjCmd, NULL, 1},
+ {"unload", Tcl_UnloadObjCmd, NULL, 0},
+ {"update", Tcl_UpdateObjCmd, NULL, 1},
+ {"vwait", Tcl_VwaitObjCmd, NULL, 1},
+ {NULL, NULL, NULL, 0}
};
/*
- * The following structure holds the client data for string-based
- * trace procs
+ * Math functions. All are safe.
*/
-typedef struct StringTraceData {
- ClientData clientData; /* Client data from Tcl_CreateTrace */
- Tcl_CmdTraceProc* proc; /* Trace procedure from Tcl_CreateTrace */
-} StringTraceData;
+typedef struct {
+ const char *name; /* Name of the function. The full name is
+ * "::tcl::mathfunc::<name>". */
+ Tcl_ObjCmdProc *objCmdProc; /* Function that evaluates the function */
+ ClientData clientData; /* Client data for the function */
+} BuiltinFuncDef;
+static const BuiltinFuncDef BuiltinFuncTable[] = {
+ { "abs", ExprAbsFunc, NULL },
+ { "acos", ExprUnaryFunc, (ClientData) acos },
+ { "asin", ExprUnaryFunc, (ClientData) asin },
+ { "atan", ExprUnaryFunc, (ClientData) atan },
+ { "atan2", ExprBinaryFunc, (ClientData) atan2 },
+ { "bool", ExprBoolFunc, NULL },
+ { "ceil", ExprCeilFunc, NULL },
+ { "cos", ExprUnaryFunc, (ClientData) cos },
+ { "cosh", ExprUnaryFunc, (ClientData) cosh },
+ { "double", ExprDoubleFunc, NULL },
+ { "entier", ExprEntierFunc, NULL },
+ { "exp", ExprUnaryFunc, (ClientData) exp },
+ { "floor", ExprFloorFunc, NULL },
+ { "fmod", ExprBinaryFunc, (ClientData) fmod },
+ { "hypot", ExprBinaryFunc, (ClientData) hypot },
+ { "int", ExprIntFunc, NULL },
+ { "isqrt", ExprIsqrtFunc, NULL },
+ { "log", ExprUnaryFunc, (ClientData) log },
+ { "log10", ExprUnaryFunc, (ClientData) log10 },
+ { "pow", ExprBinaryFunc, (ClientData) pow },
+ { "rand", ExprRandFunc, NULL },
+ { "round", ExprRoundFunc, NULL },
+ { "sin", ExprUnaryFunc, (ClientData) sin },
+ { "sinh", ExprUnaryFunc, (ClientData) sinh },
+ { "sqrt", ExprSqrtFunc, NULL },
+ { "srand", ExprSrandFunc, NULL },
+ { "tan", ExprUnaryFunc, (ClientData) tan },
+ { "tanh", ExprUnaryFunc, (ClientData) tanh },
+ { "wide", ExprWideFunc, NULL },
+ { NULL, NULL, NULL }
+};
+
+/*
+ * TIP#174's math operators. All are safe.
+ */
+
+typedef struct {
+ const char *name; /* Name of object-based command. */
+ Tcl_ObjCmdProc *objProc; /* Object-based function for command. */
+ CompileProc *compileProc; /* Function called to compile command. */
+ union {
+ int numArgs;
+ int identity;
+ } i;
+ const char *expected; /* For error message, what argument(s)
+ * were expected. */
+} OpCmdInfo;
+static const OpCmdInfo mathOpCmds[] = {
+ { "~", TclSingleOpCmd, TclCompileInvertOpCmd,
+ /* numArgs */ {1}, "integer"},
+ { "!", TclSingleOpCmd, TclCompileNotOpCmd,
+ /* numArgs */ {1}, "boolean"},
+ { "+", TclVariadicOpCmd, TclCompileAddOpCmd,
+ /* identity */ {0}, NULL},
+ { "*", TclVariadicOpCmd, TclCompileMulOpCmd,
+ /* identity */ {1}, NULL},
+ { "&", TclVariadicOpCmd, TclCompileAndOpCmd,
+ /* identity */ {-1}, NULL},
+ { "|", TclVariadicOpCmd, TclCompileOrOpCmd,
+ /* identity */ {0}, NULL},
+ { "^", TclVariadicOpCmd, TclCompileXorOpCmd,
+ /* identity */ {0}, NULL},
+ { "**", TclVariadicOpCmd, TclCompilePowOpCmd,
+ /* identity */ {1}, NULL},
+ { "<<", TclSingleOpCmd, TclCompileLshiftOpCmd,
+ /* numArgs */ {2}, "integer shift"},
+ { ">>", TclSingleOpCmd, TclCompileRshiftOpCmd,
+ /* numArgs */ {2}, "integer shift"},
+ { "%", TclSingleOpCmd, TclCompileModOpCmd,
+ /* numArgs */ {2}, "integer integer"},
+ { "!=", TclSingleOpCmd, TclCompileNeqOpCmd,
+ /* numArgs */ {2}, "value value"},
+ { "ne", TclSingleOpCmd, TclCompileStrneqOpCmd,
+ /* numArgs */ {2}, "value value"},
+ { "in", TclSingleOpCmd, TclCompileInOpCmd,
+ /* numArgs */ {2}, "value list"},
+ { "ni", TclSingleOpCmd, TclCompileNiOpCmd,
+ /* numArgs */ {2}, "value list"},
+ { "-", TclNoIdentOpCmd, TclCompileMinusOpCmd,
+ /* unused */ {0}, "value ?value ...?"},
+ { "/", TclNoIdentOpCmd, TclCompileDivOpCmd,
+ /* unused */ {0}, "value ?value ...?"},
+ { "<", TclSortingOpCmd, TclCompileLessOpCmd,
+ /* unused */ {0}, NULL},
+ { "<=", TclSortingOpCmd, TclCompileLeqOpCmd,
+ /* unused */ {0}, NULL},
+ { ">", TclSortingOpCmd, TclCompileGreaterOpCmd,
+ /* unused */ {0}, NULL},
+ { ">=", TclSortingOpCmd, TclCompileGeqOpCmd,
+ /* unused */ {0}, NULL},
+ { "==", TclSortingOpCmd, TclCompileEqOpCmd,
+ /* unused */ {0}, NULL},
+ { "eq", TclSortingOpCmd, TclCompileStreqOpCmd,
+ /* unused */ {0}, NULL},
+ { NULL, NULL, NULL,
+ {0}, NULL}
+};
+
+/*
+ * Macros for stack checks. The goal of these macros is to allow the size of
+ * the stack to be checked (so preventing overflow) in a *cheap* way. Note
+ * that the check needs to be (amortized) cheap since it is on the critical
+ * path for recursion.
+ */
+
+#if defined(TCL_NO_STACK_CHECK)
+/*
+ * Stack check disabled: make them noops.
+ */
+
+# define CheckCStack(interp, localIntPtr) 1
+# define GetCStackParams(iPtr) /* do nothing */
+#elif defined(TCL_CROSS_COMPILE)
+
+/*
+ * This variable is static and only set *once*, during library initialization.
+ * It therefore needs no thread guards.
+ */
+
+static int stackGrowsDown = 1;
+# define GetCStackParams(iPtr) \
+ stackGrowsDown = TclpGetCStackParams(&((iPtr)->stackBound))
+# define CheckCStack(iPtr, localIntPtr) \
+ (stackGrowsDown \
+ ? ((localIntPtr) > (iPtr)->stackBound) \
+ : ((localIntPtr) < (iPtr)->stackBound) \
+ )
+#else /* !TCL_NO_STACK_CHECK && !TCL_CROSS_COMPILE */
+# define GetCStackParams(iPtr) \
+ TclpGetCStackParams(&((iPtr)->stackBound))
+# ifdef TCL_STACK_GROWS_UP
+# define CheckCStack(iPtr, localIntPtr) \
+ (!(iPtr)->stackBound || (localIntPtr) < (iPtr)->stackBound)
+# else /* TCL_STACK_GROWS_UP */
+# define CheckCStack(iPtr, localIntPtr) \
+ ((localIntPtr) > (iPtr)->stackBound)
+# endif /* TCL_STACK_GROWS_UP */
+#endif /* TCL_NO_STACK_CHECK/TCL_CROSS_COMPILE */
/*
*----------------------------------------------------------------------
@@ -284,28 +367,26 @@ typedef struct StringTraceData {
* Create a new TCL command interpreter.
*
* Results:
- * The return value is a token for the interpreter, which may be
- * used in calls to procedures like Tcl_CreateCmd, Tcl_Eval, or
- * Tcl_DeleteInterp.
+ * The return value is a token for the interpreter, which may be used in
+ * calls to functions like Tcl_CreateCmd, Tcl_Eval, or Tcl_DeleteInterp.
*
* Side effects:
- * The command interpreter is initialized with the built-in commands
- * and with the variables documented in tclvars(n).
+ * The command interpreter is initialized with the built-in commands and
+ * with the variables documented in tclvars(n).
*
*----------------------------------------------------------------------
*/
Tcl_Interp *
-Tcl_CreateInterp()
+Tcl_CreateInterp(void)
{
Interp *iPtr;
Tcl_Interp *interp;
Command *cmdPtr;
- BuiltinFunc *builtinFuncPtr;
- MathFunc *mathFuncPtr;
- Tcl_HashEntry *hPtr;
- CmdInfo *cmdInfoPtr;
- int i;
+ const BuiltinFuncDef *builtinFuncPtr;
+ const OpCmdInfo *opcmdInfoPtr;
+ const CmdInfo *cmdInfoPtr;
+ Tcl_Namespace *mathfuncNSPtr, *mathopNSPtr;
union {
char c[sizeof(short)];
short s;
@@ -313,65 +394,76 @@ Tcl_CreateInterp()
#ifdef TCL_COMPILE_STATS
ByteCodeStats *statsPtr;
#endif /* TCL_COMPILE_STATS */
+ char mathFuncName[32];
+ CallFrame *framePtr;
+ int result;
- TclInitSubsystems(NULL);
+ TclInitSubsystems();
/*
- * Panic if someone updated the CallFrame structure without
- * also updating the Tcl_CallFrame structure (or vice versa).
- */
+ * Panic if someone updated the CallFrame structure without also updating
+ * the Tcl_CallFrame structure (or vice versa).
+ */
if (sizeof(Tcl_CallFrame) < sizeof(CallFrame)) {
/*NOTREACHED*/
- panic("Tcl_CallFrame must not be smaller than CallFrame");
+ Tcl_Panic("Tcl_CallFrame must not be smaller than CallFrame");
}
/*
* Initialize support for namespaces and create the global namespace
- * (whose name is ""; an alias is "::"). This also initializes the
- * Tcl object type table and other object management code.
+ * (whose name is ""; an alias is "::"). This also initializes the Tcl
+ * object type table and other object management code.
*/
iPtr = (Interp *) ckalloc(sizeof(Interp));
interp = (Tcl_Interp *) iPtr;
- iPtr->result = iPtr->resultSpace;
- iPtr->freeProc = NULL;
- iPtr->errorLine = 0;
- iPtr->objResultPtr = Tcl_NewObj();
+ iPtr->result = iPtr->resultSpace;
+ iPtr->freeProc = NULL;
+ iPtr->errorLine = 0;
+ iPtr->objResultPtr = Tcl_NewObj();
Tcl_IncrRefCount(iPtr->objResultPtr);
- iPtr->handle = TclHandleCreate(iPtr);
- iPtr->globalNsPtr = NULL;
- iPtr->hiddenCmdTablePtr = NULL;
- iPtr->interpInfo = NULL;
- Tcl_InitHashTable(&iPtr->mathFuncTable, TCL_STRING_KEYS);
+ iPtr->handle = TclHandleCreate(iPtr);
+ iPtr->globalNsPtr = NULL;
+ iPtr->hiddenCmdTablePtr = NULL;
+ iPtr->interpInfo = NULL;
iPtr->numLevels = 0;
iPtr->maxNestingDepth = MAX_NESTING_DEPTH;
- iPtr->framePtr = NULL;
- iPtr->varFramePtr = NULL;
+ iPtr->framePtr = NULL; /* Initialise as soon as :: is available */
+ iPtr->varFramePtr = NULL; /* Initialise as soon as :: is available */
-#ifdef TCL_TIP280
/*
* TIP #280 - Initialize the arrays used to extend the ByteCode and
* Proc structures.
*/
- iPtr->cmdFramePtr = NULL;
- iPtr->linePBodyPtr = (Tcl_HashTable*) ckalloc (sizeof (Tcl_HashTable));
- iPtr->lineBCPtr = (Tcl_HashTable*) ckalloc (sizeof (Tcl_HashTable));
- iPtr->lineLAPtr = (Tcl_HashTable*) ckalloc (sizeof (Tcl_HashTable));
- iPtr->lineLABCPtr = (Tcl_HashTable*) ckalloc (sizeof (Tcl_HashTable));
+
+ iPtr->cmdFramePtr = NULL;
+ iPtr->linePBodyPtr = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
+ iPtr->lineBCPtr = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
+ iPtr->lineLAPtr = (Tcl_HashTable*) ckalloc (sizeof (Tcl_HashTable));
+ iPtr->lineLABCPtr = (Tcl_HashTable*) ckalloc (sizeof (Tcl_HashTable));
Tcl_InitHashTable(iPtr->linePBodyPtr, TCL_ONE_WORD_KEYS);
- Tcl_InitHashTable(iPtr->lineBCPtr, TCL_ONE_WORD_KEYS);
- Tcl_InitHashTable(iPtr->lineLAPtr, TCL_ONE_WORD_KEYS);
- Tcl_InitHashTable(iPtr->lineLABCPtr, TCL_ONE_WORD_KEYS);
+ Tcl_InitHashTable(iPtr->lineBCPtr, TCL_ONE_WORD_KEYS);
+ Tcl_InitHashTable(iPtr->lineLAPtr, TCL_ONE_WORD_KEYS);
+ Tcl_InitHashTable(iPtr->lineLABCPtr, TCL_ONE_WORD_KEYS);
iPtr->scriptCLLocPtr = NULL;
-#endif
iPtr->activeVarTracePtr = NULL;
- iPtr->returnCode = TCL_OK;
+
+ iPtr->returnOpts = NULL;
iPtr->errorInfo = NULL;
+ TclNewLiteralStringObj(iPtr->eiVar, "::errorInfo");
+ Tcl_IncrRefCount(iPtr->eiVar);
iPtr->errorCode = NULL;
+ TclNewLiteralStringObj(iPtr->ecVar, "::errorCode");
+ Tcl_IncrRefCount(iPtr->ecVar);
+ iPtr->returnLevel = 1;
+ iPtr->returnCode = TCL_OK;
+
+ iPtr->rootFramePtr = NULL; /* Initialise as soon as :: is available */
+ iPtr->lookupNsPtr = NULL;
iPtr->appendResult = NULL;
iPtr->appendAvl = 0;
@@ -379,14 +471,15 @@ Tcl_CreateInterp()
Tcl_InitHashTable(&iPtr->packageTable, TCL_STRING_KEYS);
iPtr->packageUnknown = NULL;
-#ifdef TCL_TIP268
+
/* TIP #268 */
- iPtr->packagePrefer = (getenv ("TCL_PKG_PREFER_LATEST") == NULL ?
- PKG_PREFER_STABLE :
- PKG_PREFER_LATEST);
-#endif
+ if (getenv("TCL_PKG_PREFER_LATEST") == NULL) {
+ iPtr->packagePrefer = PKG_PREFER_STABLE;
+ } else {
+ iPtr->packagePrefer = PKG_PREFER_LATEST;
+ }
+
iPtr->cmdCount = 0;
- iPtr->termOffset = 0;
TclInitLiteralTable(&(iPtr->literalTable));
iPtr->compileEpoch = 0;
iPtr->compiledProcPtr = NULL;
@@ -398,19 +491,56 @@ Tcl_CreateInterp()
iPtr->tracesForbiddingInline = 0;
iPtr->activeCmdTracePtr = NULL;
iPtr->activeInterpTracePtr = NULL;
- iPtr->assocData = (Tcl_HashTable *) NULL;
- iPtr->execEnvPtr = NULL; /* set after namespaces initialized */
- iPtr->emptyObjPtr = Tcl_NewObj(); /* another empty object */
+ iPtr->assocData = NULL;
+ iPtr->execEnvPtr = NULL; /* Set after namespaces initialized. */
+ iPtr->emptyObjPtr = Tcl_NewObj();
+ /* Another empty object. */
Tcl_IncrRefCount(iPtr->emptyObjPtr);
iPtr->resultSpace[0] = 0;
iPtr->threadId = Tcl_GetCurrentThread();
- iPtr->globalNsPtr = NULL; /* force creation of global ns below */
+ /* TIP #378 */
+#ifdef TCL_INTERP_DEBUG_FRAME
+ iPtr->flags |= INTERP_DEBUG_FRAME;
+#else
+ if (getenv("TCL_INTERP_DEBUG_FRAME") != NULL) {
+ iPtr->flags |= INTERP_DEBUG_FRAME;
+ }
+#endif
+
+ /*
+ * Initialise the tables for variable traces and searches *before*
+ * creating the global ns - so that the trace on errorInfo can be
+ * recorded.
+ */
+
+ Tcl_InitHashTable(&iPtr->varTraces, TCL_ONE_WORD_KEYS);
+ Tcl_InitHashTable(&iPtr->varSearches, TCL_ONE_WORD_KEYS);
+
+ iPtr->globalNsPtr = NULL; /* Force creation of global ns below. */
iPtr->globalNsPtr = (Namespace *) Tcl_CreateNamespace(interp, "",
- (ClientData) NULL, (Tcl_NamespaceDeleteProc *) NULL);
+ NULL, NULL);
if (iPtr->globalNsPtr == NULL) {
- panic("Tcl_CreateInterp: can't create global namespace");
+ Tcl_Panic("Tcl_CreateInterp: can't create global namespace");
+ }
+
+ /*
+ * Initialise the rootCallframe. It cannot be allocated on the stack, as
+ * it has to be in place before TclCreateExecEnv tries to use a variable.
+ */
+
+ /* This is needed to satisfy GCC 3.3's strict aliasing rules */
+ framePtr = (CallFrame *) ckalloc(sizeof(CallFrame));
+ result = Tcl_PushCallFrame(interp, (Tcl_CallFrame *) framePtr,
+ (Tcl_Namespace *) iPtr->globalNsPtr, /*isProcCallFrame*/ 0);
+ if (result != TCL_OK) {
+ Tcl_Panic("Tcl_CreateInterp: failed to push the root stack frame");
}
+ framePtr->objc = 0;
+
+ iPtr->framePtr = framePtr;
+ iPtr->varFramePtr = framePtr;
+ iPtr->rootFramePtr = framePtr;
/*
* Initialize support for code compilation and execution. We call
@@ -422,6 +552,12 @@ Tcl_CreateInterp()
iPtr->execEnvPtr = TclCreateExecEnv(interp);
/*
+ * TIP #219, Tcl Channel Reflection API support.
+ */
+
+ iPtr->chanMsg = NULL;
+
+ /*
* Initialize the compilation and execution statistics kept for this
* interpreter.
*/
@@ -431,31 +567,28 @@ Tcl_CreateInterp()
statsPtr->numExecutions = 0;
statsPtr->numCompilations = 0;
statsPtr->numByteCodesFreed = 0;
- (VOID *) memset(statsPtr->instructionCount, 0,
+ (void) memset(statsPtr->instructionCount, 0,
sizeof(statsPtr->instructionCount));
statsPtr->totalSrcBytes = 0.0;
statsPtr->totalByteCodeBytes = 0.0;
statsPtr->currentSrcBytes = 0.0;
statsPtr->currentByteCodeBytes = 0.0;
- (VOID *) memset(statsPtr->srcCount, 0, sizeof(statsPtr->srcCount));
- (VOID *) memset(statsPtr->byteCodeCount, 0,
- sizeof(statsPtr->byteCodeCount));
- (VOID *) memset(statsPtr->lifetimeCount, 0,
- sizeof(statsPtr->lifetimeCount));
-
- statsPtr->currentInstBytes = 0.0;
- statsPtr->currentLitBytes = 0.0;
+ (void) memset(statsPtr->srcCount, 0, sizeof(statsPtr->srcCount));
+ (void) memset(statsPtr->byteCodeCount, 0, sizeof(statsPtr->byteCodeCount));
+ (void) memset(statsPtr->lifetimeCount, 0, sizeof(statsPtr->lifetimeCount));
+
+ statsPtr->currentInstBytes = 0.0;
+ statsPtr->currentLitBytes = 0.0;
statsPtr->currentExceptBytes = 0.0;
- statsPtr->currentAuxBytes = 0.0;
+ statsPtr->currentAuxBytes = 0.0;
statsPtr->currentCmdMapBytes = 0.0;
-
- statsPtr->numLiteralsCreated = 0;
- statsPtr->totalLitStringBytes = 0.0;
+
+ statsPtr->numLiteralsCreated = 0;
+ statsPtr->totalLitStringBytes = 0.0;
statsPtr->currentLitStringBytes = 0.0;
- (VOID *) memset(statsPtr->literalCount, 0,
- sizeof(statsPtr->literalCount));
-#endif /* TCL_COMPILE_STATS */
+ (void) memset(statsPtr->literalCount, 0, sizeof(statsPtr->literalCount));
+#endif /* TCL_COMPILE_STATS */
/*
* Initialise the stub table pointer.
@@ -463,54 +596,74 @@ Tcl_CreateInterp()
iPtr->stubTable = &tclStubs;
-
+ /*
+ * Initialize the ensemble error message rewriting support.
+ */
+
+ iPtr->ensembleRewrite.sourceObjs = NULL;
+ iPtr->ensembleRewrite.numRemovedObjs = 0;
+ iPtr->ensembleRewrite.numInsertedObjs = 0;
+
+ /*
+ * TIP#143: Initialise the resource limit support.
+ */
+
+ TclInitLimitSupport(interp);
+
+ /*
+ * Initialise the thread-specific data ekeko.
+ */
+
+#if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)
+ iPtr->allocCache = TclpGetAllocCache();
+#else
+ iPtr->allocCache = NULL;
+#endif
+ iPtr->pendingObjDataPtr = NULL;
+ iPtr->asyncReadyPtr = TclGetAsyncReadyPtr();
+
+ /*
+ * Insure that the stack checking mechanism for this interp is
+ * initialized.
+ */
+
+ GetCStackParams(iPtr);
+
/*
* Create the core commands. Do it here, rather than calling
- * Tcl_CreateCommand, because it's faster (there's no need to check for
- * a pre-existing command by the same name). If a command has a
- * Tcl_CmdProc but no Tcl_ObjCmdProc, set the Tcl_ObjCmdProc to
- * TclInvokeStringCommand. This is an object-based wrapper procedure
- * that extracts strings, calls the string procedure, and creates an
- * object for the result. Similarly, if a command has a Tcl_ObjCmdProc
- * but no Tcl_CmdProc, set the Tcl_CmdProc to TclInvokeObjectCommand.
- */
-
- for (cmdInfoPtr = builtInCmds; cmdInfoPtr->name != NULL;
- cmdInfoPtr++) {
- int new;
+ * Tcl_CreateCommand, because it's faster (there's no need to check for a
+ * pre-existing command by the same name). If a command has a Tcl_CmdProc
+ * but no Tcl_ObjCmdProc, set the Tcl_ObjCmdProc to
+ * TclInvokeStringCommand. This is an object-based wrapper function that
+ * extracts strings, calls the string function, and creates an object for
+ * the result. Similarly, if a command has a Tcl_ObjCmdProc but no
+ * Tcl_CmdProc, set the Tcl_CmdProc to TclInvokeObjectCommand.
+ */
+
+ for (cmdInfoPtr = builtInCmds; cmdInfoPtr->name != NULL; cmdInfoPtr++) {
+ int isNew;
Tcl_HashEntry *hPtr;
- if ((cmdInfoPtr->proc == (Tcl_CmdProc *) NULL)
- && (cmdInfoPtr->objProc == (Tcl_ObjCmdProc *) NULL)
- && (cmdInfoPtr->compileProc == (CompileProc *) NULL)) {
- panic("Tcl_CreateInterp: builtin command with NULL string and object command procs and a NULL compile proc\n");
+ if ((cmdInfoPtr->objProc == NULL)
+ && (cmdInfoPtr->compileProc == NULL)) {
+ Tcl_Panic("builtin command with NULL object command proc and a NULL compile proc");
}
-
+
hPtr = Tcl_CreateHashEntry(&iPtr->globalNsPtr->cmdTable,
- cmdInfoPtr->name, &new);
- if (new) {
+ cmdInfoPtr->name, &isNew);
+ if (isNew) {
cmdPtr = (Command *) ckalloc(sizeof(Command));
cmdPtr->hPtr = hPtr;
cmdPtr->nsPtr = iPtr->globalNsPtr;
cmdPtr->refCount = 1;
cmdPtr->cmdEpoch = 0;
cmdPtr->compileProc = cmdInfoPtr->compileProc;
- if (cmdInfoPtr->proc == (Tcl_CmdProc *) NULL) {
- cmdPtr->proc = TclInvokeObjectCommand;
- cmdPtr->clientData = (ClientData) cmdPtr;
- } else {
- cmdPtr->proc = cmdInfoPtr->proc;
- cmdPtr->clientData = (ClientData) NULL;
- }
- if (cmdInfoPtr->objProc == (Tcl_ObjCmdProc *) NULL) {
- cmdPtr->objProc = TclInvokeStringCommand;
- cmdPtr->objClientData = (ClientData) cmdPtr;
- } else {
- cmdPtr->objProc = cmdInfoPtr->objProc;
- cmdPtr->objClientData = (ClientData) NULL;
- }
+ cmdPtr->proc = TclInvokeObjectCommand;
+ cmdPtr->clientData = cmdPtr;
+ cmdPtr->objProc = cmdInfoPtr->objProc;
+ cmdPtr->objClientData = NULL;
cmdPtr->deleteProc = NULL;
- cmdPtr->deleteData = (ClientData) NULL;
+ cmdPtr->deleteData = NULL;
cmdPtr->flags = 0;
cmdPtr->importRefPtr = NULL;
cmdPtr->tracePtr = NULL;
@@ -518,6 +671,44 @@ Tcl_CreateInterp()
}
}
+ /*
+ * Create the "chan", "dict", "info" and "string" ensembles. Note that all
+ * these commands (and their subcommands that are not present in the
+ * global namespace) are wholly safe.
+ */
+
+ TclInitChanCmd(interp);
+ TclInitDictCmd(interp);
+ TclInitInfoCmd(interp);
+ TclInitStringCmd(interp);
+
+ /*
+ * Register "clock" subcommands. These *do* go through
+ * Tcl_CreateObjCommand, since they aren't in the global namespace and
+ * involve ensembles.
+ */
+
+ TclClockInit(interp);
+
+ /*
+ * Register the built-in functions. This is empty now that they are
+ * implemented as commands in the ::tcl::mathfunc namespace.
+ */
+
+ /*
+ * Register the default [interp bgerror] handler.
+ */
+
+ Tcl_CreateObjCommand(interp, "::tcl::Bgerror",
+ TclDefaultBgErrorHandlerObjCmd, NULL, NULL);
+
+ /*
+ * Create an unsupported command for debugging bytecode.
+ */
+
+ Tcl_CreateObjCommand(interp, "::tcl::unsupported::disassemble",
+ Tcl_DisassembleObjCmd, NULL, NULL);
+
#ifdef USE_DTRACE
/*
* Register the tcl::dtrace command.
@@ -530,57 +721,61 @@ Tcl_CreateInterp()
* Register the builtin math functions.
*/
- i = 0;
- for (builtinFuncPtr = tclBuiltinFuncTable; builtinFuncPtr->name != NULL;
+ mathfuncNSPtr = Tcl_CreateNamespace(interp, "::tcl::mathfunc", NULL,NULL);
+ if (mathfuncNSPtr == NULL) {
+ Tcl_Panic("Can't create math function namespace");
+ }
+ strcpy(mathFuncName, "::tcl::mathfunc::");
+#define MATH_FUNC_PREFIX_LEN 17 /* == strlen("::tcl::mathfunc::") */
+ for (builtinFuncPtr = BuiltinFuncTable; builtinFuncPtr->name != NULL;
builtinFuncPtr++) {
- Tcl_CreateMathFunc((Tcl_Interp *) iPtr, builtinFuncPtr->name,
- builtinFuncPtr->numArgs, builtinFuncPtr->argTypes,
- (Tcl_MathProc *) NULL, (ClientData) 0);
- hPtr = Tcl_FindHashEntry(&iPtr->mathFuncTable,
- builtinFuncPtr->name);
- if (hPtr == NULL) {
- panic("Tcl_CreateInterp: Tcl_CreateMathFunc incorrectly registered '%s'", builtinFuncPtr->name);
- return NULL;
+ strcpy(mathFuncName+MATH_FUNC_PREFIX_LEN, builtinFuncPtr->name);
+ Tcl_CreateObjCommand(interp, mathFuncName,
+ builtinFuncPtr->objCmdProc, builtinFuncPtr->clientData, NULL);
+ Tcl_Export(interp, mathfuncNSPtr, builtinFuncPtr->name, 0);
+ }
+
+ /*
+ * Register the mathematical "operator" commands. [TIP #174]
+ */
+
+ mathopNSPtr = Tcl_CreateNamespace(interp, "::tcl::mathop", NULL, NULL);
+#define MATH_OP_PREFIX_LEN 15 /* == strlen("::tcl::mathop::") */
+ if (mathopNSPtr == NULL) {
+ Tcl_Panic("can't create math operator namespace");
+ }
+ (void) Tcl_Export(interp, mathopNSPtr, "*", 1);
+ strcpy(mathFuncName, "::tcl::mathop::");
+ for (opcmdInfoPtr=mathOpCmds ; opcmdInfoPtr->name!=NULL ; opcmdInfoPtr++){
+ TclOpCmdClientData *occdPtr = (TclOpCmdClientData *)
+ ckalloc(sizeof(TclOpCmdClientData));
+
+ occdPtr->op = opcmdInfoPtr->name;
+ occdPtr->i.numArgs = opcmdInfoPtr->i.numArgs;
+ occdPtr->expected = opcmdInfoPtr->expected;
+ strcpy(mathFuncName + MATH_OP_PREFIX_LEN, opcmdInfoPtr->name);
+ cmdPtr = (Command *) Tcl_CreateObjCommand(interp, mathFuncName,
+ opcmdInfoPtr->objProc, occdPtr, DeleteOpCmdClientData);
+ if (cmdPtr == NULL) {
+ Tcl_Panic("failed to create math operator %s",
+ opcmdInfoPtr->name);
+ } else if (opcmdInfoPtr->compileProc != NULL) {
+ cmdPtr->compileProc = opcmdInfoPtr->compileProc;
}
- mathFuncPtr = (MathFunc *) Tcl_GetHashValue(hPtr);
- mathFuncPtr->builtinFuncIndex = i;
- i++;
}
- iPtr->flags |= EXPR_INITIALIZED;
/*
* Do Multiple/Safe Interps Tcl init stuff
*/
TclInterpInit(interp);
+ TclSetupEnv(interp);
/*
- * We used to create the "errorInfo" and "errorCode" global vars at this
- * point because so much of the Tcl implementation assumes they already
- * exist. This is not quite enough, however, since they can be unset
- * at any time.
- *
- * There are 2 choices:
- * + Check every place where a GetVar of those is used
- * and the NULL result is not checked (like in tclLoad.c)
- * + Make SetVar,... NULL friendly
- * We choose the second option because :
- * + It is easy and low cost to check for NULL pointer before
- * calling strlen()
- * + It can be helpfull to other people using those API
- * + Passing a NULL value to those closest 'meaning' is empty string
- * (specially with the new objects where 0 bytes strings are ok)
- * So the following init is commented out: -- dl
- *
- * (void) Tcl_SetVar2((Tcl_Interp *)iPtr, "errorInfo", (char *) NULL,
- * "", TCL_GLOBAL_ONLY);
- * (void) Tcl_SetVar2((Tcl_Interp *)iPtr, "errorCode", (char *) NULL,
- * "NONE", TCL_GLOBAL_ONLY);
+ * TIP #59: Make embedded configuration information available.
*/
-#ifndef TCL_GENERIC_ONLY
- TclSetupEnv(interp);
-#endif
+ TclInitEmbeddedConfigurationInformation(interp);
/*
* Compute the byte order of this machine.
@@ -594,62 +789,66 @@ Tcl_CreateInterp()
Tcl_SetVar2Ex(interp, "tcl_platform", "wordSize",
Tcl_NewLongObj((long) sizeof(long)), TCL_GLOBAL_ONLY);
+ /* TIP #291 */
+ Tcl_SetVar2Ex(interp, "tcl_platform", "pointerSize",
+ Tcl_NewLongObj((long) sizeof(void *)), TCL_GLOBAL_ONLY);
+
/*
* Set up other variables such as tcl_version and tcl_library
*/
Tcl_SetVar(interp, "tcl_patchLevel", TCL_PATCH_LEVEL, TCL_GLOBAL_ONLY);
Tcl_SetVar(interp, "tcl_version", TCL_VERSION, TCL_GLOBAL_ONLY);
- Tcl_TraceVar2(interp, "tcl_precision", (char *) NULL,
+ Tcl_TraceVar2(interp, "tcl_precision", NULL,
TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
- TclPrecTraceProc, (ClientData) NULL);
+ TclPrecTraceProc, NULL);
TclpSetVariables(interp);
#ifdef TCL_THREADS
/*
- * The existence of the "threaded" element of the tcl_platform array indicates
- * that this particular Tcl shell has been compiled with threads turned on.
- * Using "info exists tcl_platform(threaded)" a Tcl script can introspect on the
- * interpreter level of thread safety.
+ * The existence of the "threaded" element of the tcl_platform array
+ * indicates that this particular Tcl shell has been compiled with threads
+ * turned on. Using "info exists tcl_platform(threaded)" a Tcl script can
+ * introspect on the interpreter level of thread safety.
*/
-
- Tcl_SetVar2(interp, "tcl_platform", "threaded", "1",
- TCL_GLOBAL_ONLY);
+ Tcl_SetVar2(interp, "tcl_platform", "threaded", "1", TCL_GLOBAL_ONLY);
#endif
/*
* Register Tcl's version number.
- * TIP#268: Expose information about its status,
- * for runtime switches in the core library
- * and tests.
+ * TIP #268: Full patchlevel instead of just major.minor
*/
- Tcl_PkgProvideEx(interp, "Tcl", TCL_VERSION, (ClientData) &tclStubs);
+ Tcl_PkgProvideEx(interp, "Tcl", TCL_PATCH_LEVEL, &tclStubs);
-#ifdef TCL_TIP268
- Tcl_SetVar2(interp, "tcl_platform", "tip,268", "1",
- TCL_GLOBAL_ONLY);
-#endif
-#ifdef TCL_TIP280
- Tcl_SetVar2(interp, "tcl_platform", "tip,280", "1",
- TCL_GLOBAL_ONLY);
-#endif
#ifdef Tcl_InitStubs
#undef Tcl_InitStubs
#endif
Tcl_InitStubs(interp, TCL_VERSION, 1);
+ if (TclTommath_Init(interp) != TCL_OK) {
+ Tcl_Panic("%s", Tcl_GetString(Tcl_GetObjResult(interp)));
+ }
+
return interp;
}
+
+static void
+DeleteOpCmdClientData(
+ ClientData clientData)
+{
+ TclOpCmdClientData *occdPtr = clientData;
+
+ ckfree((char *) occdPtr);
+}
/*
*----------------------------------------------------------------------
*
* TclHideUnsafeCommands --
*
- * Hides base commands that are not marked as safe from this
- * interpreter.
+ * Hides base commands that are not marked as safe from this interpreter.
*
* Results:
* TCL_OK if it succeeds, TCL_ERROR else.
@@ -661,18 +860,18 @@ Tcl_CreateInterp()
*/
int
-TclHideUnsafeCommands(interp)
- Tcl_Interp *interp; /* Hide commands in this interpreter. */
+TclHideUnsafeCommands(
+ Tcl_Interp *interp) /* Hide commands in this interpreter. */
{
- register CmdInfo *cmdInfoPtr;
+ register const CmdInfo *cmdInfoPtr;
- if (interp == (Tcl_Interp *) NULL) {
- return TCL_ERROR;
+ if (interp == NULL) {
+ return TCL_ERROR;
}
for (cmdInfoPtr = builtInCmds; cmdInfoPtr->name != NULL; cmdInfoPtr++) {
- if (!cmdInfoPtr->isSafe) {
- Tcl_HideCommand(interp, cmdInfoPtr->name, cmdInfoPtr->name);
- }
+ if (!cmdInfoPtr->isSafe) {
+ Tcl_HideCommand(interp, cmdInfoPtr->name, cmdInfoPtr->name);
+ }
}
return TCL_OK;
}
@@ -682,36 +881,34 @@ TclHideUnsafeCommands(interp)
*
* Tcl_CallWhenDeleted --
*
- * Arrange for a procedure to be called before a given
- * interpreter is deleted. The procedure is called as soon
- * as Tcl_DeleteInterp is called; if Tcl_CallWhenDeleted is
- * called on an interpreter that has already been deleted,
- * the procedure will be called when the last Tcl_Release is
+ * Arrange for a function to be called before a given interpreter is
+ * deleted. The function is called as soon as Tcl_DeleteInterp is called;
+ * if Tcl_CallWhenDeleted is called on an interpreter that has already
+ * been deleted, the function will be called when the last Tcl_Release is
* done on the interpreter.
*
* Results:
* None.
*
* Side effects:
- * When Tcl_DeleteInterp is invoked to delete interp,
- * proc will be invoked. See the manual entry for
- * details.
+ * When Tcl_DeleteInterp is invoked to delete interp, proc will be
+ * invoked. See the manual entry for details.
*
*--------------------------------------------------------------
*/
void
-Tcl_CallWhenDeleted(interp, proc, clientData)
- Tcl_Interp *interp; /* Interpreter to watch. */
- Tcl_InterpDeleteProc *proc; /* Procedure to call when interpreter
- * is about to be deleted. */
- ClientData clientData; /* One-word value to pass to proc. */
+Tcl_CallWhenDeleted(
+ Tcl_Interp *interp, /* Interpreter to watch. */
+ Tcl_InterpDeleteProc *proc, /* Function to call when interpreter is about
+ * to be deleted. */
+ ClientData clientData) /* One-word value to pass to proc. */
{
Interp *iPtr = (Interp *) interp;
static Tcl_ThreadDataKey assocDataCounterKey;
int *assocDataCounterPtr =
Tcl_GetThreadData(&assocDataCounterKey, (int)sizeof(int));
- int new;
+ int isNew;
char buffer[32 + TCL_INTEGER_SPACE];
AssocData *dPtr = (AssocData *) ckalloc(sizeof(AssocData));
Tcl_HashEntry *hPtr;
@@ -719,11 +916,11 @@ Tcl_CallWhenDeleted(interp, proc, clientData)
sprintf(buffer, "Assoc Data Key #%d", *assocDataCounterPtr);
(*assocDataCounterPtr)++;
- if (iPtr->assocData == (Tcl_HashTable *) NULL) {
- iPtr->assocData = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
- Tcl_InitHashTable(iPtr->assocData, TCL_STRING_KEYS);
+ if (iPtr->assocData == NULL) {
+ iPtr->assocData = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
+ Tcl_InitHashTable(iPtr->assocData, TCL_STRING_KEYS);
}
- hPtr = Tcl_CreateHashEntry(iPtr->assocData, buffer, &new);
+ hPtr = Tcl_CreateHashEntry(iPtr->assocData, buffer, &isNew);
dPtr->proc = proc;
dPtr->clientData = clientData;
Tcl_SetHashValue(hPtr, dPtr);
@@ -734,27 +931,26 @@ Tcl_CallWhenDeleted(interp, proc, clientData)
*
* Tcl_DontCallWhenDeleted --
*
- * Cancel the arrangement for a procedure to be called when
- * a given interpreter is deleted.
+ * Cancel the arrangement for a function to be called when a given
+ * interpreter is deleted.
*
* Results:
* None.
*
* Side effects:
- * If proc and clientData were previously registered as a
- * callback via Tcl_CallWhenDeleted, they are unregistered.
- * If they weren't previously registered then nothing
- * happens.
+ * If proc and clientData were previously registered as a callback via
+ * Tcl_CallWhenDeleted, they are unregistered. If they weren't previously
+ * registered then nothing happens.
*
*--------------------------------------------------------------
*/
void
-Tcl_DontCallWhenDeleted(interp, proc, clientData)
- Tcl_Interp *interp; /* Interpreter to watch. */
- Tcl_InterpDeleteProc *proc; /* Procedure to call when interpreter
- * is about to be deleted. */
- ClientData clientData; /* One-word value to pass to proc. */
+Tcl_DontCallWhenDeleted(
+ Tcl_Interp *interp, /* Interpreter to watch. */
+ Tcl_InterpDeleteProc *proc, /* Function to call when interpreter is about
+ * to be deleted. */
+ ClientData clientData) /* One-word value to pass to proc. */
{
Interp *iPtr = (Interp *) interp;
Tcl_HashTable *hTablePtr;
@@ -763,17 +959,17 @@ Tcl_DontCallWhenDeleted(interp, proc, clientData)
AssocData *dPtr;
hTablePtr = iPtr->assocData;
- if (hTablePtr == (Tcl_HashTable *) NULL) {
- return;
+ if (hTablePtr == NULL) {
+ return;
}
for (hPtr = Tcl_FirstHashEntry(hTablePtr, &hSearch); hPtr != NULL;
hPtr = Tcl_NextHashEntry(&hSearch)) {
- dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
- if ((dPtr->proc == proc) && (dPtr->clientData == clientData)) {
- ckfree((char *) dPtr);
- Tcl_DeleteHashEntry(hPtr);
- return;
- }
+ dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
+ if ((dPtr->proc == proc) && (dPtr->clientData == clientData)) {
+ ckfree((char *) dPtr);
+ Tcl_DeleteHashEntry(hPtr);
+ return;
+ }
}
}
@@ -783,9 +979,9 @@ Tcl_DontCallWhenDeleted(interp, proc, clientData)
* Tcl_SetAssocData --
*
* Creates a named association between user-specified data, a delete
- * function and this interpreter. If the association already exists
- * the data is overwritten with the new data. The delete function will
- * be invoked when the interpreter is deleted.
+ * function and this interpreter. If the association already exists the
+ * data is overwritten with the new data. The delete function will be
+ * invoked when the interpreter is deleted.
*
* Results:
* None.
@@ -797,27 +993,27 @@ Tcl_DontCallWhenDeleted(interp, proc, clientData)
*/
void
-Tcl_SetAssocData(interp, name, proc, clientData)
- Tcl_Interp *interp; /* Interpreter to associate with. */
- CONST char *name; /* Name for association. */
- Tcl_InterpDeleteProc *proc; /* Proc to call when interpreter is
- * about to be deleted. */
- ClientData clientData; /* One-word value to pass to proc. */
+Tcl_SetAssocData(
+ Tcl_Interp *interp, /* Interpreter to associate with. */
+ const char *name, /* Name for association. */
+ Tcl_InterpDeleteProc *proc, /* Proc to call when interpreter is about to
+ * be deleted. */
+ ClientData clientData) /* One-word value to pass to proc. */
{
Interp *iPtr = (Interp *) interp;
AssocData *dPtr;
Tcl_HashEntry *hPtr;
- int new;
+ int isNew;
- if (iPtr->assocData == (Tcl_HashTable *) NULL) {
- iPtr->assocData = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
- Tcl_InitHashTable(iPtr->assocData, TCL_STRING_KEYS);
+ if (iPtr->assocData == NULL) {
+ iPtr->assocData = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
+ Tcl_InitHashTable(iPtr->assocData, TCL_STRING_KEYS);
}
- hPtr = Tcl_CreateHashEntry(iPtr->assocData, name, &new);
- if (new == 0) {
- dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
+ hPtr = Tcl_CreateHashEntry(iPtr->assocData, name, &isNew);
+ if (isNew == 0) {
+ dPtr = Tcl_GetHashValue(hPtr);
} else {
- dPtr = (AssocData *) ckalloc(sizeof(AssocData));
+ dPtr = (AssocData *) ckalloc(sizeof(AssocData));
}
dPtr->proc = proc;
dPtr->clientData = clientData;
@@ -830,8 +1026,8 @@ Tcl_SetAssocData(interp, name, proc, clientData)
*
* Tcl_DeleteAssocData --
*
- * Deletes a named association of user-specified data with
- * the specified interpreter.
+ * Deletes a named association of user-specified data with the specified
+ * interpreter.
*
* Results:
* None.
@@ -843,24 +1039,24 @@ Tcl_SetAssocData(interp, name, proc, clientData)
*/
void
-Tcl_DeleteAssocData(interp, name)
- Tcl_Interp *interp; /* Interpreter to associate with. */
- CONST char *name; /* Name of association. */
+Tcl_DeleteAssocData(
+ Tcl_Interp *interp, /* Interpreter to associate with. */
+ const char *name) /* Name of association. */
{
Interp *iPtr = (Interp *) interp;
AssocData *dPtr;
Tcl_HashEntry *hPtr;
- if (iPtr->assocData == (Tcl_HashTable *) NULL) {
- return;
+ if (iPtr->assocData == NULL) {
+ return;
}
hPtr = Tcl_FindHashEntry(iPtr->assocData, name);
- if (hPtr == (Tcl_HashEntry *) NULL) {
- return;
+ if (hPtr == NULL) {
+ return;
}
- dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
+ dPtr = Tcl_GetHashValue(hPtr);
if (dPtr->proc != NULL) {
- (dPtr->proc) (dPtr->clientData, interp);
+ dPtr->proc(dPtr->clientData, interp);
}
ckfree((char *) dPtr);
Tcl_DeleteHashEntry(hPtr);
@@ -871,8 +1067,8 @@ Tcl_DeleteAssocData(interp, name)
*
* Tcl_GetAssocData --
*
- * Returns the client data associated with this name in the
- * specified interpreter.
+ * Returns the client data associated with this name in the specified
+ * interpreter.
*
* Results:
* The client data in the AssocData record denoted by the named
@@ -885,26 +1081,27 @@ Tcl_DeleteAssocData(interp, name)
*/
ClientData
-Tcl_GetAssocData(interp, name, procPtr)
- Tcl_Interp *interp; /* Interpreter associated with. */
- CONST char *name; /* Name of association. */
- Tcl_InterpDeleteProc **procPtr; /* Pointer to place to store address
- * of current deletion callback. */
+Tcl_GetAssocData(
+ Tcl_Interp *interp, /* Interpreter associated with. */
+ const char *name, /* Name of association. */
+ Tcl_InterpDeleteProc **procPtr)
+ /* Pointer to place to store address of
+ * current deletion callback. */
{
Interp *iPtr = (Interp *) interp;
AssocData *dPtr;
Tcl_HashEntry *hPtr;
- if (iPtr->assocData == (Tcl_HashTable *) NULL) {
- return (ClientData) NULL;
+ if (iPtr->assocData == NULL) {
+ return NULL;
}
hPtr = Tcl_FindHashEntry(iPtr->assocData, name);
- if (hPtr == (Tcl_HashEntry *) NULL) {
- return (ClientData) NULL;
+ if (hPtr == NULL) {
+ return NULL;
}
- dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
- if (procPtr != (Tcl_InterpDeleteProc **) NULL) {
- *procPtr = dPtr->proc;
+ dPtr = Tcl_GetHashValue(hPtr);
+ if (procPtr != NULL) {
+ *procPtr = dPtr->proc;
}
return dPtr->clientData;
}
@@ -914,8 +1111,8 @@ Tcl_GetAssocData(interp, name, procPtr)
*
* Tcl_InterpDeleted --
*
- * Returns nonzero if the interpreter has been deleted with a call
- * to Tcl_DeleteInterp.
+ * Returns nonzero if the interpreter has been deleted with a call to
+ * Tcl_DeleteInterp.
*
* Results:
* Nonzero if the interpreter is deleted, zero otherwise.
@@ -927,8 +1124,8 @@ Tcl_GetAssocData(interp, name, procPtr)
*/
int
-Tcl_InterpDeleted(interp)
- Tcl_Interp *interp;
+Tcl_InterpDeleted(
+ Tcl_Interp *interp)
{
return (((Interp *) interp)->flags & DELETED) ? 1 : 0;
}
@@ -938,11 +1135,11 @@ Tcl_InterpDeleted(interp)
*
* Tcl_DeleteInterp --
*
- * Ensures that the interpreter will be deleted eventually. If there
- * are no Tcl_Preserve calls in effect for this interpreter, it is
- * deleted immediately, otherwise the interpreter is deleted when
- * the last Tcl_Preserve is matched by a call to Tcl_Release. In either
- * case, the procedure runs the currently registered deletion callbacks.
+ * Ensures that the interpreter will be deleted eventually. If there are
+ * no Tcl_Preserve calls in effect for this interpreter, it is deleted
+ * immediately, otherwise the interpreter is deleted when the last
+ * Tcl_Preserve is matched by a call to Tcl_Release. In either case, the
+ * function runs the currently registered deletion callbacks.
*
* Results:
* None.
@@ -957,9 +1154,9 @@ Tcl_InterpDeleted(interp)
*/
void
-Tcl_DeleteInterp(interp)
- Tcl_Interp *interp; /* Token for command interpreter (returned
- * by a previous call to Tcl_CreateInterp). */
+Tcl_DeleteInterp(
+ Tcl_Interp *interp) /* Token for command interpreter (returned by
+ * a previous call to Tcl_CreateInterp). */
{
Interp *iPtr = (Interp *) interp;
@@ -968,21 +1165,22 @@ Tcl_DeleteInterp(interp)
*/
if (iPtr->flags & DELETED) {
- return;
+ return;
}
-
+
/*
* Mark the interpreter as deleted. No further evals will be allowed.
+ * Increase the compileEpoch as a signal to compiled bytecodes.
*/
iPtr->flags |= DELETED;
+ iPtr->compileEpoch++;
/*
* Ensure that the interpreter is eventually deleted.
*/
- Tcl_EventuallyFree((ClientData) interp,
- (Tcl_FreeProc *) DeleteInterpProc);
+ Tcl_EventuallyFree(interp, (Tcl_FreeProc *) DeleteInterpProc);
}
/*
@@ -990,25 +1188,25 @@ Tcl_DeleteInterp(interp)
*
* DeleteInterpProc --
*
- * Helper procedure to delete an interpreter. This procedure is
- * called when the last call to Tcl_Preserve on this interpreter
- * is matched by a call to Tcl_Release. The procedure cleans up
- * all resources used in the interpreter and calls all currently
- * registered interpreter deletion callbacks.
+ * Helper function to delete an interpreter. This function is called when
+ * the last call to Tcl_Preserve on this interpreter is matched by a call
+ * to Tcl_Release. The function cleans up all resources used in the
+ * interpreter and calls all currently registered interpreter deletion
+ * callbacks.
*
* Results:
* None.
*
* Side effects:
- * Whatever the interpreter deletion callbacks do. Frees resources
- * used by the interpreter.
+ * Whatever the interpreter deletion callbacks do. Frees resources used
+ * by the interpreter.
*
*----------------------------------------------------------------------
*/
static void
-DeleteInterpProc(interp)
- Tcl_Interp *interp; /* Interpreter to delete. */
+DeleteInterpProc(
+ Tcl_Interp *interp) /* Interpreter to delete. */
{
Interp *iPtr = (Interp *) interp;
Tcl_HashEntry *hPtr;
@@ -1019,120 +1217,137 @@ DeleteInterpProc(interp)
/*
* Punt if there is an error in the Tcl_Release/Tcl_Preserve matchup.
*/
-
+
if (iPtr->numLevels > 0) {
- panic("DeleteInterpProc called with active evals");
+ Tcl_Panic("DeleteInterpProc called with active evals");
}
/*
- * The interpreter should already be marked deleted; otherwise how
- * did we get here?
+ * The interpreter should already be marked deleted; otherwise how did we
+ * get here?
*/
if (!(iPtr->flags & DELETED)) {
- panic("DeleteInterpProc called on interpreter not marked deleted");
+ Tcl_Panic("DeleteInterpProc called on interpreter not marked deleted");
}
- TclHandleFree(iPtr->handle);
+ /*
+ * TIP #219, Tcl Channel Reflection API. Discard a leftover state.
+ */
+
+ if (iPtr->chanMsg != NULL) {
+ Tcl_DecrRefCount(iPtr->chanMsg);
+ iPtr->chanMsg = NULL;
+ }
+
+ /*
+ * Shut down all limit handler callback scripts that call back into this
+ * interpreter. Then eliminate all limit handlers for this interpreter.
+ */
+
+ TclRemoveScriptLimitCallbacks(interp);
+ TclLimitRemoveAllHandlers(interp);
/*
- * Dismantle everything in the global namespace except for the
- * "errorInfo" and "errorCode" variables. These remain until the
- * namespace is actually destroyed, in case any errors occur.
- *
* Dismantle the namespace here, before we clear the assocData. If any
* background errors occur here, they will be deleted below.
+ *
+ * Dismantle the namespace after freeing the iPtr->handle so that each
+ * bytecode releases its literals without caring to update the literal
+ * table, as it will be freed later in this function without further use.
*/
-
+
+ TclHandleFree(iPtr->handle);
TclTeardownNamespace(iPtr->globalNsPtr);
/*
* Delete all the hidden commands.
*/
-
+
hTablePtr = iPtr->hiddenCmdTablePtr;
if (hTablePtr != NULL) {
/*
- * Non-pernicious deletion. The deletion callbacks will not be
- * allowed to create any new hidden or non-hidden commands.
+ * Non-pernicious deletion. The deletion callbacks will not be allowed
+ * to create any new hidden or non-hidden commands.
* Tcl_DeleteCommandFromToken() will remove the entry from the
* hiddenCmdTablePtr.
*/
-
+
hPtr = Tcl_FirstHashEntry(hTablePtr, &search);
- for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
+ for (; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
Tcl_DeleteCommandFromToken(interp,
(Tcl_Command) Tcl_GetHashValue(hPtr));
}
Tcl_DeleteHashTable(hTablePtr);
ckfree((char *) hTablePtr);
}
+
/*
- * Tear down the math function table.
+ * Invoke deletion callbacks; note that a callback can create new
+ * callbacks, so we iterate.
*/
- for (hPtr = Tcl_FirstHashEntry(&iPtr->mathFuncTable, &search);
- hPtr != NULL;
- hPtr = Tcl_NextHashEntry(&search)) {
- ckfree((char *) Tcl_GetHashValue(hPtr));
+ while (iPtr->assocData != NULL) {
+ AssocData *dPtr;
+
+ hTablePtr = iPtr->assocData;
+ iPtr->assocData = NULL;
+ for (hPtr = Tcl_FirstHashEntry(hTablePtr, &search);
+ hPtr != NULL;
+ hPtr = Tcl_FirstHashEntry(hTablePtr, &search)) {
+ dPtr = Tcl_GetHashValue(hPtr);
+ Tcl_DeleteHashEntry(hPtr);
+ if (dPtr->proc != NULL) {
+ dPtr->proc(dPtr->clientData, interp);
+ }
+ ckfree((char *) dPtr);
+ }
+ Tcl_DeleteHashTable(hTablePtr);
+ ckfree((char *) hTablePtr);
}
- Tcl_DeleteHashTable(&iPtr->mathFuncTable);
/*
- * Invoke deletion callbacks; note that a callback can create new
- * callbacks, so we iterate.
+ * Pop the root frame pointer and finish deleting the global
+ * namespace. The order is important [Bug 1658572].
*/
- while (iPtr->assocData != (Tcl_HashTable *) NULL) {
- AssocData *dPtr;
-
- hTablePtr = iPtr->assocData;
- iPtr->assocData = (Tcl_HashTable *) NULL;
- for (hPtr = Tcl_FirstHashEntry(hTablePtr, &search);
- hPtr != NULL;
- hPtr = Tcl_FirstHashEntry(hTablePtr, &search)) {
- dPtr = (AssocData *) Tcl_GetHashValue(hPtr);
- Tcl_DeleteHashEntry(hPtr);
- if (dPtr->proc != NULL) {
- (*dPtr->proc)(dPtr->clientData, interp);
- }
- ckfree((char *) dPtr);
- }
- Tcl_DeleteHashTable(hTablePtr);
- ckfree((char *) hTablePtr);
- }
-
- /*
- * Finish deleting the global namespace.
- */
-
+ if (iPtr->framePtr != iPtr->rootFramePtr) {
+ Tcl_Panic("DeleteInterpProc: popping rootCallFrame with other frames on top");
+ }
+ Tcl_PopCallFrame(interp);
+ ckfree((char *) iPtr->rootFramePtr);
+ iPtr->rootFramePtr = NULL;
Tcl_DeleteNamespace((Tcl_Namespace *) iPtr->globalNsPtr);
/*
- * Free up the result *after* deleting variables, since variable
- * deletion could have transferred ownership of the result string
- * to Tcl.
+ * Free up the result *after* deleting variables, since variable deletion
+ * could have transferred ownership of the result string to Tcl.
*/
Tcl_FreeResult(interp);
interp->result = NULL;
Tcl_DecrRefCount(iPtr->objResultPtr);
iPtr->objResultPtr = NULL;
- if (iPtr->errorInfo != NULL) {
- ckfree(iPtr->errorInfo);
- iPtr->errorInfo = NULL;
+ Tcl_DecrRefCount(iPtr->ecVar);
+ if (iPtr->errorCode) {
+ Tcl_DecrRefCount(iPtr->errorCode);
+ iPtr->errorCode = NULL;
+ }
+ Tcl_DecrRefCount(iPtr->eiVar);
+ if (iPtr->errorInfo) {
+ Tcl_DecrRefCount(iPtr->errorInfo);
+ iPtr->errorInfo = NULL;
}
- if (iPtr->errorCode != NULL) {
- ckfree(iPtr->errorCode);
- iPtr->errorCode = NULL;
+ if (iPtr->returnOpts) {
+ Tcl_DecrRefCount(iPtr->returnOpts);
}
if (iPtr->appendResult != NULL) {
ckfree(iPtr->appendResult);
- iPtr->appendResult = NULL;
+ iPtr->appendResult = NULL;
}
TclFreePackageInfo(iPtr);
while (iPtr->tracePtr != NULL) {
- Tcl_DeleteTrace((Tcl_Interp*) iPtr, (Tcl_Trace) iPtr->tracePtr);
+ Tcl_DeleteTrace((Tcl_Interp *) iPtr, (Tcl_Trace) iPtr->tracePtr);
}
if (iPtr->execEnvPtr != NULL) {
TclDeleteExecEnv(iPtr->execEnvPtr);
@@ -1149,9 +1364,9 @@ DeleteInterpProc(interp)
nextResPtr = resPtr->nextPtr;
ckfree(resPtr->name);
ckfree((char *) resPtr);
- resPtr = nextResPtr;
+ resPtr = nextResPtr;
}
-
+
/*
* Free up literal objects created for scripts compiled by the
* interpreter.
@@ -1159,60 +1374,59 @@ DeleteInterpProc(interp)
TclDeleteLiteralTable(interp, &(iPtr->literalTable));
-#ifdef TCL_TIP280
- /* TIP #280 - Release the arrays for ByteCode/Proc extension, and contents.
+ /*
+ * TIP #280 - Release the arrays for ByteCode/Proc extension, and
+ * contents.
*/
+
{
- Tcl_HashEntry *hPtr;
+ Tcl_HashEntry *hPtr;
Tcl_HashSearch hSearch;
- CmdFrame* cfPtr;
- ExtCmdLoc* eclPtr;
- int i;
+ int i;
for (hPtr = Tcl_FirstHashEntry(iPtr->linePBodyPtr, &hSearch);
- hPtr != NULL;
- hPtr = Tcl_NextHashEntry(&hSearch)) {
-
- cfPtr = (CmdFrame*) Tcl_GetHashValue (hPtr);
+ hPtr != NULL;
+ hPtr = Tcl_NextHashEntry(&hSearch)) {
+ CmdFrame *cfPtr = Tcl_GetHashValue(hPtr);
if (cfPtr->type == TCL_LOCATION_SOURCE) {
- Tcl_DecrRefCount (cfPtr->data.eval.path);
+ Tcl_DecrRefCount(cfPtr->data.eval.path);
}
- ckfree ((char*) cfPtr->line);
- ckfree ((char*) cfPtr);
- Tcl_DeleteHashEntry (hPtr);
-
+ ckfree((char *) cfPtr->line);
+ ckfree((char *) cfPtr);
+ Tcl_DeleteHashEntry(hPtr);
}
- Tcl_DeleteHashTable (iPtr->linePBodyPtr);
- ckfree ((char*) iPtr->linePBodyPtr);
+ Tcl_DeleteHashTable(iPtr->linePBodyPtr);
+ ckfree((char *) iPtr->linePBodyPtr);
iPtr->linePBodyPtr = NULL;
- /* See also tclCompile.c, TclCleanupByteCode */
+ /*
+ * See also tclCompile.c, TclCleanupByteCode
+ */
for (hPtr = Tcl_FirstHashEntry(iPtr->lineBCPtr, &hSearch);
- hPtr != NULL;
- hPtr = Tcl_NextHashEntry(&hSearch)) {
-
- eclPtr = (ExtCmdLoc*) Tcl_GetHashValue (hPtr);
+ hPtr != NULL;
+ hPtr = Tcl_NextHashEntry(&hSearch)) {
+ ExtCmdLoc *eclPtr = (ExtCmdLoc *) Tcl_GetHashValue(hPtr);
if (eclPtr->type == TCL_LOCATION_SOURCE) {
- Tcl_DecrRefCount (eclPtr->path);
+ Tcl_DecrRefCount(eclPtr->path);
}
for (i=0; i< eclPtr->nuloc; i++) {
- ckfree ((char*) eclPtr->loc[i].line);
+ ckfree((char *) eclPtr->loc[i].line);
}
- if (eclPtr->loc != NULL) {
- ckfree ((char*) eclPtr->loc);
+ if (eclPtr->loc != NULL) {
+ ckfree((char *) eclPtr->loc);
}
Tcl_DeleteHashTable (&eclPtr->litInfo);
- ckfree ((char*) eclPtr);
- Tcl_DeleteHashEntry (hPtr);
+ ckfree((char *) eclPtr);
+ Tcl_DeleteHashEntry(hPtr);
}
- Tcl_DeleteHashTable (iPtr->lineBCPtr);
- ckfree((char*) iPtr->lineBCPtr);
+ Tcl_DeleteHashTable(iPtr->lineBCPtr);
+ ckfree((char *) iPtr->lineBCPtr);
iPtr->lineBCPtr = NULL;
/*
@@ -1248,7 +1462,10 @@ DeleteInterpProc(interp)
ckfree((char*) iPtr->lineLABCPtr);
iPtr->lineLABCPtr = NULL;
}
-#endif
+
+ Tcl_DeleteHashTable(&iPtr->varTraces);
+ Tcl_DeleteHashTable(&iPtr->varSearches);
+
ckfree((char *) iPtr);
}
@@ -1257,79 +1474,77 @@ DeleteInterpProc(interp)
*
* Tcl_HideCommand --
*
- * Makes a command hidden so that it cannot be invoked from within
- * an interpreter, only from within an ancestor.
+ * Makes a command hidden so that it cannot be invoked from within an
+ * interpreter, only from within an ancestor.
*
* Results:
- * A standard Tcl result; also leaves a message in the interp's result
- * if an error occurs.
+ * A standard Tcl result; also leaves a message in the interp's result if
+ * an error occurs.
*
* Side effects:
- * Removes a command from the command table and create an entry
- * into the hidden command table under the specified token name.
+ * Removes a command from the command table and create an entry into the
+ * hidden command table under the specified token name.
*
*---------------------------------------------------------------------------
*/
int
-Tcl_HideCommand(interp, cmdName, hiddenCmdToken)
- Tcl_Interp *interp; /* Interpreter in which to hide command. */
- CONST char *cmdName; /* Name of command to hide. */
- CONST char *hiddenCmdToken; /* Token name of the to-be-hidden command. */
+Tcl_HideCommand(
+ Tcl_Interp *interp, /* Interpreter in which to hide command. */
+ const char *cmdName, /* Name of command to hide. */
+ const char *hiddenCmdToken) /* Token name of the to-be-hidden command. */
{
Interp *iPtr = (Interp *) interp;
Tcl_Command cmd;
Command *cmdPtr;
Tcl_HashTable *hiddenCmdTablePtr;
Tcl_HashEntry *hPtr;
- int new;
+ int isNew;
if (iPtr->flags & DELETED) {
+ /*
+ * The interpreter is being deleted. Do not create any new structures,
+ * because it is not safe to modify the interpreter.
+ */
- /*
- * The interpreter is being deleted. Do not create any new
- * structures, because it is not safe to modify the interpreter.
- */
-
- return TCL_ERROR;
+ return TCL_ERROR;
}
/*
* Disallow hiding of commands that are currently in a namespace or
- * renaming (as part of hiding) into a namespace.
- *
- * (because the current implementation with a single global table
- * and the needed uniqueness of names cause problems with namespaces)
+ * renaming (as part of hiding) into a namespace (because the current
+ * implementation with a single global table and the needed uniqueness of
+ * names cause problems with namespaces).
*
- * we don't need to check for "::" in cmdName because the real check is
- * on the nsPtr below.
+ * We don't need to check for "::" in cmdName because the real check is on
+ * the nsPtr below.
*
- * hiddenCmdToken is just a string which is not interpreted in any way.
- * It may contain :: but the string is not interpreted as a namespace
+ * hiddenCmdToken is just a string which is not interpreted in any way. It
+ * may contain :: but the string is not interpreted as a namespace
* qualifier command name. Thus, hiding foo::bar to foo::bar and then
* trying to expose or invoke ::foo::bar will NOT work; but if the
* application always uses the same strings it will get consistent
* behaviour.
*
- * But as we currently limit ourselves to the global namespace only
- * for the source, in order to avoid potential confusion,
- * lets prevent "::" in the token too. --dl
+ * But as we currently limit ourselves to the global namespace only for
+ * the source, in order to avoid potential confusion, lets prevent "::" in
+ * the token too. - dl
*/
if (strstr(hiddenCmdToken, "::") != NULL) {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "cannot use namespace qualifiers in hidden command",
- " token (rename)", (char *) NULL);
- return TCL_ERROR;
+ Tcl_AppendResult(interp,
+ "cannot use namespace qualifiers in hidden command"
+ " token (rename)", NULL);
+ return TCL_ERROR;
}
/*
- * Find the command to hide. An error is returned if cmdName can't
- * be found. Look up the command only from the global namespace.
- * Full path of the command must be given if using namespaces.
+ * Find the command to hide. An error is returned if cmdName can't be
+ * found. Look up the command only from the global namespace. Full path of
+ * the command must be given if using namespaces.
*/
- cmd = Tcl_FindCommand(interp, cmdName, (Tcl_Namespace *) NULL,
+ cmd = Tcl_FindCommand(interp, cmdName, NULL,
/*flags*/ TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
if (cmd == (Tcl_Command) NULL) {
return TCL_ERROR;
@@ -1340,22 +1555,21 @@ Tcl_HideCommand(interp, cmdName, hiddenCmdToken)
* Check that the command is really in global namespace
*/
- if ( cmdPtr->nsPtr != iPtr->globalNsPtr ) {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "can only hide global namespace commands",
- " (use rename then hide)", (char *) NULL);
- return TCL_ERROR;
+ if (cmdPtr->nsPtr != iPtr->globalNsPtr) {
+ Tcl_AppendResult(interp, "can only hide global namespace commands"
+ " (use rename then hide)", NULL);
+ return TCL_ERROR;
}
-
+
/*
* Initialize the hidden command table if necessary.
*/
hiddenCmdTablePtr = iPtr->hiddenCmdTablePtr;
if (hiddenCmdTablePtr == NULL) {
- hiddenCmdTablePtr = (Tcl_HashTable *)
- ckalloc((unsigned) sizeof(Tcl_HashTable));
- Tcl_InitHashTable(hiddenCmdTablePtr, TCL_STRING_KEYS);
+ hiddenCmdTablePtr = (Tcl_HashTable *)
+ ckalloc((unsigned) sizeof(Tcl_HashTable));
+ Tcl_InitHashTable(hiddenCmdTablePtr, TCL_STRING_KEYS);
iPtr->hiddenCmdTablePtr = hiddenCmdTablePtr;
}
@@ -1364,20 +1578,18 @@ Tcl_HideCommand(interp, cmdName, hiddenCmdToken)
* hiddenCmdToken if a hidden command with the name hiddenCmdToken already
* exists.
*/
-
- hPtr = Tcl_CreateHashEntry(hiddenCmdTablePtr, hiddenCmdToken, &new);
- if (!new) {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "hidden command named \"", hiddenCmdToken, "\" already exists",
- (char *) NULL);
- return TCL_ERROR;
+
+ hPtr = Tcl_CreateHashEntry(hiddenCmdTablePtr, hiddenCmdToken, &isNew);
+ if (!isNew) {
+ Tcl_AppendResult(interp, "hidden command named \"", hiddenCmdToken,
+ "\" already exists", NULL);
+ return TCL_ERROR;
}
/*
- * Nb : This code is currently 'like' a rename to a specialy set apart
- * name table. Changes here and in TclRenameCommand must
- * be kept in synch untill the common parts are actually
- * factorized out.
+ * NB: This code is currently 'like' a rename to a specialy set apart name
+ * table. Changes here and in TclRenameCommand must be kept in synch until
+ * the common parts are actually factorized out.
*/
/*
@@ -1387,26 +1599,34 @@ Tcl_HideCommand(interp, cmdName, hiddenCmdToken)
*/
if (cmdPtr->hPtr != NULL) {
- Tcl_DeleteHashEntry(cmdPtr->hPtr);
- cmdPtr->hPtr = (Tcl_HashEntry *) NULL;
+ Tcl_DeleteHashEntry(cmdPtr->hPtr);
+ cmdPtr->hPtr = NULL;
cmdPtr->cmdEpoch++;
}
/*
- * Now link the hash table entry with the command structure.
- * We ensured above that the nsPtr was right.
+ * 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.
*/
-
+
+ TclInvalidateNsCmdLookup(cmdPtr->nsPtr);
+
+ /*
+ * Now link the hash table entry with the command structure. We ensured
+ * above that the nsPtr was right.
+ */
+
cmdPtr->hPtr = hPtr;
- Tcl_SetHashValue(hPtr, (ClientData) cmdPtr);
+ Tcl_SetHashValue(hPtr, cmdPtr);
/*
- * If the command being hidden has a compile procedure, increment the
- * interpreter's compileEpoch to invalidate its compiled code. This
- * makes sure that we don't later try to execute old code compiled with
- * command-specific (i.e., inline) bytecodes for the now-hidden
- * command. This field is checked in Tcl_EvalObj and ObjInterpProc,
- * and code whose compilation epoch doesn't match is recompiled.
+ * If the command being hidden has a compile function, increment the
+ * interpreter's compileEpoch to invalidate its compiled code. This makes
+ * sure that we don't later try to execute old code compiled with
+ * command-specific (i.e., inline) bytecodes for the now-hidden command.
+ * This field is checked in Tcl_EvalObj and ObjInterpProc, and code whose
+ * compilation epoch doesn't match is recompiled.
*/
if (cmdPtr->compileProc != NULL) {
@@ -1420,12 +1640,12 @@ Tcl_HideCommand(interp, cmdName, hiddenCmdToken)
*
* Tcl_ExposeCommand --
*
- * Makes a previously hidden command callable from inside the
- * interpreter instead of only by its ancestors.
+ * Makes a previously hidden command callable from inside the interpreter
+ * instead of only by its ancestors.
*
* Results:
- * A standard Tcl result. If an error occurs, a message is left
- * in the interp's result.
+ * A standard Tcl result. If an error occurs, a message is left in the
+ * interp's result.
*
* Side effects:
* Moves commands from one hash table to another.
@@ -1434,40 +1654,38 @@ Tcl_HideCommand(interp, cmdName, hiddenCmdToken)
*/
int
-Tcl_ExposeCommand(interp, hiddenCmdToken, cmdName)
- Tcl_Interp *interp; /* Interpreter in which to make command
- * callable. */
- CONST char *hiddenCmdToken; /* Name of hidden command. */
- CONST char *cmdName; /* Name of to-be-exposed command. */
+Tcl_ExposeCommand(
+ Tcl_Interp *interp, /* Interpreter in which to make command
+ * callable. */
+ const char *hiddenCmdToken, /* Name of hidden command. */
+ const char *cmdName) /* Name of to-be-exposed command. */
{
Interp *iPtr = (Interp *) interp;
Command *cmdPtr;
Namespace *nsPtr;
Tcl_HashEntry *hPtr;
Tcl_HashTable *hiddenCmdTablePtr;
- int new;
+ int isNew;
if (iPtr->flags & DELETED) {
- /*
- * The interpreter is being deleted. Do not create any new
- * structures, because it is not safe to modify the interpreter.
- */
-
- return TCL_ERROR;
+ /*
+ * The interpreter is being deleted. Do not create any new structures,
+ * because it is not safe to modify the interpreter.
+ */
+
+ return TCL_ERROR;
}
/*
- * Check that we have a regular name for the command
- * (that the user is not trying to do an expose and a rename
- * (to another namespace) at the same time)
+ * Check that we have a regular name for the command (that the user is not
+ * trying to do an expose and a rename (to another namespace) at the same
+ * time).
*/
if (strstr(cmdName, "::") != NULL) {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "can not expose to a namespace ",
- "(use expose to toplevel, then rename)",
- (char *) NULL);
- return TCL_ERROR;
+ Tcl_AppendResult(interp, "cannot expose to a namespace "
+ "(use expose to toplevel, then rename)", NULL);
+ return TCL_ERROR;
}
/*
@@ -1479,82 +1697,90 @@ Tcl_ExposeCommand(interp, hiddenCmdToken, cmdName)
if (hiddenCmdTablePtr != NULL) {
hPtr = Tcl_FindHashEntry(hiddenCmdTablePtr, hiddenCmdToken);
}
- if (hPtr == (Tcl_HashEntry *) NULL) {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "unknown hidden command \"", hiddenCmdToken,
- "\"", (char *) NULL);
- return TCL_ERROR;
+ if (hPtr == NULL) {
+ Tcl_AppendResult(interp, "unknown hidden command \"", hiddenCmdToken,
+ "\"", NULL);
+ return TCL_ERROR;
}
- cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
-
+ cmdPtr = Tcl_GetHashValue(hPtr);
/*
- * Check that we have a true global namespace
- * command (enforced by Tcl_HideCommand() but let's double
- * check. (If it was not, we would not really know how to
- * handle it).
+ * Check that we have a true global namespace command (enforced by
+ * Tcl_HideCommand() but let's double check. (If it was not, we would not
+ * really know how to handle it).
*/
- if ( cmdPtr->nsPtr != iPtr->globalNsPtr ) {
- /*
- * This case is theoritically impossible,
- * we might rather panic() than 'nicely' erroring out ?
+
+ if (cmdPtr->nsPtr != iPtr->globalNsPtr) {
+ /*
+ * This case is theoritically impossible, we might rather Tcl_Panic()
+ * than 'nicely' erroring out ?
*/
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "trying to expose a non global command name space command",
- (char *) NULL);
- return TCL_ERROR;
+
+ Tcl_AppendResult(interp,
+ "trying to expose a non global command name space command",
+ NULL);
+ return TCL_ERROR;
}
-
- /* This is the global table */
+
+ /*
+ * This is the global table.
+ */
+
nsPtr = cmdPtr->nsPtr;
/*
- * It is an error to overwrite an existing exposed command as a result
- * of exposing a previously hidden command.
+ * It is an error to overwrite an existing exposed command as a result of
+ * exposing a previously hidden command.
*/
- hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, cmdName, &new);
- if (!new) {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "exposed command \"", cmdName,
- "\" already exists", (char *) NULL);
- return TCL_ERROR;
+ hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, cmdName, &isNew);
+ if (!isNew) {
+ Tcl_AppendResult(interp, "exposed command \"", cmdName,
+ "\" already exists", NULL);
+ return TCL_ERROR;
}
/*
+ * 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.
+ */
+
+ TclInvalidateNsCmdLookup(nsPtr);
+
+ /*
* Remove the hash entry for the command from the interpreter hidden
* command table.
*/
if (cmdPtr->hPtr != NULL) {
- Tcl_DeleteHashEntry(cmdPtr->hPtr);
- cmdPtr->hPtr = NULL;
+ Tcl_DeleteHashEntry(cmdPtr->hPtr);
+ cmdPtr->hPtr = NULL;
}
/*
- * Now link the hash table entry with the command structure.
- * This is like creating a new command, so deal with any shadowing
- * of commands in the global namespace.
+ * Now link the hash table entry with the command structure. This is like
+ * creating a new command, so deal with any shadowing of commands in the
+ * global namespace.
*/
-
+
cmdPtr->hPtr = hPtr;
- Tcl_SetHashValue(hPtr, (ClientData) cmdPtr);
+ Tcl_SetHashValue(hPtr, cmdPtr);
/*
- * Not needed as we are only in the global namespace
- * (but would be needed again if we supported namespace command hiding)
+ * Not needed as we are only in the global namespace (but would be needed
+ * again if we supported namespace command hiding)
*
* TclResetShadowedCmdRefs(interp, cmdPtr);
*/
-
/*
- * If the command being exposed has a compile procedure, increment
- * interpreter's compileEpoch to invalidate its compiled code. This
- * makes sure that we don't later try to execute old code compiled
- * assuming the command is hidden. This field is checked in Tcl_EvalObj
- * and ObjInterpProc, and code whose compilation epoch doesn't match is
+ * If the command being exposed has a compile function, increment
+ * interpreter's compileEpoch to invalidate its compiled code. This makes
+ * sure that we don't later try to execute old code compiled assuming the
+ * command is hidden. This field is checked in Tcl_EvalObj and
+ * ObjInterpProc, and code whose compilation epoch doesn't match is
* recompiled.
*/
@@ -1572,94 +1798,103 @@ Tcl_ExposeCommand(interp, hiddenCmdToken, cmdName)
* Define a new command in a command table.
*
* Results:
- * The return value is a token for the command, which can
- * be used in future calls to Tcl_GetCommandName.
+ * The return value is a token for the command, which can be used in
+ * future calls to Tcl_GetCommandName.
*
* Side effects:
* If a command named cmdName already exists for interp, it is deleted.
* In the future, when cmdName is seen as the name of a command by
* Tcl_Eval, proc will be called. To support the bytecode interpreter,
* the command is created with a wrapper Tcl_ObjCmdProc
- * (TclInvokeStringCommand) that eventially calls proc. When the
- * command is deleted from the table, deleteProc will be called.
- * See the manual entry for details on the calling sequence.
+ * (TclInvokeStringCommand) that eventially calls proc. When the command
+ * is deleted from the table, deleteProc will be called. See the manual
+ * entry for details on the calling sequence.
*
*----------------------------------------------------------------------
*/
Tcl_Command
-Tcl_CreateCommand(interp, cmdName, proc, clientData, deleteProc)
- Tcl_Interp *interp; /* Token for command interpreter returned by
- * a previous call to Tcl_CreateInterp. */
- CONST char *cmdName; /* Name of command. If it contains namespace
+Tcl_CreateCommand(
+ Tcl_Interp *interp, /* Token for command interpreter returned by a
+ * previous call to Tcl_CreateInterp. */
+ const char *cmdName, /* Name of command. If it contains namespace
* qualifiers, the new command is put in the
- * specified namespace; otherwise it is put
- * in the global namespace. */
- Tcl_CmdProc *proc; /* Procedure to associate with cmdName. */
- ClientData clientData; /* Arbitrary value passed to string proc. */
- Tcl_CmdDeleteProc *deleteProc;
- /* If not NULL, gives a procedure to call
- * when this command is deleted. */
+ * specified namespace; otherwise it is put in
+ * the global namespace. */
+ Tcl_CmdProc *proc, /* Function to associate with cmdName. */
+ ClientData clientData, /* Arbitrary value passed to string proc. */
+ Tcl_CmdDeleteProc *deleteProc)
+ /* If not NULL, gives a function to call when
+ * this command is deleted. */
{
Interp *iPtr = (Interp *) interp;
ImportRef *oldRefPtr = NULL;
Namespace *nsPtr, *dummy1, *dummy2;
Command *cmdPtr, *refCmdPtr;
Tcl_HashEntry *hPtr;
- CONST char *tail;
- int new;
+ const char *tail;
+ int isNew;
ImportedCmdData *dataPtr;
if (iPtr->flags & DELETED) {
/*
- * The interpreter is being deleted. Don't create any new
- * commands; it's not safe to muck with the interpreter anymore.
+ * The interpreter is being deleted. Don't create any new commands;
+ * it's not safe to muck with the interpreter anymore.
*/
return (Tcl_Command) NULL;
}
/*
- * Determine where the command should reside. If its name contains
- * namespace qualifiers, we put it in the specified namespace;
- * otherwise, we always put it in the global namespace.
+ * Determine where the command should reside. If its name contains
+ * namespace qualifiers, we put it in the specified namespace; otherwise,
+ * we always put it in the global namespace.
*/
if (strstr(cmdName, "::") != NULL) {
- TclGetNamespaceForQualName(interp, cmdName, (Namespace *) NULL,
- CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
- if ((nsPtr == NULL) || (tail == NULL)) {
+ TclGetNamespaceForQualName(interp, cmdName, NULL,
+ TCL_CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
+ if ((nsPtr == NULL) || (tail == NULL)) {
return (Tcl_Command) NULL;
}
} else {
nsPtr = iPtr->globalNsPtr;
tail = cmdName;
}
-
- hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
- if (!new) {
+
+ hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
+ if (!isNew) {
/*
- * Command already exists. Delete the old one.
- * Be careful to preserve any existing import links so we can
- * restore them down below. That way, you can redefine a
- * command and its import status will remain intact.
+ * Command already exists. Delete the old one. Be careful to preserve
+ * any existing import links so we can restore them down below. That
+ * way, you can redefine a command and its import status will remain
+ * intact.
*/
- cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
+ cmdPtr = Tcl_GetHashValue(hPtr);
oldRefPtr = cmdPtr->importRefPtr;
cmdPtr->importRefPtr = NULL;
Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
- hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
- if (!new) {
+ hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
+ if (!isNew) {
/*
- * If the deletion callback recreated the command, just throw
- * away the new command (if we try to delete it again, we
- * could get stuck in an infinite loop).
+ * If the deletion callback recreated the command, just throw away
+ * the new command (if we try to delete it again, we could get
+ * stuck in an infinite loop).
*/
- ckfree((char*) Tcl_GetHashValue(hPtr));
+ ckfree((char *) Tcl_GetHashValue(hPtr));
}
+ } else {
+ /*
+ * 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.
+ */
+
+ TclInvalidateNsCmdLookup(nsPtr);
+ TclInvalidateNsPath(nsPtr);
}
cmdPtr = (Command *) ckalloc(sizeof(Command));
Tcl_SetHashValue(hPtr, cmdPtr);
@@ -1667,9 +1902,9 @@ Tcl_CreateCommand(interp, cmdName, proc, clientData, deleteProc)
cmdPtr->nsPtr = nsPtr;
cmdPtr->refCount = 1;
cmdPtr->cmdEpoch = 0;
- cmdPtr->compileProc = (CompileProc *) NULL;
+ cmdPtr->compileProc = NULL;
cmdPtr->objProc = TclInvokeStringCommand;
- cmdPtr->objClientData = (ClientData) cmdPtr;
+ cmdPtr->objClientData = cmdPtr;
cmdPtr->proc = proc;
cmdPtr->clientData = clientData;
cmdPtr->deleteProc = deleteProc;
@@ -1679,15 +1914,15 @@ Tcl_CreateCommand(interp, cmdName, proc, clientData, deleteProc)
cmdPtr->tracePtr = NULL;
/*
- * Plug in any existing import references found above. Be sure
- * to update all of these references to point to the new command.
+ * Plug in any existing import references found above. Be sure to update
+ * all of these references to point to the new command.
*/
if (oldRefPtr != NULL) {
cmdPtr->importRefPtr = oldRefPtr;
while (oldRefPtr != NULL) {
refCmdPtr = oldRefPtr->importedCmdPtr;
- dataPtr = (ImportedCmdData*)refCmdPtr->objClientData;
+ dataPtr = refCmdPtr->objClientData;
dataPtr->realCmdPtr = cmdPtr;
oldRefPtr = oldRefPtr->nextPtr;
}
@@ -1699,7 +1934,7 @@ Tcl_CreateCommand(interp, cmdName, proc, clientData, deleteProc)
* shadowed commands are found, invalidate all cached command references
* in the affected namespaces.
*/
-
+
TclResetShadowedCmdRefs(interp, cmdPtr);
return (Tcl_Command) cmdPtr;
}
@@ -1712,70 +1947,70 @@ Tcl_CreateCommand(interp, cmdName, proc, clientData, deleteProc)
* Define a new object-based command in a command table.
*
* Results:
- * The return value is a token for the command, which can
- * be used in future calls to Tcl_GetCommandName.
+ * The return value is a token for the command, which can be used in
+ * 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.
+ * 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.
*
* 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
* Tcl_ObjCmdProc proc will be called. When the command is deleted from
- * the table, deleteProc will be called. See the manual entry for
- * details on the calling sequence.
+ * the table, deleteProc will be called. See the manual entry for details
+ * on the calling sequence.
*
*----------------------------------------------------------------------
*/
Tcl_Command
-Tcl_CreateObjCommand(interp, cmdName, proc, clientData, deleteProc)
- Tcl_Interp *interp; /* Token for command interpreter (returned
- * by previous call to Tcl_CreateInterp). */
- CONST char *cmdName; /* Name of command. If it contains namespace
+Tcl_CreateObjCommand(
+ Tcl_Interp *interp, /* Token for command interpreter (returned by
+ * previous call to Tcl_CreateInterp). */
+ const char *cmdName, /* Name of command. If it contains namespace
* qualifiers, the new command is put in the
- * specified namespace; otherwise it is put
- * in the global namespace. */
- Tcl_ObjCmdProc *proc; /* Object-based procedure to associate with
+ * specified namespace; otherwise it is put in
+ * the global namespace. */
+ Tcl_ObjCmdProc *proc, /* Object-based function to associate with
* name. */
- ClientData clientData; /* Arbitrary value to pass to object
- * procedure. */
- Tcl_CmdDeleteProc *deleteProc;
- /* If not NULL, gives a procedure to call
- * when this command is deleted. */
+ ClientData clientData, /* Arbitrary value to pass to object
+ * function. */
+ Tcl_CmdDeleteProc *deleteProc)
+ /* If not NULL, gives a function to call when
+ * this command is deleted. */
{
Interp *iPtr = (Interp *) interp;
ImportRef *oldRefPtr = NULL;
Namespace *nsPtr, *dummy1, *dummy2;
Command *cmdPtr, *refCmdPtr;
Tcl_HashEntry *hPtr;
- CONST char *tail;
- int new;
+ const char *tail;
+ int isNew;
ImportedCmdData *dataPtr;
if (iPtr->flags & DELETED) {
/*
- * The interpreter is being deleted. Don't create any new
- * commands; it's not safe to muck with the interpreter anymore.
+ * The interpreter is being deleted. Don't create any new commands;
+ * it's not safe to muck with the interpreter anymore.
*/
return (Tcl_Command) NULL;
}
/*
- * Determine where the command should reside. If its name contains
- * namespace qualifiers, we put it in the specified namespace;
- * otherwise, we always put it in the global namespace.
+ * Determine where the command should reside. If its name contains
+ * namespace qualifiers, we put it in the specified namespace; otherwise,
+ * we always put it in the global namespace.
*/
if (strstr(cmdName, "::") != NULL) {
- TclGetNamespaceForQualName(interp, cmdName, (Namespace *) NULL,
- CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
- if ((nsPtr == NULL) || (tail == NULL)) {
+ TclGetNamespaceForQualName(interp, cmdName, NULL,
+ TCL_CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
+ if ((nsPtr == NULL) || (tail == NULL)) {
return (Tcl_Command) NULL;
}
} else {
@@ -1783,45 +2018,54 @@ Tcl_CreateObjCommand(interp, cmdName, proc, clientData, deleteProc)
tail = cmdName;
}
- hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
- if (!new) {
- cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
+ hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
+ TclInvalidateNsPath(nsPtr);
+ if (!isNew) {
+ cmdPtr = Tcl_GetHashValue(hPtr);
/*
* 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.
+ * argument "proc". Otherwise, we delete the old command.
*/
if (cmdPtr->objProc == TclInvokeStringCommand) {
cmdPtr->objProc = proc;
cmdPtr->objClientData = clientData;
- cmdPtr->deleteProc = deleteProc;
- cmdPtr->deleteData = clientData;
+ cmdPtr->deleteProc = deleteProc;
+ cmdPtr->deleteData = clientData;
return (Tcl_Command) cmdPtr;
}
/*
- * Otherwise, we delete the old command. Be careful to preserve
- * any existing import links so we can restore them down below.
- * That way, you can redefine a command and its import status
- * will remain intact.
+ * Otherwise, we delete the old command. Be careful to preserve any
+ * existing import links so we can restore them down below. That way,
+ * you can redefine a command and its import status will remain
+ * intact.
*/
oldRefPtr = cmdPtr->importRefPtr;
cmdPtr->importRefPtr = NULL;
Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
- hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &new);
- if (!new) {
+ hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
+ if (!isNew) {
/*
- * If the deletion callback recreated the command, just throw
- * away the new command (if we try to delete it again, we
- * could get stuck in an infinite loop).
+ * If the deletion callback recreated the command, just throw away
+ * the new command (if we try to delete it again, we could get
+ * stuck in an infinite loop).
*/
- ckfree((char *) Tcl_GetHashValue(hPtr));
+ ckfree(Tcl_GetHashValue(hPtr));
}
+ } else {
+ /*
+ * 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.
+ */
+
+ TclInvalidateNsCmdLookup(nsPtr);
}
cmdPtr = (Command *) ckalloc(sizeof(Command));
Tcl_SetHashValue(hPtr, cmdPtr);
@@ -1829,11 +2073,11 @@ Tcl_CreateObjCommand(interp, cmdName, proc, clientData, deleteProc)
cmdPtr->nsPtr = nsPtr;
cmdPtr->refCount = 1;
cmdPtr->cmdEpoch = 0;
- cmdPtr->compileProc = (CompileProc *) NULL;
+ cmdPtr->compileProc = NULL;
cmdPtr->objProc = proc;
cmdPtr->objClientData = clientData;
cmdPtr->proc = TclInvokeObjectCommand;
- cmdPtr->clientData = (ClientData) cmdPtr;
+ cmdPtr->clientData = cmdPtr;
cmdPtr->deleteProc = deleteProc;
cmdPtr->deleteData = clientData;
cmdPtr->flags = 0;
@@ -1841,27 +2085,27 @@ Tcl_CreateObjCommand(interp, cmdName, proc, clientData, deleteProc)
cmdPtr->tracePtr = NULL;
/*
- * Plug in any existing import references found above. Be sure
- * to update all of these references to point to the new command.
+ * Plug in any existing import references found above. Be sure to update
+ * all of these references to point to the new command.
*/
if (oldRefPtr != NULL) {
cmdPtr->importRefPtr = oldRefPtr;
while (oldRefPtr != NULL) {
refCmdPtr = oldRefPtr->importedCmdPtr;
- dataPtr = (ImportedCmdData*)refCmdPtr->objClientData;
+ dataPtr = refCmdPtr->objClientData;
dataPtr->realCmdPtr = cmdPtr;
oldRefPtr = oldRefPtr->nextPtr;
}
}
-
+
/*
* We just created a command, so in its namespace and all of its parent
* namespaces, it may shadow global commands with the same name. If any
* shadowed commands are found, invalidate all cached command references
* in the affected namespaces.
*/
-
+
TclResetShadowedCmdRefs(interp, cmdPtr);
return (Tcl_Command) cmdPtr;
}
@@ -1872,10 +2116,10 @@ Tcl_CreateObjCommand(interp, cmdName, proc, clientData, deleteProc)
* TclInvokeStringCommand --
*
* "Wrapper" Tcl_ObjCmdProc used to call an existing string-based
- * Tcl_CmdProc if no object-based procedure exists for a command. A
- * pointer to this procedure is stored as the Tcl_ObjCmdProc in a
- * Command structure. It simply turns around and calls the string
- * Tcl_CmdProc in the Command structure.
+ * Tcl_CmdProc if no object-based function exists for a command. A
+ * pointer to this function is stored as the Tcl_ObjCmdProc in a Command
+ * structure. It simply turns around and calls the string Tcl_CmdProc in
+ * the Command structure.
*
* Results:
* A standard Tcl object result value.
@@ -1888,35 +2132,16 @@ Tcl_CreateObjCommand(interp, cmdName, proc, clientData, deleteProc)
*/
int
-TclInvokeStringCommand(clientData, interp, objc, objv)
- ClientData clientData; /* Points to command's Command structure. */
- Tcl_Interp *interp; /* Current interpreter. */
- register int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+TclInvokeStringCommand(
+ ClientData clientData, /* Points to command's Command structure. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ register int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- register Command *cmdPtr = (Command *) clientData;
- register int i;
- int result;
-
- /*
- * This procedure generates an argv array for the string arguments. It
- * starts out with stack-allocated space but uses dynamically-allocated
- * storage if needed.
- */
-
-#define NUM_ARGS 20
- CONST char *(argStorage[NUM_ARGS]);
- CONST char **argv = argStorage;
-
- /*
- * Create the string argument array "argv". Make sure argv is large
- * enough to hold the objc arguments plus 1 extra for the zero
- * end-of-argv word.
- */
-
- if ((objc + 1) > NUM_ARGS) {
- argv = (CONST char **) ckalloc((unsigned)(objc + 1) * sizeof(char *));
- }
+ Command *cmdPtr = clientData;
+ int i, result;
+ const char **argv = (const char **)
+ TclStackAlloc(interp, (unsigned)(objc + 1) * sizeof(char *));
for (i = 0; i < objc; i++) {
argv[i] = Tcl_GetString(objv[i]);
@@ -1929,15 +2154,8 @@ TclInvokeStringCommand(clientData, interp, objc, objv)
result = (*cmdPtr->proc)(cmdPtr->clientData, interp, objc, argv);
- /*
- * Free the argv array if malloc'ed storage was used.
- */
-
- if (argv != argStorage) {
- ckfree((char *) argv);
- }
+ TclStackFree(interp, (void *) argv);
return result;
-#undef NUM_ARGS
}
/*
@@ -1946,10 +2164,10 @@ TclInvokeStringCommand(clientData, interp, objc, objv)
* TclInvokeObjectCommand --
*
* "Wrapper" Tcl_CmdProc used to call an existing object-based
- * Tcl_ObjCmdProc if no string-based procedure exists for a command.
- * A pointer to this procedure is stored as the Tcl_CmdProc in a
- * Command structure. It simply turns around and calls the object
- * Tcl_ObjCmdProc in the Command structure.
+ * Tcl_ObjCmdProc if no string-based function exists for a command. A
+ * pointer to this function is stored as the Tcl_CmdProc in a Command
+ * structure. It simply turns around and calls the object Tcl_ObjCmdProc
+ * in the Command structure.
*
* Results:
* A standard Tcl string result value.
@@ -1962,42 +2180,21 @@ TclInvokeStringCommand(clientData, interp, objc, objv)
*/
int
-TclInvokeObjectCommand(clientData, interp, argc, argv)
- ClientData clientData; /* Points to command's Command structure. */
- Tcl_Interp *interp; /* Current interpreter. */
- int argc; /* Number of arguments. */
- register CONST char **argv; /* Argument strings. */
+TclInvokeObjectCommand(
+ ClientData clientData, /* Points to command's Command structure. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int argc, /* Number of arguments. */
+ register const char **argv) /* Argument strings. */
{
Command *cmdPtr = (Command *) clientData;
- register Tcl_Obj *objPtr;
- register int i;
- int length, result;
-
- /*
- * This procedure generates an objv array for object arguments that hold
- * the argv strings. It starts out with stack-allocated space but uses
- * dynamically-allocated storage if needed.
- */
-
-#define NUM_ARGS 20
- Tcl_Obj *(argStorage[NUM_ARGS]);
- register Tcl_Obj **objv = argStorage;
-
- /*
- * Create the object argument array "objv". Make sure objv is large
- * enough to hold the objc arguments plus 1 extra for the zero
- * end-of-objv word.
- */
-
- if (argc > NUM_ARGS) {
- objv = (Tcl_Obj **)
- ckalloc((unsigned)(argc * sizeof(Tcl_Obj *)));
- }
+ Tcl_Obj *objPtr;
+ int i, length, result;
+ Tcl_Obj **objv = (Tcl_Obj **)
+ TclStackAlloc(interp, (unsigned)(argc * sizeof(Tcl_Obj *)));
for (i = 0; i < argc; i++) {
length = strlen(argv[i]);
- TclNewObj(objPtr);
- TclInitStringRep(objPtr, argv[i], length);
+ TclNewStringObj(objPtr, argv[i], length);
Tcl_IncrRefCount(objPtr);
objv[i] = objPtr;
}
@@ -2009,27 +2206,23 @@ TclInvokeObjectCommand(clientData, interp, argc, argv)
result = (*cmdPtr->objProc)(cmdPtr->objClientData, interp, argc, objv);
/*
- * Move the interpreter's object result to the string result,
- * then reset the object result.
+ * Move the interpreter's object result to the string result, then reset
+ * the object result.
*/
- Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
- TCL_VOLATILE);
-
+ (void) Tcl_GetStringResult(interp);
+
/*
- * Decrement the ref counts for the argument objects created above,
- * then free the objv array if malloc'ed storage was used.
+ * Decrement the ref counts for the argument objects created above, then
+ * free the objv array if malloc'ed storage was used.
*/
for (i = 0; i < argc; i++) {
objPtr = objv[i];
Tcl_DecrRefCount(objPtr);
}
- if (objv != argStorage) {
- ckfree((char *) objv);
- }
+ TclStackFree(interp, objv);
return result;
-#undef NUM_ARGS
}
/*
@@ -2037,65 +2230,64 @@ TclInvokeObjectCommand(clientData, interp, argc, argv)
*
* TclRenameCommand --
*
- * Called to give an existing Tcl command a different name. Both the
- * old command name and the new command name can have "::" namespace
- * qualifiers. If the new command has a different namespace context,
- * the command will be moved to that namespace and will execute in
- * the context of that new namespace.
+ * Called to give an existing Tcl command a different name. Both the old
+ * command name and the new command name can have "::" namespace
+ * qualifiers. If the new command has a different namespace context, the
+ * command will be moved to that namespace and will execute in the
+ * context of that new namespace.
*
- * If the new command name is NULL or the null string, the command is
- * deleted.
+ * If the new command name is NULL or the null string, the command is
+ * deleted.
*
* Results:
- * Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
+ * Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
*
* Side effects:
- * If anything goes wrong, an error message is returned in the
- * interpreter's result object.
+ * If anything goes wrong, an error message is returned in the
+ * interpreter's result object.
*
*----------------------------------------------------------------------
*/
int
-TclRenameCommand(interp, oldName, newName)
- Tcl_Interp *interp; /* Current interpreter. */
- char *oldName; /* Existing command name. */
- char *newName; /* New command name. */
+TclRenameCommand(
+ Tcl_Interp *interp, /* Current interpreter. */
+ const char *oldName, /* Existing command name. */
+ const char *newName) /* New command name. */
{
Interp *iPtr = (Interp *) interp;
- CONST char *newTail;
+ const char *newTail;
Namespace *cmdNsPtr, *newNsPtr, *dummy1, *dummy2;
Tcl_Command cmd;
Command *cmdPtr;
Tcl_HashEntry *hPtr, *oldHPtr;
- int new, result;
- Tcl_Obj* oldFullName;
+ int isNew, result;
+ Tcl_Obj *oldFullName;
Tcl_DString newFullName;
/*
- * Find the existing command. An error is returned if cmdName can't
- * be found.
+ * Find the existing command. An error is returned if cmdName can't be
+ * found.
*/
- cmd = Tcl_FindCommand(interp, oldName, (Tcl_Namespace *) NULL,
- /*flags*/ 0);
+ cmd = Tcl_FindCommand(interp, oldName, NULL, /*flags*/ 0);
cmdPtr = (Command *) cmd;
if (cmdPtr == NULL) {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "can't ",
- ((newName == NULL)||(*newName == '\0'))? "delete":"rename",
- " \"", oldName, "\": command doesn't exist", (char *) NULL);
+ Tcl_AppendResult(interp, "can't ",
+ ((newName == NULL)||(*newName == '\0'))? "delete":"rename",
+ " \"", oldName, "\": command doesn't exist", NULL);
return TCL_ERROR;
}
cmdNsPtr = cmdPtr->nsPtr;
oldFullName = Tcl_NewObj();
- Tcl_IncrRefCount( oldFullName );
- Tcl_GetCommandFullName( interp, cmd, oldFullName );
+ Tcl_IncrRefCount(oldFullName);
+ Tcl_GetCommandFullName(interp, cmd, oldFullName);
/*
* If the new command name is NULL or empty, delete the command. Do this
* with Tcl_DeleteCommandFromToken, since we already have the command.
*/
-
+
if ((newName == NULL) || (*newName == '\0')) {
Tcl_DeleteCommandFromToken(interp, cmd);
result = TCL_OK;
@@ -2103,101 +2295,106 @@ TclRenameCommand(interp, oldName, newName)
}
/*
- * Make sure that the destination command does not already exist.
- * The rename operation is like creating a command, so we should
- * automatically create the containing namespaces just like
- * Tcl_CreateCommand would.
+ * Make sure that the destination command does not already exist. The
+ * rename operation is like creating a command, so we should automatically
+ * create the containing namespaces just like Tcl_CreateCommand would.
*/
- TclGetNamespaceForQualName(interp, newName, (Namespace *) NULL,
- CREATE_NS_IF_UNKNOWN, &newNsPtr, &dummy1, &dummy2, &newTail);
+ TclGetNamespaceForQualName(interp, newName, NULL,
+ TCL_CREATE_NS_IF_UNKNOWN, &newNsPtr, &dummy1, &dummy2, &newTail);
if ((newNsPtr == NULL) || (newTail == NULL)) {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "can't rename to \"", newName, "\": bad command name",
- (char *) NULL);
+ Tcl_AppendResult(interp, "can't rename to \"", newName,
+ "\": bad command name", NULL);
result = TCL_ERROR;
goto done;
}
if (Tcl_FindHashEntry(&newNsPtr->cmdTable, newTail) != NULL) {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "can't rename to \"", newName,
- "\": command already exists", (char *) NULL);
+ Tcl_AppendResult(interp, "can't rename to \"", newName,
+ "\": command already exists", NULL);
result = TCL_ERROR;
goto done;
}
/*
- * Warning: any changes done in the code here are likely
- * to be needed in Tcl_HideCommand() code too.
- * (until the common parts are extracted out) --dl
+ * Warning: any changes done in the code here are likely to be needed in
+ * Tcl_HideCommand() code too (until the common parts are extracted out).
+ * - dl
*/
/*
- * Put the command in the new namespace so we can check for an alias
- * loop. Since we are adding a new command to a namespace, we must
- * handle any shadowing of the global commands that this might create.
+ * Put the command in the new namespace so we can check for an alias loop.
+ * Since we are adding a new command to a namespace, we must handle any
+ * shadowing of the global commands that this might create.
*/
-
+
oldHPtr = cmdPtr->hPtr;
- hPtr = Tcl_CreateHashEntry(&newNsPtr->cmdTable, newTail, &new);
- Tcl_SetHashValue(hPtr, (ClientData) cmdPtr);
+ hPtr = Tcl_CreateHashEntry(&newNsPtr->cmdTable, newTail, &isNew);
+ Tcl_SetHashValue(hPtr, cmdPtr);
cmdPtr->hPtr = hPtr;
cmdPtr->nsPtr = newNsPtr;
TclResetShadowedCmdRefs(interp, cmdPtr);
/*
- * Now check for an alias loop. If we detect one, put everything back
- * the way it was and report the error.
+ * Now check for an alias loop. If we detect one, put everything back the
+ * way it was and report the error.
*/
result = TclPreventAliasLoop(interp, interp, (Tcl_Command) cmdPtr);
if (result != TCL_OK) {
- Tcl_DeleteHashEntry(cmdPtr->hPtr);
- cmdPtr->hPtr = oldHPtr;
- cmdPtr->nsPtr = cmdNsPtr;
+ Tcl_DeleteHashEntry(cmdPtr->hPtr);
+ cmdPtr->hPtr = oldHPtr;
+ cmdPtr->nsPtr = cmdNsPtr;
goto done;
}
/*
- * 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 TclCleanupCommand.
+ * 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. These might refer to the same variable,
+ * but that's no big deal.
+ */
+
+ TclInvalidateNsCmdLookup(cmdNsPtr);
+ TclInvalidateNsCmdLookup(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
+ * TclCleanupCommand.
*
- * The trace procedure needs to get a fully qualified name for
- * old and new commands [Tcl bug #651271], or else there's no way
- * for the trace procedure to get the namespace from which the old
- * command is being renamed!
+ * The trace function needs to get a fully qualified name for old and new
+ * commands [Tcl bug #651271], or else there's no way for the trace
+ * function to get the namespace from which the old command is being
+ * renamed!
*/
- Tcl_DStringInit( &newFullName );
- Tcl_DStringAppend( &newFullName, newNsPtr->fullName, -1 );
- if ( newNsPtr != iPtr->globalNsPtr ) {
- Tcl_DStringAppend( &newFullName, "::", 2 );
+ Tcl_DStringInit(&newFullName);
+ Tcl_DStringAppend(&newFullName, newNsPtr->fullName, -1);
+ if (newNsPtr != iPtr->globalNsPtr) {
+ Tcl_DStringAppend(&newFullName, "::", 2);
}
- Tcl_DStringAppend( &newFullName, newTail, -1 );
+ Tcl_DStringAppend(&newFullName, newTail, -1);
cmdPtr->refCount++;
- CallCommandTraces( iPtr, cmdPtr,
- Tcl_GetString( oldFullName ),
- Tcl_DStringValue( &newFullName ),
- TCL_TRACE_RENAME);
- Tcl_DStringFree( &newFullName );
+ CallCommandTraces(iPtr, cmdPtr, Tcl_GetString(oldFullName),
+ Tcl_DStringValue(&newFullName), TCL_TRACE_RENAME);
+ Tcl_DStringFree(&newFullName);
/*
- * The new command name is okay, so remove the command from its
- * current namespace. This is like deleting the command, so bump
- * the cmdEpoch to invalidate any cached references to the command.
+ * The new command name is okay, so remove the command from its current
+ * namespace. This is like deleting the command, so bump the cmdEpoch to
+ * invalidate any cached references to the command.
*/
-
+
Tcl_DeleteHashEntry(oldHPtr);
cmdPtr->cmdEpoch++;
/*
- * If the command being renamed has a compile procedure, increment the
- * interpreter's compileEpoch to invalidate its compiled code. This
- * makes sure that we don't later try to execute old code compiled for
- * the now-renamed command.
+ * If the command being renamed has a compile function, increment the
+ * interpreter's compileEpoch to invalidate its compiled code. This makes
+ * sure that we don't later try to execute old code compiled for the
+ * now-renamed command.
*/
if (cmdPtr->compileProc != NULL) {
@@ -2205,14 +2402,15 @@ TclRenameCommand(interp, oldName, newName)
}
/*
- * Now free the Command structure, if the "oldName" command has
- * been deleted by invocation of rename traces.
+ * Now free the Command structure, if the "oldName" command has been
+ * deleted by invocation of rename traces.
*/
- TclCleanupCommand(cmdPtr);
+
+ TclCleanupCommandMacro(cmdPtr);
result = TCL_OK;
- done:
- TclDecrRefCount( oldFullName );
+ done:
+ TclDecrRefCount(oldFullName);
return result;
}
@@ -2221,16 +2419,15 @@ TclRenameCommand(interp, oldName, newName)
*
* Tcl_SetCommandInfo --
*
- * Modifies various information about a Tcl command. Note that
- * this procedure will not change a command's namespace; use
- * Tcl_RenameCommand to do that. Also, the isNativeObjectProc
- * member of *infoPtr is ignored.
+ * Modifies various information about a Tcl command. Note that this
+ * function will not change a command's namespace; use TclRenameCommand
+ * to do that. Also, the isNativeObjectProc member of *infoPtr is
+ * ignored.
*
* Results:
- * If cmdName exists in interp, then the information at *infoPtr
- * is stored with the command in place of the current information
- * and 1 is returned. If the command doesn't exist then 0 is
- * returned.
+ * If cmdName exists in interp, then the information at *infoPtr is
+ * stored with the command in place of the current information and 1 is
+ * returned. If the command doesn't exist then 0 is returned.
*
* Side effects:
* None.
@@ -2239,20 +2436,17 @@ TclRenameCommand(interp, oldName, newName)
*/
int
-Tcl_SetCommandInfo(interp, cmdName, infoPtr)
- Tcl_Interp *interp; /* Interpreter in which to look
- * for command. */
- CONST char *cmdName; /* Name of desired command. */
- CONST Tcl_CmdInfo *infoPtr; /* Where to find information
- * to store in the command. */
+Tcl_SetCommandInfo(
+ Tcl_Interp *interp, /* Interpreter in which to look for
+ * command. */
+ const char *cmdName, /* Name of desired command. */
+ const Tcl_CmdInfo *infoPtr) /* Where to find information to store in the
+ * command. */
{
Tcl_Command cmd;
- cmd = Tcl_FindCommand(interp, cmdName, (Tcl_Namespace *) NULL,
- /*flags*/ 0);
-
- return Tcl_SetCommandInfoFromToken( cmd, infoPtr );
-
+ cmd = Tcl_FindCommand(interp, cmdName, NULL, /*flags*/ 0);
+ return Tcl_SetCommandInfoFromToken(cmd, infoPtr);
}
/*
@@ -2260,16 +2454,15 @@ Tcl_SetCommandInfo(interp, cmdName, infoPtr)
*
* Tcl_SetCommandInfoFromToken --
*
- * Modifies various information about a Tcl command. Note that
- * this procedure will not change a command's namespace; use
- * Tcl_RenameCommand to do that. Also, the isNativeObjectProc
- * member of *infoPtr is ignored.
+ * Modifies various information about a Tcl command. Note that this
+ * function will not change a command's namespace; use TclRenameCommand
+ * to do that. Also, the isNativeObjectProc member of *infoPtr is
+ * ignored.
*
* Results:
- * If cmdName exists in interp, then the information at *infoPtr
- * is stored with the command in place of the current information
- * and 1 is returned. If the command doesn't exist then 0 is
- * returned.
+ * If cmdName exists in interp, then the information at *infoPtr is
+ * stored with the command in place of the current information and 1 is
+ * returned. If the command doesn't exist then 0 is returned.
*
* Side effects:
* None.
@@ -2278,11 +2471,11 @@ Tcl_SetCommandInfo(interp, cmdName, infoPtr)
*/
int
-Tcl_SetCommandInfoFromToken( cmd, infoPtr )
- Tcl_Command cmd;
- CONST Tcl_CmdInfo* infoPtr;
+Tcl_SetCommandInfoFromToken(
+ Tcl_Command cmd,
+ const Tcl_CmdInfo *infoPtr)
{
- Command* cmdPtr; /* Internal representation of the command */
+ Command *cmdPtr; /* Internal representation of the command */
if (cmd == (Tcl_Command) NULL) {
return 0;
@@ -2291,13 +2484,13 @@ Tcl_SetCommandInfoFromToken( cmd, infoPtr )
/*
* The isNativeObjectProc and nsPtr members of *infoPtr are ignored.
*/
-
+
cmdPtr = (Command *) cmd;
cmdPtr->proc = infoPtr->proc;
cmdPtr->clientData = infoPtr->clientData;
- if (infoPtr->objProc == (Tcl_ObjCmdProc *) NULL) {
+ if (infoPtr->objProc == NULL) {
cmdPtr->objProc = TclInvokeStringCommand;
- cmdPtr->objClientData = (ClientData) cmdPtr;
+ cmdPtr->objClientData = cmdPtr;
} else {
cmdPtr->objProc = infoPtr->objProc;
cmdPtr->objClientData = infoPtr->objClientData;
@@ -2315,10 +2508,9 @@ Tcl_SetCommandInfoFromToken( cmd, infoPtr )
* Returns various information about a Tcl command.
*
* Results:
- * If cmdName exists in interp, then *infoPtr is modified to
- * hold information about cmdName and 1 is returned. If the
- * command doesn't exist then 0 is returned and *infoPtr isn't
- * modified.
+ * If cmdName exists in interp, then *infoPtr is modified to hold
+ * information about cmdName and 1 is returned. If the command doesn't
+ * exist then 0 is returned and *infoPtr isn't modified.
*
* Side effects:
* None.
@@ -2327,20 +2519,17 @@ Tcl_SetCommandInfoFromToken( cmd, infoPtr )
*/
int
-Tcl_GetCommandInfo(interp, cmdName, infoPtr)
- Tcl_Interp *interp; /* Interpreter in which to look
- * for command. */
- CONST char *cmdName; /* Name of desired command. */
- Tcl_CmdInfo *infoPtr; /* Where to store information about
- * command. */
+Tcl_GetCommandInfo(
+ Tcl_Interp *interp, /* Interpreter in which to look for
+ * command. */
+ const char *cmdName, /* Name of desired command. */
+ Tcl_CmdInfo *infoPtr) /* Where to store information about
+ * command. */
{
Tcl_Command cmd;
- cmd = Tcl_FindCommand(interp, cmdName, (Tcl_Namespace *) NULL,
- /*flags*/ 0);
-
- return Tcl_GetCommandInfoFromToken( cmd, infoPtr );
-
+ cmd = Tcl_FindCommand(interp, cmdName, NULL, /*flags*/ 0);
+ return Tcl_GetCommandInfoFromToken(cmd, infoPtr);
}
/*
@@ -2351,9 +2540,9 @@ Tcl_GetCommandInfo(interp, cmdName, infoPtr)
* Returns various information about a Tcl command.
*
* Results:
- * Copies information from the command identified by 'cmd' into
- * a caller-supplied structure and returns 1. If the 'cmd' is
- * NULL, leaves the structure untouched and returns 0.
+ * Copies information from the command identified by 'cmd' into a
+ * caller-supplied structure and returns 1. If the 'cmd' is NULL, leaves
+ * the structure untouched and returns 0.
*
* Side effects:
* None.
@@ -2362,14 +2551,13 @@ Tcl_GetCommandInfo(interp, cmdName, infoPtr)
*/
int
-Tcl_GetCommandInfoFromToken( cmd, infoPtr )
- Tcl_Command cmd;
- Tcl_CmdInfo* infoPtr;
+Tcl_GetCommandInfoFromToken(
+ Tcl_Command cmd,
+ Tcl_CmdInfo *infoPtr)
{
+ Command *cmdPtr; /* Internal representation of the command */
- Command* cmdPtr; /* Internal representation of the command */
-
- if ( cmd == (Tcl_Command) NULL ) {
+ if (cmd == (Tcl_Command) NULL) {
return 0;
}
@@ -2390,7 +2578,6 @@ Tcl_GetCommandInfoFromToken( cmd, infoPtr )
infoPtr->namespacePtr = (Tcl_Namespace *) cmdPtr->nsPtr;
return 1;
-
}
/*
@@ -2398,9 +2585,8 @@ Tcl_GetCommandInfoFromToken( cmd, infoPtr )
*
* Tcl_GetCommandName --
*
- * Given a token returned by Tcl_CreateCommand, this procedure
- * returns the current name of the command (which may have changed
- * due to renaming).
+ * Given a token returned by Tcl_CreateCommand, this function returns the
+ * current name of the command (which may have changed due to renaming).
*
* Results:
* The return value is the name of the given command.
@@ -2411,25 +2597,25 @@ Tcl_GetCommandInfoFromToken( cmd, infoPtr )
*----------------------------------------------------------------------
*/
-CONST char *
-Tcl_GetCommandName(interp, command)
- Tcl_Interp *interp; /* Interpreter containing the command. */
- Tcl_Command command; /* Token for command returned by a previous
- * call to Tcl_CreateCommand. The command
- * must not have been deleted. */
+const char *
+Tcl_GetCommandName(
+ Tcl_Interp *interp, /* Interpreter containing the command. */
+ Tcl_Command command) /* Token for command returned by a previous
+ * call to Tcl_CreateCommand. The command must
+ * not have been deleted. */
{
Command *cmdPtr = (Command *) command;
if ((cmdPtr == NULL) || (cmdPtr->hPtr == NULL)) {
-
/*
* This should only happen if command was "created" after the
- * interpreter began to be deleted, so there isn't really any
- * command. Just return an empty string.
+ * interpreter began to be deleted, so there isn't really any command.
+ * Just return an empty string.
*/
return "";
}
+
return Tcl_GetHashKey(cmdPtr->hPtr->tablePtr, cmdPtr->hPtr);
}
@@ -2438,28 +2624,28 @@ Tcl_GetCommandName(interp, command)
*
* Tcl_GetCommandFullName --
*
- * Given a token returned by, e.g., Tcl_CreateCommand or
- * Tcl_FindCommand, this procedure appends to an object the command's
- * full name, qualified by a sequence of parent namespace names. The
- * command's fully-qualified name may have changed due to renaming.
+ * Given a token returned by, e.g., Tcl_CreateCommand or Tcl_FindCommand,
+ * this function appends to an object the command's full name, qualified
+ * by a sequence of parent namespace names. The command's fully-qualified
+ * name may have changed due to renaming.
*
* Results:
* None.
*
* Side effects:
* The command's fully-qualified name is appended to the string
- * representation of objPtr.
+ * representation of objPtr.
*
*----------------------------------------------------------------------
*/
void
-Tcl_GetCommandFullName(interp, command, objPtr)
- Tcl_Interp *interp; /* Interpreter containing the command. */
- Tcl_Command command; /* Token for command returned by a previous
- * call to Tcl_CreateCommand. The command
- * must not have been deleted. */
- Tcl_Obj *objPtr; /* Points to the object onto which the
+Tcl_GetCommandFullName(
+ Tcl_Interp *interp, /* Interpreter containing the command. */
+ Tcl_Command command, /* Token for command returned by a previous
+ * call to Tcl_CreateCommand. The command must
+ * not have been deleted. */
+ Tcl_Obj *objPtr) /* Points to the object onto which the
* command's full name is appended. */
{
@@ -2482,7 +2668,7 @@ Tcl_GetCommandFullName(interp, command, objPtr)
if (cmdPtr->hPtr != NULL) {
name = Tcl_GetHashKey(cmdPtr->hPtr->tablePtr, cmdPtr->hPtr);
Tcl_AppendToObj(objPtr, name, -1);
- }
+ }
}
}
@@ -2494,30 +2680,28 @@ Tcl_GetCommandFullName(interp, command, objPtr)
* Remove the given command from the given interpreter.
*
* Results:
- * 0 is returned if the command was deleted successfully.
- * -1 is returned if there didn't exist a command by that name.
+ * 0 is returned if the command was deleted successfully. -1 is returned
+ * if there didn't exist a command by that name.
*
* Side effects:
- * cmdName will no longer be recognized as a valid command for
- * interp.
+ * cmdName will no longer be recognized as a valid command for interp.
*
*----------------------------------------------------------------------
*/
int
-Tcl_DeleteCommand(interp, cmdName)
- Tcl_Interp *interp; /* Token for command interpreter (returned
- * by a previous Tcl_CreateInterp call). */
- CONST char *cmdName; /* Name of command to remove. */
+Tcl_DeleteCommand(
+ Tcl_Interp *interp, /* Token for command interpreter (returned by
+ * a previous Tcl_CreateInterp call). */
+ const char *cmdName) /* Name of command to remove. */
{
Tcl_Command cmd;
/*
- * Find the desired command and delete it.
+ * Find the desired command and delete it.
*/
- cmd = Tcl_FindCommand(interp, cmdName, (Tcl_Namespace *) NULL,
- /*flags*/ 0);
+ cmd = Tcl_FindCommand(interp, cmdName, NULL, /*flags*/ 0);
if (cmd == (Tcl_Command) NULL) {
return -1;
}
@@ -2529,26 +2713,26 @@ Tcl_DeleteCommand(interp, cmdName)
*
* Tcl_DeleteCommandFromToken --
*
- * Removes the given command from the given interpreter. This procedure
- * resembles Tcl_DeleteCommand, but takes a Tcl_Command token instead
- * of a command name for efficiency.
+ * Removes the given command from the given interpreter. This function
+ * resembles Tcl_DeleteCommand, but takes a Tcl_Command token instead of
+ * a command name for efficiency.
*
* Results:
- * 0 is returned if the command was deleted successfully.
- * -1 is returned if there didn't exist a command by that name.
+ * 0 is returned if the command was deleted successfully. -1 is returned
+ * if there didn't exist a command by that name.
*
* Side effects:
- * The command specified by "cmd" will no longer be recognized as a
- * valid command for "interp".
+ * The command specified by "cmd" will no longer be recognized as a valid
+ * command for "interp".
*
*----------------------------------------------------------------------
*/
int
-Tcl_DeleteCommandFromToken(interp, cmd)
- Tcl_Interp *interp; /* Token for command interpreter returned by
- * a previous call to Tcl_CreateInterp. */
- Tcl_Command cmd; /* Token for command to delete. */
+Tcl_DeleteCommandFromToken(
+ Tcl_Interp *interp, /* Token for command interpreter returned by a
+ * previous call to Tcl_CreateInterp. */
+ Tcl_Command cmd) /* Token for command to delete. */
{
Interp *iPtr = (Interp *) interp;
Command *cmdPtr = (Command *) cmd;
@@ -2556,73 +2740,90 @@ Tcl_DeleteCommandFromToken(interp, cmd)
Tcl_Command importCmd;
/*
- * The code here is tricky. We can't delete the hash table entry
- * before invoking the deletion callback because there are cases
- * where the deletion callback needs to invoke the command (e.g.
- * object systems such as OTcl). However, this means that the
- * callback could try to delete or rename the command. The deleted
- * flag allows us to detect these cases and skip nested deletes.
+ * Bump the command epoch counter. This will invalidate all cached
+ * references that point to this command.
+ */
+
+ cmdPtr->cmdEpoch++;
+
+ /*
+ * The code here is tricky. We can't delete the hash table entry before
+ * invoking the deletion callback because there are cases where the
+ * deletion callback needs to invoke the command (e.g. object systems such
+ * as OTcl). However, this means that the callback could try to delete or
+ * rename the command. The deleted flag allows us to detect these cases
+ * and skip nested deletes.
*/
if (cmdPtr->flags & CMD_IS_DELETED) {
/*
- * Another deletion is already in progress. Remove the hash
- * table entry now, but don't invoke a callback or free the
- * command structure.
+ * Another deletion is already in progress. Remove the hash table
+ * entry now, but don't invoke a callback or free the command
+ * structure. Take care to only remove the hash entry if it has not
+ * already been removed; otherwise if we manage to hit this function
+ * three times, everything goes up in smoke. [Bug 1220058]
*/
- Tcl_DeleteHashEntry(cmdPtr->hPtr);
- cmdPtr->hPtr = NULL;
+ if (cmdPtr->hPtr != NULL) {
+ Tcl_DeleteHashEntry(cmdPtr->hPtr);
+ cmdPtr->hPtr = NULL;
+ }
return 0;
}
- /*
- * We must delete this command, even though both traces and
- * delete procs may try to avoid this (renaming the command etc).
- * Also traces and delete procs may try to delete the command
- * themsevles. This flag declares that a delete is in progress
- * and that recursive deletes should be ignored.
- */
- cmdPtr->flags |= CMD_IS_DELETED;
-
/*
- * Bump the command epoch counter. This will invalidate all cached
- * references that point to this command.
+ * We must delete this command, even though both traces and delete procs
+ * may try to avoid this (renaming the command etc). Also traces and
+ * delete procs may try to delete the command themsevles. This flag
+ * declares that a delete is in progress and that recursive deletes should
+ * be ignored.
*/
-
- cmdPtr->cmdEpoch++;
+
+ cmdPtr->flags |= CMD_IS_DELETED;
/*
- * Call trace procedures for the command being deleted. Then delete
- * its traces.
+ * Call trace functions for the command being deleted. Then delete its
+ * traces.
*/
if (cmdPtr->tracePtr != NULL) {
CommandTrace *tracePtr;
CallCommandTraces(iPtr,cmdPtr,NULL,NULL,TCL_TRACE_DELETE);
- /* Now delete these traces */
+
+ /*
+ * Now delete these traces.
+ */
+
tracePtr = cmdPtr->tracePtr;
while (tracePtr != NULL) {
CommandTrace *nextPtr = tracePtr->nextPtr;
if ((--tracePtr->refCount) <= 0) {
- ckfree((char*)tracePtr);
+ ckfree((char *) tracePtr);
}
tracePtr = nextPtr;
}
cmdPtr->tracePtr = NULL;
}
-
+
/*
- * If the command being deleted has a compile procedure, increment the
- * interpreter's compileEpoch to invalidate its compiled code. This
- * makes sure that we don't later try to execute old code compiled with
- * command-specific (i.e., inline) bytecodes for the now-deleted
- * command. This field is checked in Tcl_EvalObj and ObjInterpProc, and
- * code whose compilation epoch doesn't match is recompiled.
+ * 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.
+ */
+
+ TclInvalidateNsCmdLookup(cmdPtr->nsPtr);
+
+ /*
+ * If the command being deleted has a compile function, increment the
+ * interpreter's compileEpoch to invalidate its compiled code. This makes
+ * sure that we don't later try to execute old code compiled with
+ * command-specific (i.e., inline) bytecodes for the now-deleted command.
+ * This field is checked in Tcl_EvalObj and ObjInterpProc, and code whose
+ * compilation epoch doesn't match is recompiled.
*/
if (cmdPtr->compileProc != NULL) {
- iPtr->compileEpoch++;
+ iPtr->compileEpoch++;
}
if (cmdPtr->deleteProc != NULL) {
@@ -2632,15 +2833,15 @@ Tcl_DeleteCommandFromToken(interp, cmd)
* data will be a pointer to a ImportedCmdData structure describing
* the "real" command that this imported command refers to.
*/
-
+
/*
* If you are getting a crash during the call to deleteProc and
- * cmdPtr->deleteProc is a pointer to the function free(), the
- * most likely cause is that your extension allocated memory
- * for the clientData argument to Tcl_CreateObjCommand() with
- * the ckalloc() macro and you are now trying to deallocate
- * this memory with free() instead of ckfree(). You should
- * pass a pointer to your own method that calls ckfree().
+ * cmdPtr->deleteProc is a pointer to the function free(), the most
+ * likely cause is that your extension allocated memory for the
+ * clientData argument to Tcl_CreateObjCommand() with the ckalloc()
+ * macro and you are now trying to deallocate this memory with free()
+ * instead of ckfree(). You should pass a pointer to your own method
+ * that calls ckfree().
*/
(*cmdPtr->deleteProc)(cmdPtr->deleteData);
@@ -2653,78 +2854,77 @@ Tcl_DeleteCommandFromToken(interp, cmd)
*/
for (refPtr = cmdPtr->importRefPtr; refPtr != NULL;
- refPtr = nextRefPtr) {
+ refPtr = nextRefPtr) {
nextRefPtr = refPtr->nextPtr;
importCmd = (Tcl_Command) refPtr->importedCmdPtr;
- Tcl_DeleteCommandFromToken(interp, importCmd);
+ Tcl_DeleteCommandFromToken(interp, importCmd);
}
/*
- * Don't use hPtr to delete the hash entry here, because it's
- * possible that the deletion callback renamed the command.
- * Instead, use cmdPtr->hptr, and make sure that no-one else
- * has already deleted the hash entry.
+ * Don't use hPtr to delete the hash entry here, because it's possible
+ * that the deletion callback renamed the command. Instead, use
+ * cmdPtr->hptr, and make sure that no-one else has already deleted the
+ * hash entry.
*/
if (cmdPtr->hPtr != NULL) {
Tcl_DeleteHashEntry(cmdPtr->hPtr);
+ cmdPtr->hPtr = NULL;
}
/*
* Mark the Command structure as no longer valid. This allows
* TclExecuteByteCode to recognize when a Command has logically been
* deleted and a pointer to this Command structure cached in a CmdName
- * object is invalid. TclExecuteByteCode will look up the command again
- * in the interpreter's command hashtable.
+ * object is invalid. TclExecuteByteCode will look up the command again in
+ * the interpreter's command hashtable.
*/
cmdPtr->objProc = NULL;
/*
- * Now free the Command structure, unless there is another reference to
- * it 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
- * TclExecuteByteCode looks up the command in the command hashtable).
+ * Now free the Command structure, unless there is another reference to it
+ * 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 TclExecuteByteCode
+ * looks up the command in the command hashtable).
*/
-
- TclCleanupCommand(cmdPtr);
+
+ TclCleanupCommandMacro(cmdPtr);
return 0;
}
static char *
-CallCommandTraces(iPtr, cmdPtr, oldName, newName, flags)
- Interp *iPtr; /* Interpreter containing command. */
- Command *cmdPtr; /* Command whose traces are to be
- * invoked. */
- CONST char *oldName; /* Command's old name, or NULL if we
- * must get the name from cmdPtr */
- CONST char *newName; /* Command's new name, or NULL if
- * the command is not being renamed */
- int flags; /* Flags indicating the type of traces
- * to trigger, either TCL_TRACE_DELETE
- * or TCL_TRACE_RENAME. */
+CallCommandTraces(
+ Interp *iPtr, /* Interpreter containing command. */
+ Command *cmdPtr, /* Command whose traces are to be invoked. */
+ const char *oldName, /* Command's old name, or NULL if we must get
+ * the name from cmdPtr */
+ const char *newName, /* Command's new name, or NULL if the command
+ * is not being renamed */
+ int flags) /* Flags indicating the type of traces to
+ * trigger, either TCL_TRACE_DELETE or
+ * TCL_TRACE_RENAME. */
{
register CommandTrace *tracePtr;
ActiveCommandTrace active;
char *result;
Tcl_Obj *oldNamePtr = NULL;
- int mask = (TCL_TRACE_DELETE | TCL_TRACE_RENAME); /* Safety */
-
- flags &= mask;
+ Tcl_InterpState state = NULL;
if (cmdPtr->flags & CMD_TRACE_ACTIVE) {
- /*
- * While a rename trace is active, we will not process any more
- * rename traces; while a delete trace is active we will never
- * reach here -- because Tcl_DeleteCommandFromToken checks for the
- * condition (cmdPtr->flags & CMD_IS_DELETED) and returns immediately
- * when a command deletion is in progress. For all other traces,
- * delete traces will not be invoked but a call to TraceCommandProc
- * will ensure that tracePtr->clientData is freed whenever the
- * command "oldName" is deleted.
+ /*
+ * While a rename trace is active, we will not process any more rename
+ * traces; while a delete trace is active we will never reach here -
+ * because Tcl_DeleteCommandFromToken checks for the condition
+ * (cmdPtr->flags & CMD_IS_DELETED) and returns immediately when a
+ * command deletion is in progress. For all other traces, delete
+ * traces will not be invoked but a call to TraceCommandProc will
+ * ensure that tracePtr->clientData is freed whenever the command
+ * "oldName" is deleted.
*/
+
if (cmdPtr->flags & TCL_TRACE_RENAME) {
flags &= ~TCL_TRACE_RENAME;
}
@@ -2734,7 +2934,7 @@ CallCommandTraces(iPtr, cmdPtr, oldName, newName, flags)
}
cmdPtr->flags |= CMD_TRACE_ACTIVE;
cmdPtr->refCount++;
-
+
result = NULL;
active.nextPtr = iPtr->activeCmdTracePtr;
active.reverseScan = 0;
@@ -2744,37 +2944,41 @@ CallCommandTraces(iPtr, cmdPtr, oldName, newName, flags)
flags |= TCL_TRACE_DESTROYED;
}
active.cmdPtr = cmdPtr;
-
- Tcl_Preserve((ClientData) iPtr);
-
- for (tracePtr = cmdPtr->tracePtr; tracePtr != NULL;
- tracePtr = active.nextTracePtr) {
- int traceFlags = (tracePtr->flags & mask);
+ Tcl_Preserve(iPtr);
+
+ for (tracePtr = cmdPtr->tracePtr; tracePtr != NULL;
+ tracePtr = active.nextTracePtr) {
active.nextTracePtr = tracePtr->nextPtr;
- if (!(traceFlags & flags)) {
+ if (!(tracePtr->flags & flags)) {
continue;
}
- cmdPtr->flags |= traceFlags;
+ cmdPtr->flags |= tracePtr->flags;
if (oldName == NULL) {
TclNewObj(oldNamePtr);
Tcl_IncrRefCount(oldNamePtr);
- Tcl_GetCommandFullName((Tcl_Interp *) iPtr,
- (Tcl_Command) cmdPtr, oldNamePtr);
+ Tcl_GetCommandFullName((Tcl_Interp *) iPtr,
+ (Tcl_Command) cmdPtr, oldNamePtr);
oldName = TclGetString(oldNamePtr);
}
tracePtr->refCount++;
+ if (state == NULL) {
+ state = Tcl_SaveInterpState((Tcl_Interp *) iPtr, TCL_OK);
+ }
(*tracePtr->traceProc)(tracePtr->clientData,
(Tcl_Interp *) iPtr, oldName, newName, flags);
- cmdPtr->flags &= ~traceFlags;
+ cmdPtr->flags &= ~tracePtr->flags;
if ((--tracePtr->refCount) <= 0) {
- ckfree((char*)tracePtr);
+ ckfree((char *) tracePtr);
}
}
+ if (state) {
+ Tcl_RestoreInterpState((Tcl_Interp *) iPtr, state);
+ }
+
/*
- * If a new object was created to hold the full oldName,
- * free it now.
+ * If a new object was created to hold the full oldName, free it now.
*/
if (oldNamePtr != NULL) {
@@ -2782,26 +2986,55 @@ CallCommandTraces(iPtr, cmdPtr, oldName, newName, flags)
}
/*
- * Restore the variable's flags, remove the record of our active
- * traces, and then return.
+ * Restore the variable's flags, remove the record of our active traces,
+ * and then return.
*/
cmdPtr->flags &= ~CMD_TRACE_ACTIVE;
cmdPtr->refCount--;
iPtr->activeCmdTracePtr = active.nextPtr;
- Tcl_Release((ClientData) iPtr);
+ Tcl_Release(iPtr);
return result;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+GetCommandSource(
+ Interp *iPtr,
+ const char *command,
+ int numChars,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ if (!command) {
+ return Tcl_NewListObj(objc, objv);
+ }
+ if (command == (char *) -1) {
+ command = TclGetSrcInfoForCmd(iPtr, &numChars);
+ }
+ return Tcl_NewStringObj(command, numChars);
+}
/*
*----------------------------------------------------------------------
*
* TclCleanupCommand --
*
- * This procedure frees up a Command structure unless it is still
+ * This function frees up a Command structure unless it is still
* referenced from an interpreter's command hashtable or from a CmdName
* Tcl object representing the name of a command in a ByteCode
- * instruction sequence.
+ * instruction sequence.
*
* Results:
* None.
@@ -2815,8 +3048,8 @@ CallCommandTraces(iPtr, cmdPtr, oldName, newName, flags)
*/
void
-TclCleanupCommand(cmdPtr)
- register Command *cmdPtr; /* Points to the Command structure to
+TclCleanupCommand(
+ register Command *cmdPtr) /* Points to the Command structure to
* be freed. */
{
cmdPtr->refCount--;
@@ -2830,18 +3063,17 @@ TclCleanupCommand(cmdPtr)
*
* Tcl_CreateMathFunc --
*
- * Creates a new math function for expressions in a given
- * interpreter.
+ * Creates a new math function for expressions in a given interpreter.
*
* Results:
* None.
*
* Side effects:
- * The function defined by "name" is created or redefined. If the
- * function already exists then its definition is replaced; this
- * includes the builtin functions. Redefining a builtin function forces
- * all existing code to be invalidated since that code may be compiled
- * using an instruction specific to the replaced function. In addition,
+ * The Tcl function defined by "name" is created or redefined. If the
+ * function already exists then its definition is replaced; this includes
+ * the builtin functions. Redefining a builtin function forces all
+ * existing code to be invalidated since that code may be compiled using
+ * an instruction specific to the replaced function. In addition,
* redefioning a non-builtin function will force existing code to be
* invalidated if the number of arguments has changed.
*
@@ -2849,65 +3081,205 @@ TclCleanupCommand(cmdPtr)
*/
void
-Tcl_CreateMathFunc(interp, name, numArgs, argTypes, proc, clientData)
- Tcl_Interp *interp; /* Interpreter in which function is
- * to be available. */
- CONST char *name; /* Name of function (e.g. "sin"). */
- int numArgs; /* Nnumber of arguments required by
- * function. */
- Tcl_ValueType *argTypes; /* Array of types acceptable for
- * each argument. */
- Tcl_MathProc *proc; /* Procedure that implements the
- * math function. */
- ClientData clientData; /* Additional value to pass to the
- * function. */
+Tcl_CreateMathFunc(
+ Tcl_Interp *interp, /* Interpreter in which function is to be
+ * available. */
+ const char *name, /* Name of function (e.g. "sin"). */
+ int numArgs, /* Nnumber of arguments required by
+ * function. */
+ Tcl_ValueType *argTypes, /* Array of types acceptable for each
+ * argument. */
+ Tcl_MathProc *proc, /* C function that implements the math
+ * function. */
+ ClientData clientData) /* Additional value to pass to the
+ * function. */
{
- Interp *iPtr = (Interp *) interp;
- Tcl_HashEntry *hPtr;
- MathFunc *mathFuncPtr;
- int new, i;
+ Tcl_DString bigName;
+ OldMathFuncData *data = (OldMathFuncData *)
+ ckalloc(sizeof(OldMathFuncData));
+
+ data->proc = proc;
+ data->numArgs = numArgs;
+ data->argTypes = (Tcl_ValueType *)
+ ckalloc(numArgs * sizeof(Tcl_ValueType));
+ memcpy(data->argTypes, argTypes, numArgs * sizeof(Tcl_ValueType));
+ data->clientData = clientData;
+
+ Tcl_DStringInit(&bigName);
+ Tcl_DStringAppend(&bigName, "::tcl::mathfunc::", -1);
+ Tcl_DStringAppend(&bigName, name, -1);
+
+ Tcl_CreateObjCommand(interp, Tcl_DStringValue(&bigName),
+ OldMathFuncProc, data, OldMathFuncDeleteProc);
+ Tcl_DStringFree(&bigName);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * OldMathFuncProc --
+ *
+ * Dispatch to a math function created with Tcl_CreateMathFunc
+ *
+ * Results:
+ * Returns a standard Tcl result.
+ *
+ * Side effects:
+ * Whatever the math function does.
+ *
+ *----------------------------------------------------------------------
+ */
- hPtr = Tcl_CreateHashEntry(&iPtr->mathFuncTable, name, &new);
- if (new) {
- Tcl_SetHashValue(hPtr, ckalloc(sizeof(MathFunc)));
+static int
+OldMathFuncProc(
+ ClientData clientData, /* Ponter to OldMathFuncData describing the
+ * function being called */
+ Tcl_Interp *interp, /* Tcl interpreter */
+ int objc, /* Actual parameter count */
+ Tcl_Obj *const *objv) /* Parameter vector */
+{
+ Tcl_Obj *valuePtr;
+ OldMathFuncData *dataPtr = clientData;
+ Tcl_Value funcResult, *args;
+ int result;
+ int j, k;
+ double d;
+
+ /*
+ * Check argument count.
+ */
+
+ if (objc != dataPtr->numArgs + 1) {
+ MathFuncWrongNumArgs(interp, dataPtr->numArgs+1, objc, objv);
+ return TCL_ERROR;
}
- mathFuncPtr = (MathFunc *) Tcl_GetHashValue(hPtr);
- if (!new) {
- if (mathFuncPtr->builtinFuncIndex >= 0) {
- /*
- * We are redefining a builtin math function. Invalidate the
- * interpreter's existing code by incrementing its
- * compileEpoch member. This field is checked in Tcl_EvalObj
- * and ObjInterpProc, and code whose compilation epoch doesn't
- * match is recompiled. Newly compiled code will no longer
- * treat the function as builtin.
- */
+ /*
+ * Convert arguments from Tcl_Obj's to Tcl_Value's.
+ */
- iPtr->compileEpoch++;
- } else {
+ args = (Tcl_Value *) ckalloc(dataPtr->numArgs * sizeof(Tcl_Value));
+ for (j = 1, k = 0; j < objc; ++j, ++k) {
+
+ /* TODO: Convert to TclGetNumberFromObj() ? */
+ valuePtr = objv[j];
+ result = Tcl_GetDoubleFromObj(NULL, valuePtr, &d);
+#ifdef ACCEPT_NAN
+ if ((result != TCL_OK) && (valuePtr->typePtr == &tclDoubleType)) {
+ d = valuePtr->internalRep.doubleValue;
+ result = TCL_OK;
+ }
+#endif
+ if (result != TCL_OK) {
/*
- * A non-builtin function is being redefined. We must invalidate
- * existing code if the number of arguments has changed. This
- * is because existing code was compiled assuming that number.
+ * We have a non-numeric argument.
*/
- if (numArgs != mathFuncPtr->numArgs) {
- iPtr->compileEpoch++;
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ "argument to math function didn't have numeric value",-1));
+ TclCheckBadOctal(interp, Tcl_GetString(valuePtr));
+ ckfree((char *)args);
+ return TCL_ERROR;
+ }
+
+ /*
+ * Copy the object's numeric value to the argument record, converting
+ * it if necessary.
+ *
+ * NOTE: no bignum support; use the new mathfunc interface for that.
+ */
+
+ args[k].type = dataPtr->argTypes[k];
+ switch (args[k].type) {
+ case TCL_EITHER:
+ if (Tcl_GetLongFromObj(NULL, valuePtr, &(args[k].intValue))
+ == TCL_OK) {
+ args[k].type = TCL_INT;
+ break;
+ }
+ if (Tcl_GetWideIntFromObj(interp, valuePtr, &(args[k].wideValue))
+ == TCL_OK) {
+ args[k].type = TCL_WIDE_INT;
+ break;
+ }
+ args[k].type = TCL_DOUBLE;
+ /* FALLTHROUGH */
+
+ case TCL_DOUBLE:
+ args[k].doubleValue = d;
+ break;
+ case TCL_INT:
+ if (ExprIntFunc(NULL, interp, 2, &(objv[j-1])) != TCL_OK) {
+ ckfree((char *)args);
+ return TCL_ERROR;
+ }
+ valuePtr = Tcl_GetObjResult(interp);
+ Tcl_GetLongFromObj(NULL, valuePtr, &(args[k].intValue));
+ Tcl_ResetResult(interp);
+ break;
+ case TCL_WIDE_INT:
+ if (ExprWideFunc(NULL, interp, 2, &(objv[j-1])) != TCL_OK) {
+ ckfree((char *)args);
+ return TCL_ERROR;
}
+ valuePtr = Tcl_GetObjResult(interp);
+ Tcl_GetWideIntFromObj(NULL, valuePtr, &(args[k].wideValue));
+ Tcl_ResetResult(interp);
+ break;
}
}
-
- mathFuncPtr->builtinFuncIndex = -1; /* can't be a builtin function */
- if (numArgs > MAX_MATH_ARGS) {
- numArgs = MAX_MATH_ARGS;
+
+ /*
+ * Call the function.
+ */
+
+ errno = 0;
+ result = (*dataPtr->proc)(dataPtr->clientData, interp, args, &funcResult);
+ ckfree((char *)args);
+ if (result != TCL_OK) {
+ return result;
}
- mathFuncPtr->numArgs = numArgs;
- for (i = 0; i < numArgs; i++) {
- mathFuncPtr->argTypes[i] = argTypes[i];
+
+ /*
+ * Return the result of the call.
+ */
+
+ if (funcResult.type == TCL_INT) {
+ TclNewLongObj(valuePtr, funcResult.intValue);
+ } else if (funcResult.type == TCL_WIDE_INT) {
+ valuePtr = Tcl_NewWideIntObj(funcResult.wideValue);
+ } else {
+ return CheckDoubleResult(interp, funcResult.doubleValue);
}
- mathFuncPtr->proc = proc;
- mathFuncPtr->clientData = clientData;
+ Tcl_SetObjResult(interp, valuePtr);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * OldMathFuncDeleteProc --
+ *
+ * Cleans up after deleting a math function registered with
+ * Tcl_CreateMathFunc
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Frees allocated memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+OldMathFuncDeleteProc(
+ ClientData clientData)
+{
+ OldMathFuncData *dataPtr = clientData;
+
+ ckfree((void *) dataPtr->argTypes);
+ ckfree((void *) dataPtr);
}
/*
@@ -2919,64 +3291,80 @@ Tcl_CreateMathFunc(interp, name, numArgs, argTypes, proc, clientData)
* interpreter.
*
* Results:
- * TCL_OK if it succeeds, TCL_ERROR else (leaving an error message
- * in the interpreter result if that happens.)
+ * TCL_OK if it succeeds, TCL_ERROR else (leaving an error message in the
+ * interpreter result if that happens.)
*
* Side effects:
- * If this function succeeds, the variables pointed to by the
- * numArgsPtr and argTypePtr arguments will be updated to detail the
- * arguments allowed by the function. The variable pointed to by the
- * procPtr argument will be set to NULL if the function is a builtin
- * function, and will be set to the address of the C function used to
- * implement the math function otherwise (in which case the variable
- * pointed to by the clientDataPtr argument will also be updated.)
+ * If this function succeeds, the variables pointed to by the numArgsPtr
+ * and argTypePtr arguments will be updated to detail the arguments
+ * allowed by the function. The variable pointed to by the procPtr
+ * argument will be set to NULL if the function is a builtin function,
+ * and will be set to the address of the C function used to implement the
+ * math function otherwise (in which case the variable pointed to by the
+ * clientDataPtr argument will also be updated.)
*
*----------------------------------------------------------------------
*/
int
-Tcl_GetMathFuncInfo(interp, name, numArgsPtr, argTypesPtr, procPtr,
- clientDataPtr)
- Tcl_Interp *interp;
- CONST char *name;
- int *numArgsPtr;
- Tcl_ValueType **argTypesPtr;
- Tcl_MathProc **procPtr;
- ClientData *clientDataPtr;
+Tcl_GetMathFuncInfo(
+ Tcl_Interp *interp,
+ const char *name,
+ int *numArgsPtr,
+ Tcl_ValueType **argTypesPtr,
+ Tcl_MathProc **procPtr,
+ ClientData *clientDataPtr)
{
- Interp *iPtr = (Interp *) interp;
- Tcl_HashEntry *hPtr;
- MathFunc *mathFuncPtr;
- Tcl_ValueType *argTypes;
- int i,numArgs;
+ Tcl_Obj *cmdNameObj;
+ Command *cmdPtr;
- hPtr = Tcl_FindHashEntry(&iPtr->mathFuncTable, name);
- if (hPtr == NULL) {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "math function \"", name, "\" not known in this interpreter",
- (char *) NULL);
+ /*
+ * Get the command that implements the math function.
+ */
+
+ TclNewLiteralStringObj(cmdNameObj, "tcl::mathfunc::");
+ Tcl_AppendToObj(cmdNameObj, name, -1);
+ Tcl_IncrRefCount(cmdNameObj);
+ cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, cmdNameObj);
+ Tcl_DecrRefCount(cmdNameObj);
+
+ /*
+ * Report unknown functions.
+ */
+
+ if (cmdPtr == NULL) {
+ Tcl_Obj *message;
+
+ TclNewLiteralStringObj(message, "unknown math function \"");
+ Tcl_AppendToObj(message, name, -1);
+ Tcl_AppendToObj(message, "\"", 1);
+ Tcl_SetObjResult(interp, message);
+ *numArgsPtr = -1;
+ *argTypesPtr = NULL;
+ *procPtr = NULL;
+ *clientDataPtr = NULL;
return TCL_ERROR;
}
- mathFuncPtr = (MathFunc *) Tcl_GetHashValue(hPtr);
- *numArgsPtr = numArgs = mathFuncPtr->numArgs;
- if (numArgs == 0) {
- /* Avoid doing zero-sized allocs... */
- numArgs = 1;
- }
- *argTypesPtr = argTypes =
- (Tcl_ValueType *)ckalloc(numArgs * sizeof(Tcl_ValueType));
- for (i = 0; i < mathFuncPtr->numArgs; i++) {
- argTypes[i] = mathFuncPtr->argTypes[i];
- }
+ /*
+ * Retrieve function info for user defined functions; return dummy
+ * information for builtins.
+ */
+
+ if (cmdPtr->objProc == &OldMathFuncProc) {
+ OldMathFuncData *dataPtr = cmdPtr->clientData;
- if (mathFuncPtr->builtinFuncIndex == -1) {
- *procPtr = (Tcl_MathProc *) NULL;
+ *procPtr = dataPtr->proc;
+ *numArgsPtr = dataPtr->numArgs;
+ *argTypesPtr = dataPtr->argTypes;
+ *clientDataPtr = dataPtr->clientData;
} else {
- *procPtr = mathFuncPtr->proc;
- *clientDataPtr = mathFuncPtr->clientData;
+ *procPtr = NULL;
+ *numArgsPtr = -1;
+ *argTypesPtr = NULL;
+ *procPtr = NULL;
+ *clientDataPtr = NULL;
}
-
return TCL_OK;
}
@@ -2989,9 +3377,9 @@ Tcl_GetMathFuncInfo(interp, name, numArgsPtr, argTypesPtr, procPtr,
* interpreter.
*
* Results:
- * A pointer to a Tcl_Obj structure with a reference count of zero,
- * or NULL in the case of an error (in which case a suitable error
- * message will be left in the interpreter result.)
+ * A pointer to a Tcl_Obj structure with a reference count of zero, or
+ * NULL in the case of an error (in which case a suitable error message
+ * will be left in the interpreter result.)
*
* Side effects:
* None.
@@ -3000,28 +3388,46 @@ Tcl_GetMathFuncInfo(interp, name, numArgsPtr, argTypesPtr, procPtr,
*/
Tcl_Obj *
-Tcl_ListMathFuncs(interp, pattern)
- Tcl_Interp *interp;
- CONST char *pattern;
+Tcl_ListMathFuncs(
+ Tcl_Interp *interp,
+ const char *pattern)
{
- Interp *iPtr = (Interp *) interp;
- Tcl_Obj *resultList = Tcl_NewObj();
- register Tcl_HashEntry *hPtr;
- Tcl_HashSearch hSearch;
- CONST char *name;
-
- for (hPtr = Tcl_FirstHashEntry(&iPtr->mathFuncTable, &hSearch);
- hPtr != NULL; hPtr = Tcl_NextHashEntry(&hSearch)) {
- name = Tcl_GetHashKey(&iPtr->mathFuncTable, hPtr);
- if ((pattern == NULL || Tcl_StringMatch(name, pattern)) &&
- /* I don't expect this to fail, but... */
- Tcl_ListObjAppendElement(interp, resultList,
- Tcl_NewStringObj(name,-1)) != TCL_OK) {
- Tcl_DecrRefCount(resultList);
- return NULL;
+ 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;
+ }
+
+ if ((pattern != NULL) && TclMatchIsTrivial(pattern)) {
+ if (Tcl_FindHashEntry(&nsPtr->cmdTable, pattern) != NULL) {
+ Tcl_ListObjAppendElement(NULL, result,
+ Tcl_NewStringObj(pattern, -1));
+ }
+ } 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));
+ }
}
}
- return resultList;
+ return result;
}
/*
@@ -3029,13 +3435,12 @@ Tcl_ListMathFuncs(interp, pattern)
*
* TclInterpReady --
*
- * Check if an interpreter is ready to eval commands or scripts,
- * i.e., if it was not deleted and if the nesting level is not
- * too high.
+ * Check if an interpreter is ready to eval commands or scripts, i.e., if
+ * it was not deleted and if the nesting level is not too high.
*
* Results:
- * The return value is TCL_OK if it the interpreter is ready,
- * TCL_ERROR otherwise.
+ * The return value is TCL_OK if it the interpreter is ready, TCL_ERROR
+ * otherwise.
*
* Side effects:
* The interpreters object and string results are cleared.
@@ -3043,15 +3448,18 @@ Tcl_ListMathFuncs(interp, pattern)
*----------------------------------------------------------------------
*/
-int
-TclInterpReady(interp)
- Tcl_Interp *interp;
+int
+TclInterpReady(
+ Tcl_Interp *interp)
{
+#if !defined(TCL_NO_STACK_CHECK)
+ int localInt; /* used for checking the stack */
+#endif
register Interp *iPtr = (Interp *) interp;
/*
- * Reset both the interpreter's string and object results and clear
- * out any previous error information.
+ * Reset both the interpreter's string and object results and clear out
+ * any previous error information.
*/
Tcl_ResetResult(interp);
@@ -3059,46 +3467,53 @@ TclInterpReady(interp)
/*
* If the interpreter has been deleted, return an error.
*/
-
+
if (iPtr->flags & DELETED) {
Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "attempt to call eval in deleted interpreter", -1);
- Tcl_SetErrorCode(interp, "CORE", "IDELETE",
- "attempt to call eval in deleted interpreter",
- (char *) NULL);
+ Tcl_AppendResult(interp,
+ "attempt to call eval in deleted interpreter", NULL);
+ Tcl_SetErrorCode(interp, "TCL", "IDELETE",
+ "attempt to call eval in deleted interpreter", NULL);
return TCL_ERROR;
}
/*
- * Check depth of nested calls to Tcl_Eval: if this gets too large,
- * it's probably because of an infinite loop somewhere.
+ * Check depth of nested calls to Tcl_Eval: if this gets too large, it's
+ * probably because of an infinite loop somewhere.
*/
- if (((iPtr->numLevels) > iPtr->maxNestingDepth)
- || (TclpCheckStackSpace() == 0)) {
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "too many nested evaluations (infinite loop?)", -1);
- return TCL_ERROR;
+ if (((iPtr->numLevels) <= iPtr->maxNestingDepth)
+ && CheckCStack(iPtr, &localInt)) {
+ return TCL_OK;
}
- return TCL_OK;
+ if (!CheckCStack(iPtr, &localInt)) {
+ Tcl_AppendResult(interp,
+ "out of stack space (infinite loop?)", NULL);
+ } else {
+ Tcl_AppendResult(interp,
+ "too many nested evaluations (infinite loop?)", NULL);
+ }
+ return TCL_ERROR;
}
/*
*----------------------------------------------------------------------
*
- * TclEvalObjvInternal --
+ * TclEvalObjvInternal
*
- * This procedure evaluates a Tcl command that has already been
- * parsed into words, with one Tcl_Obj holding each word. The caller
- * is responsible for managing the iPtr->numLevels.
+ * This function evaluates a Tcl command that has already been parsed
+ * into words, with one Tcl_Obj holding each word. The caller is
+ * responsible for managing the iPtr->numLevels.
+ *
+ * TclEvalObjvInternal is the backend for Tcl_EvalObjv, the bytecode
+ * engine also calls it directly.
*
* Results:
- * The return value is a standard Tcl completion code such as
- * TCL_OK or TCL_ERROR. A result or error message is left in
- * interp's result. If an error occurs, this procedure does
- * NOT add any information to the errorInfo variable.
+ * The return value is a standard Tcl completion code such as TCL_OK or
+ * TCL_ERROR. A result or error message is left in interp's result. If an
+ * error occurs, this function does NOT add any information to the
+ * errorInfo variable.
*
* Side effects:
* Depends on the command.
@@ -3107,39 +3522,39 @@ TclInterpReady(interp)
*/
int
-TclEvalObjvInternal(interp, objc, objv, command, length, flags)
- Tcl_Interp *interp; /* Interpreter in which to evaluate the
- * command. Also used for error
- * reporting. */
- int objc; /* Number of words in command. */
- Tcl_Obj *CONST objv[]; /* An array of pointers to objects that are
+TclEvalObjvInternal(
+ Tcl_Interp *interp, /* Interpreter in which to evaluate the
+ * command. Also used for error reporting. */
+ int objc, /* Number of words in command. */
+ Tcl_Obj *const objv[], /* An array of pointers to objects that are
* the words that make up the command. */
- CONST char *command; /* Points to the beginning of the string
- * representation of the command; this
- * is used for traces. If the string
- * representation of the command is
- * unknown, an empty string should be
- * supplied. If it is NULL, no traces will
- * be called. */
- int length; /* Number of bytes in command; if -1, all
+ const char *command, /* Points to the beginning of the string
+ * representation of the command; this is used
+ * for traces. NULL if the string
+ * representation of the command is unknown is
+ * to be generated from (objc,objv), -1 if it
+ * is to be generated from bytecode
+ * source. This is only needed the traces. */
+ int length, /* Number of bytes in command; if -1, all
* characters up to the first null byte are
* used. */
- int flags; /* Collection of OR-ed bits that control
- * the evaluation of the script. Only
+ int flags) /* Collection of OR-ed bits that control the
+ * evaluation of the script. Only
* TCL_EVAL_GLOBAL and TCL_EVAL_INVOKE are
* currently supported. */
-
{
Command *cmdPtr;
Interp *iPtr = (Interp *) interp;
Tcl_Obj **newObjv;
int i;
- CallFrame *savedVarFramePtr; /* Saves old copy of iPtr->varFramePtr
- * in case TCL_EVAL_GLOBAL was set. */
+ CallFrame *savedVarFramePtr = NULL;
+ CallFrame *varFramePtr = iPtr->varFramePtr;
int code = TCL_OK;
int traceCode = TCL_OK;
- int checkTraces = 1;
+ int checkTraces = 1, traced;
Namespace *savedNsPtr = NULL;
+ Namespace *lookupNsPtr = iPtr->lookupNsPtr;
+ Tcl_Obj *commandPtr = NULL;
if (TclInterpReady(interp) == TCL_ERROR) {
return TCL_ERROR;
@@ -3149,93 +3564,107 @@ TclEvalObjvInternal(interp, objc, objv, command, length, flags)
return TCL_OK;
}
+ /*
+ * If any execution traces rename or delete the current command, we may
+ * need (at most) two passes here.
+ */
+
+ reparseBecauseOfTraces:
/*
- * If any execution traces rename or delete the current command,
- * we may need (at most) two passes here.
+ * Configure evaluation context to match the requested flags.
*/
- savedVarFramePtr = iPtr->varFramePtr;
- while (1) {
-
- /* Configure evaluation context to match the requested flags */
- if (flags & TCL_EVAL_GLOBAL) {
- iPtr->varFramePtr = NULL;
- } else if ((flags & TCL_EVAL_INVOKE) && iPtr->varFramePtr) {
- savedNsPtr = iPtr->varFramePtr->nsPtr;
- iPtr->varFramePtr->nsPtr = iPtr->globalNsPtr;
- }
-
- /*
- * Find the procedure to execute this command. If there isn't one,
- * then see if there is a command "unknown". If so, create a new
- * word array with "unknown" as the first word and the original
- * command words as arguments. Then call ourselves recursively
- * to execute it.
- */
- cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, objv[0]);
- if (cmdPtr == NULL) {
- newObjv = (Tcl_Obj **) ckalloc((unsigned)
- ((objc + 1) * sizeof (Tcl_Obj *)));
- for (i = objc-1; i >= 0; i--) {
- newObjv[i+1] = objv[i];
- }
- newObjv[0] = Tcl_NewStringObj("::unknown", -1);
- Tcl_IncrRefCount(newObjv[0]);
- cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, newObjv[0]);
- if (cmdPtr == NULL) {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "invalid command name \"", Tcl_GetString(objv[0]), "\"",
- (char *) NULL);
- code = TCL_ERROR;
+ if (flags) {
+ if (flags & TCL_EVAL_INVOKE) {
+ savedNsPtr = varFramePtr->nsPtr;
+ if (lookupNsPtr) {
+ varFramePtr->nsPtr = lookupNsPtr;
+ iPtr->lookupNsPtr = NULL;
} else {
- iPtr->numLevels++;
- code = TclEvalObjvInternal(interp, objc+1, newObjv,
- command, length, 0);
- iPtr->numLevels--;
+ varFramePtr->nsPtr = iPtr->globalNsPtr;
}
- Tcl_DecrRefCount(newObjv[0]);
- ckfree((char *) newObjv);
- if (savedNsPtr) {
- iPtr->varFramePtr->nsPtr = savedNsPtr;
+ } else if ((flags & TCL_EVAL_GLOBAL)
+ && (varFramePtr != iPtr->rootFramePtr) && !savedVarFramePtr) {
+ varFramePtr = iPtr->rootFramePtr;
+ savedVarFramePtr = iPtr->varFramePtr;
+ iPtr->varFramePtr = varFramePtr;
+ }
+ }
+
+ /*
+ * Find the function to execute this command. If there isn't one, then see
+ * if there is an unknown command handler registered for this namespace.
+ * If so, create a new word array with the handler as the first words and
+ * the original command words as arguments. Then call ourselves
+ * recursively to execute it.
+ */
+
+ cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, objv[0]);
+ if (!cmdPtr) {
+ goto notFound;
+ }
+
+ if (savedNsPtr) {
+ varFramePtr->nsPtr = savedNsPtr;
+ } else if (iPtr->ensembleRewrite.sourceObjs) {
+ /*
+ * TCL_EVAL_INVOKE was not set: clear rewrite rules
+ */
+
+ iPtr->ensembleRewrite.sourceObjs = NULL;
+ }
+
+ /*
+ * Call trace functions if needed.
+ */
+
+ traced = (iPtr->tracePtr || (cmdPtr->flags & CMD_HAS_EXEC_TRACES));
+ if (traced && checkTraces) {
+ int cmdEpoch = cmdPtr->cmdEpoch;
+ int newEpoch;
+
+ /*
+ * Insure that we have a correct nul-terminated command string for the
+ * trace code.
+ */
+
+ commandPtr = GetCommandSource(iPtr, command, length, objc, objv);
+ command = TclGetStringFromObj(commandPtr, &length);
+
+ /*
+ * 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.
+ */
+
+ cmdPtr->refCount++;
+ if (iPtr->tracePtr && (traceCode == TCL_OK)) {
+ traceCode = TclCheckInterpTraces(interp, command, length,
+ cmdPtr, code, TCL_TRACE_ENTER_EXEC, objc, objv);
+ }
+ if ((cmdPtr->flags & CMD_HAS_EXEC_TRACES) && (traceCode == TCL_OK)) {
+ traceCode = TclCheckExecutionTraces(interp, command, length,
+ cmdPtr, code, TCL_TRACE_ENTER_EXEC, objc, objv);
+ }
+ newEpoch = cmdPtr->cmdEpoch;
+ TclCleanupCommandMacro(cmdPtr);
+
+ /*
+ * If the traces modified/deleted the command or any existing traces,
+ * they will update the command's epoch. When that happens, set
+ * checkTraces is set to 0 to prevent the re-calling of traces (and
+ * any possible infinite loop) and we go back to re-find the command
+ * implementation.
+ */
+
+ if (cmdEpoch != newEpoch) {
+ checkTraces = 0;
+ if (commandPtr) {
+ Tcl_DecrRefCount(commandPtr);
}
- goto done;
- }
- if (savedNsPtr) {
- iPtr->varFramePtr->nsPtr = savedNsPtr;
+ goto reparseBecauseOfTraces;
}
-
- /*
- * Call trace procedures if needed.
- */
- if ((checkTraces) && (command != NULL)) {
- int cmdEpoch = cmdPtr->cmdEpoch;
- int newEpoch;
-
- cmdPtr->refCount++;
- /*
- * If the first set of traces modifies/deletes the command or
- * any existing traces, then the set checkTraces to 0 and
- * go through this while loop one more time.
- */
- if (iPtr->tracePtr != NULL && traceCode == TCL_OK) {
- traceCode = TclCheckInterpTraces(interp, command, length,
- cmdPtr, code, TCL_TRACE_ENTER_EXEC, objc, objv);
- }
- if ((cmdPtr->flags & CMD_HAS_EXEC_TRACES)
- && (traceCode == TCL_OK)) {
- traceCode = TclCheckExecutionTraces(interp, command, length,
- cmdPtr, code, TCL_TRACE_ENTER_EXEC, objc, objv);
- }
- newEpoch = cmdPtr->cmdEpoch;
- TclCleanupCommand(cmdPtr);
- if (cmdEpoch != newEpoch) {
- /* The command has been modified in some way */
- checkTraces = 0;
- continue;
- }
- }
- break;
}
#ifdef USE_DTRACE
@@ -3249,14 +3678,24 @@ TclEvalObjvInternal(interp, objc, objv, command, length, flags)
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() && iPtr->cmdFramePtr) {
+ Tcl_Obj *info = TclInfoFrame(interp, iPtr->cmdFramePtr);
+ char *a[4]; int i[2];
+
+ TclDTraceInfo(info, a, i);
+ TCL_DTRACE_CMD_INFO(a[0], a[1], a[2], a[3], i[0], i[1]);
+ TclDecrRefCount(info);
+ }
#endif /* USE_DTRACE */
/*
* Finally, invoke the command's Tcl_ObjCmdProc.
*/
+
cmdPtr->refCount++;
iPtr->cmdCount++;
- if ( code == TCL_OK && traceCode == TCL_OK) {
+ if (code == TCL_OK && traceCode == TCL_OK
+ && !TclLimitExceeded(iPtr->limit)) {
if (TCL_DTRACE_CMD_ENTRY_ENABLED()) {
TCL_DTRACE_CMD_ENTRY(TclGetString(objv[0]), objc - 1,
(Tcl_Obj **)(objv + 1));
@@ -3266,48 +3705,58 @@ TclEvalObjvInternal(interp, objc, objv, command, length, flags)
TCL_DTRACE_CMD_RETURN(TclGetString(objv[0]), code);
}
}
- if (Tcl_AsyncReady()) {
+
+ if (TclAsyncReady(iPtr)) {
code = Tcl_AsyncInvoke(interp, code);
}
+ if (code == TCL_OK && TclLimitReady(iPtr->limit)) {
+ code = Tcl_LimitCheck(interp);
+ }
/*
* Call 'leave' command traces
*/
- if (!(cmdPtr->flags & CMD_IS_DELETED)) {
- int saveErrFlags = iPtr->flags
- & (ERR_IN_PROGRESS | ERR_ALREADY_LOGGED | ERROR_CODE_SET);
- if ((cmdPtr->flags & CMD_HAS_EXEC_TRACES) && (traceCode == TCL_OK)) {
- traceCode = TclCheckExecutionTraces (interp, command, length,
- cmdPtr, code, TCL_TRACE_LEAVE_EXEC, objc, objv);
- }
- if (iPtr->tracePtr != NULL && traceCode == TCL_OK) {
- traceCode = TclCheckInterpTraces(interp, command, length,
- cmdPtr, code, TCL_TRACE_LEAVE_EXEC, objc, objv);
- }
- if (traceCode == TCL_OK) {
- iPtr->flags |= saveErrFlags;
+
+ if (traced) {
+ if (!(cmdPtr->flags & CMD_IS_DELETED)) {
+ if ((cmdPtr->flags & CMD_HAS_EXEC_TRACES) && traceCode == TCL_OK){
+ traceCode = TclCheckExecutionTraces(interp, command, length,
+ cmdPtr, code, TCL_TRACE_LEAVE_EXEC, objc, objv);
+ }
+ if (iPtr->tracePtr != NULL && traceCode == TCL_OK) {
+ traceCode = TclCheckInterpTraces(interp, command, length,
+ cmdPtr, code, TCL_TRACE_LEAVE_EXEC, objc, objv);
+ }
+ }
+
+ /*
+ * If one of the trace invocation resulted in error, then change the
+ * result code accordingly. Note, that the interp->result should
+ * already be set correctly by the call to TraceExecutionProc.
+ */
+
+ if (traceCode != TCL_OK) {
+ code = traceCode;
+ }
+ if (commandPtr) {
+ Tcl_DecrRefCount(commandPtr);
}
}
- TclCleanupCommand(cmdPtr);
/*
- * If one of the trace invocation resulted in error, then
- * change the result code accordingly. Note, that the
- * interp->result should already be set correctly by the
- * call to TraceExecutionProc.
+ * Decrement the reference count of cmdPtr and deallocate it if it has
+ * dropped to zero.
*/
- if (traceCode != TCL_OK) {
- code = traceCode;
- }
-
+ TclCleanupCommandMacro(cmdPtr);
+
/*
- * If the interpreter has a non-empty string result, the result
- * object is either empty or stale because some procedure set
- * interp->result directly. If so, move the string result to the
- * result object, then reset the string result.
+ * If the interpreter has a non-empty string result, the result object is
+ * either empty or stale because some function set interp->result
+ * directly. If so, move the string result to the result object, then
+ * reset the string result.
*/
-
+
if (*(iPtr->result) != 0) {
(void) Tcl_GetObjResult(interp);
}
@@ -3317,532 +3766,213 @@ TclEvalObjvInternal(interp, objc, objv, command, length, flags)
Tcl_Obj *r;
r = Tcl_GetObjResult(interp);
- TCL_DTRACE_CMD_RESULT(TclGetString(objv[0]), code, TclGetString(r), r);
+ TCL_DTRACE_CMD_RESULT(TclGetString(objv[0]), code, TclGetString(r),r);
}
#endif /* USE_DTRACE */
- done:
- iPtr->varFramePtr = savedVarFramePtr;
+ done:
+ if (savedVarFramePtr) {
+ iPtr->varFramePtr = savedVarFramePtr;
+ }
return code;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tcl_EvalObjv --
- *
- * This procedure evaluates a Tcl command that has already been
- * parsed into words, with one Tcl_Obj holding each word.
- *
- * Results:
- * The return value is a standard Tcl completion code such as
- * TCL_OK or TCL_ERROR. A result or error message is left in
- * interp's result.
- *
- * Side effects:
- * Depends on the command.
- *
- *----------------------------------------------------------------------
- */
-int
-Tcl_EvalObjv(interp, objc, objv, flags)
- Tcl_Interp *interp; /* Interpreter in which to evaluate the
- * command. Also used for error
- * reporting. */
- int objc; /* Number of words in command. */
- Tcl_Obj *CONST objv[]; /* An array of pointers to objects that are
- * the words that make up the command. */
- int flags; /* Collection of OR-ed bits that control
- * the evaluation of the script. Only
- * TCL_EVAL_GLOBAL and TCL_EVAL_INVOKE
- * are currently supported. */
-{
- Interp *iPtr = (Interp *)interp;
- Trace *tracePtr;
- Tcl_DString cmdBuf;
- char *cmdString = ""; /* A command string is only necessary for
- * command traces or error logs; it will be
- * generated to replace this default value if
- * necessary. */
- int cmdLen = 0; /* a non-zero value indicates that a command
- * string was generated. */
- int code = TCL_OK;
- int i;
- int allowExceptions = (iPtr->evalFlags & TCL_ALLOW_EXCEPTIONS);
-
- for (tracePtr = iPtr->tracePtr; tracePtr; tracePtr = tracePtr->nextPtr) {
- if ((tracePtr->level == 0) || (iPtr->numLevels <= tracePtr->level)) {
- /*
- * The command may be needed for an execution trace. Generate a
- * command string.
- */
-
- Tcl_DStringInit(&cmdBuf);
- for (i = 0; i < objc; i++) {
- Tcl_DStringAppendElement(&cmdBuf, Tcl_GetString(objv[i]));
+ notFound:
+ {
+ Namespace *currNsPtr = NULL; /* Used to check for and invoke any
+ * registered unknown command handler
+ * for the current namespace (TIP
+ * 181). */
+ int newObjc, handlerObjc;
+ Tcl_Obj **handlerObjv;
+
+ currNsPtr = varFramePtr->nsPtr;
+ if ((currNsPtr == NULL) || (currNsPtr->unknownHandlerPtr == NULL)) {
+ currNsPtr = iPtr->globalNsPtr;
+ if (currNsPtr == NULL) {
+ Tcl_Panic("TclEvalObjvInternal: NULL global namespace pointer");
}
- cmdString = Tcl_DStringValue(&cmdBuf);
- cmdLen = Tcl_DStringLength(&cmdBuf);
- break;
}
- }
- iPtr->numLevels++;
- code = TclEvalObjvInternal(interp, objc, objv, cmdString, cmdLen, flags);
- iPtr->numLevels--;
+ /*
+ * Check to see if the resolution namespace has lost its unknown
+ * handler. If so, reset it to "::unknown".
+ */
- /*
- * If we are again at the top level, process any unusual
- * return code returned by the evaluated code.
- */
-
- if (iPtr->numLevels == 0) {
- if (code == TCL_RETURN) {
- code = TclUpdateReturnInfo(iPtr);
+ if (currNsPtr->unknownHandlerPtr == NULL) {
+ TclNewLiteralStringObj(currNsPtr->unknownHandlerPtr, "::unknown");
+ Tcl_IncrRefCount(currNsPtr->unknownHandlerPtr);
}
- if ((code != TCL_OK) && (code != TCL_ERROR)
- && !allowExceptions) {
- ProcessUnexpectedResult(interp, code);
- code = TCL_ERROR;
+
+ /*
+ * Get the list of words for the unknown handler and allocate enough
+ * space to hold both the handler prefix and all words of the command
+ * invokation itself.
+ */
+
+ Tcl_ListObjGetElements(NULL, currNsPtr->unknownHandlerPtr,
+ &handlerObjc, &handlerObjv);
+ newObjc = objc + handlerObjc;
+ newObjv = (Tcl_Obj **) TclStackAlloc(interp,
+ (int) sizeof(Tcl_Obj *) * newObjc);
+
+ /*
+ * Copy command prefix from unknown handler and add on the real
+ * command's full argument list. Note that we only use memcpy() once
+ * because we have to increment the reference count of all the handler
+ * arguments anyway.
+ */
+
+ for (i = 0; i < handlerObjc; ++i) {
+ newObjv[i] = handlerObjv[i];
+ Tcl_IncrRefCount(newObjv[i]);
}
- }
-
- if ((code == TCL_ERROR) && !(flags & TCL_EVAL_INVOKE)) {
+ memcpy(newObjv+handlerObjc, objv, sizeof(Tcl_Obj *) * (unsigned)objc);
- /*
- * If there was an error, a command string will be needed for the
- * error log: generate it now if it was not done previously.
+ /*
+ * Look up and invoke the handler (by recursive call to this
+ * function). If there is no handler at all, instead of doing the
+ * recursive call we just generate a generic error message; it would
+ * be an infinite-recursion nightmare otherwise.
*/
- if (cmdLen == 0) {
- Tcl_DStringInit(&cmdBuf);
- for (i = 0; i < objc; i++) {
- Tcl_DStringAppendElement(&cmdBuf, Tcl_GetString(objv[i]));
- }
- cmdString = Tcl_DStringValue(&cmdBuf);
- cmdLen = Tcl_DStringLength(&cmdBuf);
+ cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, newObjv[0]);
+ if (cmdPtr == NULL) {
+ Tcl_AppendResult(interp, "invalid command name \"",
+ TclGetString(objv[0]), "\"", NULL);
+ code = TCL_ERROR;
+ } else {
+ iPtr->numLevels++;
+ code = TclEvalObjvInternal(interp, newObjc, newObjv, command,
+ length, 0);
+ iPtr->numLevels--;
}
- Tcl_LogCommandInfo(interp, cmdString, cmdString, cmdLen);
- }
- if (cmdLen != 0) {
- Tcl_DStringFree(&cmdBuf);
+ /*
+ * Release any resources we locked and allocated during the handler
+ * call.
+ */
+
+ for (i = 0; i < handlerObjc; ++i) {
+ Tcl_DecrRefCount(newObjv[i]);
+ }
+ TclStackFree(interp, newObjv);
+ if (savedNsPtr) {
+ varFramePtr->nsPtr = savedNsPtr;
+ }
+ goto done;
}
- return code;
}
/*
*----------------------------------------------------------------------
*
- * Tcl_LogCommandInfo --
+ * Tcl_EvalObjv --
*
- * This procedure is invoked after an error occurs in an interpreter.
- * It adds information to the "errorInfo" variable to describe the
- * command that was being executed when the error occurred.
+ * This function evaluates a Tcl command that has already been parsed
+ * into words, with one Tcl_Obj holding each word.
*
* Results:
- * None.
+ * The return value is a standard Tcl completion code such as TCL_OK or
+ * TCL_ERROR. A result or error message is left in interp's result.
*
* Side effects:
- * Information about the command is added to errorInfo and the
- * line number stored internally in the interpreter is set. If this
- * is the first call to this procedure or Tcl_AddObjErrorInfo since
- * an error occurred, then old information in errorInfo is
- * deleted.
+ * Depends on the command.
*
*----------------------------------------------------------------------
*/
-void
-Tcl_LogCommandInfo(interp, script, command, length)
- Tcl_Interp *interp; /* Interpreter in which to log information. */
- CONST char *script; /* First character in script containing
- * command (must be <= command). */
- CONST char *command; /* First character in command that
- * generated the error. */
- int length; /* Number of bytes in command (-1 means
- * use all bytes up to first null byte). */
+int
+Tcl_EvalObjv(
+ Tcl_Interp *interp, /* Interpreter in which to evaluate the
+ * command. Also used for error reporting. */
+ int objc, /* Number of words in command. */
+ Tcl_Obj *const objv[], /* An array of pointers to objects that are
+ * the words that make up the command. */
+ int flags) /* Collection of OR-ed bits that control the
+ * evaluation of the script. Only
+ * TCL_EVAL_GLOBAL and TCL_EVAL_INVOKE are
+ * currently supported. */
{
- char buffer[200];
- register CONST char *p;
- char *ellipsis = "";
Interp *iPtr = (Interp *) interp;
+ int code = TCL_OK;
+ int allowExceptions = (iPtr->evalFlags & TCL_ALLOW_EXCEPTIONS);
+
+ iPtr->numLevels++;
+ code = TclEvalObjvInternal(interp, objc, objv, NULL, 0, flags);
+ iPtr->numLevels--;
+
+ if (code == TCL_OK) {
+ return code;
+ } else {
- if (iPtr->flags & ERR_ALREADY_LOGGED) {
/*
- * Someone else has already logged error information for this
- * command; we shouldn't add anything more.
+ * If we are again at the top level, process any unusual return code
+ * returned by the evaluated code.
*/
- return;
- }
+ if (iPtr->numLevels == 0) {
+ if (code == TCL_RETURN) {
+ code = TclUpdateReturnInfo(iPtr);
+ }
+ if ((code != TCL_ERROR) && !allowExceptions) {
+ ProcessUnexpectedResult(interp, code);
+ code = TCL_ERROR;
+ }
+ }
- /*
- * Compute the line number where the error occurred.
- */
+ if ((code == TCL_ERROR) && !(flags & TCL_EVAL_INVOKE)) {
+ /*
+ * If there was an error, a command string will be needed for the
+ * error log: generate it now. Do not worry too much about doing
+ * it expensively.
+ */
- iPtr->errorLine = 1;
- for (p = script; p != command; p++) {
- if (*p == '\n') {
- iPtr->errorLine++;
- }
- }
+ Tcl_Obj *listPtr;
+ char *cmdString;
+ int cmdLen;
- /*
- * Create an error message to add to errorInfo, including up to a
- * maximum number of characters of the command.
- */
+ listPtr = Tcl_NewListObj(objc, objv);
+ cmdString = Tcl_GetStringFromObj(listPtr, &cmdLen);
+ Tcl_LogCommandInfo(interp, cmdString, cmdString, cmdLen);
+ Tcl_DecrRefCount(listPtr);
+ }
- if (length < 0) {
- length = strlen(command);
- }
- if (length > 150) {
- length = 150;
- ellipsis = "...";
- }
- while ( (command[length] & 0xC0) == 0x80 ) {
- /*
- * Back up truncation point so that we don't truncate in the
- * middle of a multi-byte character (in UTF-8)
- */
- length--;
- ellipsis = "...";
- }
- if (!(iPtr->flags & ERR_IN_PROGRESS)) {
- sprintf(buffer, "\n while executing\n\"%.*s%s\"",
- length, command, ellipsis);
- } else {
- sprintf(buffer, "\n invoked from within\n\"%.*s%s\"",
- length, command, ellipsis);
+ return code;
}
- Tcl_AddObjErrorInfo(interp, buffer, -1);
- iPtr->flags &= ~ERR_ALREADY_LOGGED;
}
/*
*----------------------------------------------------------------------
*
- * Tcl_EvalTokensStandard, EvalTokensStandard --
+ * Tcl_EvalTokensStandard --
+ *
+ * Given an array of tokens parsed from a Tcl command (e.g., the tokens
+ * that make up a word or the index for an array variable) this function
+ * evaluates the tokens and concatenates their values to form a single
+ * result value.
*
- * Given an array of tokens parsed from a Tcl command (e.g., the
- * tokens that make up a word or the index for an array variable)
- * this procedure evaluates the tokens and concatenates their
- * values to form a single result value.
- *
* Results:
- * The return value is a standard Tcl completion code such as
- * TCL_OK or TCL_ERROR. A result or error message is left in
- * interp's result.
+ * The return value is a standard Tcl completion code such as TCL_OK or
+ * TCL_ERROR. A result or error message is left in interp's result.
*
* Side effects:
* Depends on the array of tokens being evaled.
*
- * TIP #280 : Keep public API, internally extended API.
*----------------------------------------------------------------------
*/
int
-Tcl_EvalTokensStandard(interp, tokenPtr, count)
- Tcl_Interp *interp; /* Interpreter in which to lookup
- * variables, execute nested commands,
- * and report errors. */
- Tcl_Token *tokenPtr; /* Pointer to first in an array of tokens
- * to evaluate and concatenate. */
- int count; /* Number of tokens to consider at tokenPtr.
+Tcl_EvalTokensStandard(
+ Tcl_Interp *interp, /* Interpreter in which to lookup variables,
+ * execute nested commands, and report
+ * errors. */
+ Tcl_Token *tokenPtr, /* Pointer to first in an array of tokens to
+ * evaluate and concatenate. */
+ int count) /* Number of tokens to consider at tokenPtr.
* Must be at least 1. */
{
-#ifdef TCL_TIP280
- return EvalTokensStandard (interp, tokenPtr, count, 1, NULL, NULL);
-}
-
-static int
-EvalTokensStandard(interp, tokenPtr, count, line, clNextOuter, outerScript)
- Tcl_Interp *interp; /* Interpreter in which to lookup
- * variables, execute nested commands,
- * and report errors. */
- Tcl_Token *tokenPtr; /* Pointer to first in an array of tokens
- * to evaluate and concatenate. */
- int count; /* Number of tokens to consider at tokenPtr.
- * Must be at least 1. */
- int line; /* The line the script starts on. */
- int* clNextOuter; /* Information about an outer context for */
- CONST char* outerScript; /* continuation line data. This is set by
- * EvalEx() to properly handle [...]-nested
- * commands. The 'outerScript' refers to the
- * most-outer script containing the embedded
- * command, which is refered to by 'script'. The
- * 'clNextOuter' refers to the current entry in
- * the table of continuation lines in this
- * "master script", and the character offsets are
- * relative to the 'outerScript' as well.
- *
- * If outerScript == script, then this call is for
- * words in the outer-most script/command. See
- * Tcl_EvalEx() and TclEvalObjEx() for the places
- * generating arguments for which this is true.
- */
-{
-#endif
- Tcl_Obj *resultPtr, *indexPtr, *valuePtr;
- char buffer[TCL_UTF_MAX];
-#ifdef TCL_MEM_DEBUG
-# define MAX_VAR_CHARS 5
-#else
-# define MAX_VAR_CHARS 30
-#endif
- char nameBuffer[MAX_VAR_CHARS+1];
- char *varName, *index;
- CONST char *p = NULL; /* Initialized to avoid compiler warning. */
- int length, code;
-#ifdef TCL_TIP280
-#define NUM_STATIC_POS 20
- int isLiteral, maxNumCL, numCL, i, adjust;
- int* clPosition = NULL;
- Interp* iPtr = (Interp*) interp;
- int inFile = iPtr->evalFlags & TCL_EVAL_FILE;
-#endif
-
- /*
- * The only tricky thing about this procedure is that it attempts to
- * avoid object creation and string copying whenever possible. For
- * example, if the value is just a nested command, then use the
- * command's result object directly.
- */
-
- code = TCL_OK;
- resultPtr = NULL;
- Tcl_ResetResult(interp);
-#ifdef TCL_TIP280
- /*
- * For the handling of continuation lines in literals we first check if
- * this is actually a literal. For if not we can forego the additional
- * processing. Otherwise we pre-allocate a small table to store the
- * locations of all continuation lines we find in this literal, if
- * any. The table is extended if needed.
- */
-
- numCL = 0;
- maxNumCL = 0;
- isLiteral = 1;
- for (i=0 ; i < count; i++) {
- if ((tokenPtr[i].type != TCL_TOKEN_TEXT) &&
- (tokenPtr[i].type != TCL_TOKEN_BS)) {
- isLiteral = 0;
- break;
- }
- }
-
- if (isLiteral) {
- maxNumCL = NUM_STATIC_POS;
- clPosition = (int*) ckalloc (maxNumCL*sizeof(int));
- }
- adjust = 0;
-#endif
- for ( ; count > 0; count--, tokenPtr++) {
- valuePtr = NULL;
-
- /*
- * The switch statement below computes the next value to be
- * concat to the result, as either a range of text or an
- * object.
- */
-
- switch (tokenPtr->type) {
- case TCL_TOKEN_TEXT:
- p = tokenPtr->start;
- length = tokenPtr->size;
- break;
-
- case TCL_TOKEN_BS:
- length = TclParseBackslash(tokenPtr->start, tokenPtr->size,
- (int *) NULL, buffer);
- p = buffer;
-#ifdef TCL_TIP280
- /*
- * If the backslash sequence we found is in a literal, and
- * represented a continuation line, we compute and store its
- * location (as char offset to the beginning of the _result_
- * script). We may have to extend the table of locations.
- *
- * Note that the continuation line information is relevant
- * even if the word we are processing is not a literal, as it
- * can affect nested commands. See the branch for
- * TCL_TOKEN_COMMAND below, where the adjustment we are
- * tracking here is taken into account. The good thing is that
- * we do not need a table of everything, just the number of
- * lines we have to add as correction.
- */
-
- if ((length == 1) && (buffer[0] == ' ') &&
- (tokenPtr->start[1] == '\n')) {
- if (isLiteral) {
- int clPos;
- if (resultPtr == 0) {
- clPos = 0;
- } else {
- Tcl_GetStringFromObj(resultPtr, &clPos);
- }
-
- if (numCL >= maxNumCL) {
- maxNumCL *= 2;
- clPosition = (int*) ckrealloc ((char*)clPosition,
- maxNumCL*sizeof(int));
- }
- clPosition[numCL] = clPos;
- numCL ++;
- }
- adjust ++;
- }
-#endif
- break;
-
- case TCL_TOKEN_COMMAND: {
- Interp *iPtr = (Interp *) interp;
- iPtr->numLevels++;
- code = TclInterpReady(interp);
- if (code == TCL_OK) {
-#ifndef TCL_TIP280
- code = Tcl_EvalEx(interp,
- tokenPtr->start+1, tokenPtr->size-2, 0);
-#else
- /* TIP #280: Transfer line information to nested command */
- TclAdvanceContinuations (&line, &clNextOuter,
- tokenPtr->start - outerScript);
- code = EvalEx(interp,
- tokenPtr->start+1, tokenPtr->size-2, 0,
- line + adjust, clNextOuter, outerScript);
-
- /*
- * Restore flag reset by the nested eval for future
- * bracketed commands and their CmdFrame setup
- */
- if (inFile) {
- iPtr->evalFlags |= TCL_EVAL_FILE;
- }
-#endif
- }
- iPtr->numLevels--;
- if (code != TCL_OK) {
- goto done;
- }
- valuePtr = Tcl_GetObjResult(interp);
- break;
- }
-
- case TCL_TOKEN_VARIABLE:
- if (tokenPtr->numComponents == 1) {
- indexPtr = NULL;
- index = NULL;
- } else {
-#ifndef TCL_TIP280
- code = Tcl_EvalTokensStandard(interp, tokenPtr+2,
- tokenPtr->numComponents - 1);
-#else
- /* TIP #280: Transfer line information to nested command */
- code = EvalTokensStandard(interp, tokenPtr+2,
- tokenPtr->numComponents - 1, line, NULL, NULL);
-#endif
- if (code != TCL_OK) {
- goto done;
- }
- indexPtr = Tcl_GetObjResult(interp);
- Tcl_IncrRefCount(indexPtr);
- index = Tcl_GetString(indexPtr);
- }
-
- /*
- * We have to make a copy of the variable name in order
- * to have a null-terminated string. We can't make a
- * temporary modification to the script to null-terminate
- * the name, because a trace callback might potentially
- * reuse the script and be affected by the null character.
- */
-
- if (tokenPtr[1].size <= MAX_VAR_CHARS) {
- varName = nameBuffer;
- } else {
- varName = ckalloc((unsigned) (tokenPtr[1].size + 1));
- }
- strncpy(varName, tokenPtr[1].start, (size_t) tokenPtr[1].size);
- varName[tokenPtr[1].size] = 0;
- valuePtr = Tcl_GetVar2Ex(interp, varName, index,
- TCL_LEAVE_ERR_MSG);
- if (varName != nameBuffer) {
- ckfree(varName);
- }
- if (indexPtr != NULL) {
- Tcl_DecrRefCount(indexPtr);
- }
- if (valuePtr == NULL) {
- code = TCL_ERROR;
- goto done;
- }
- count -= tokenPtr->numComponents;
- tokenPtr += tokenPtr->numComponents;
- break;
-
- default:
- panic("unexpected token type in Tcl_EvalTokensStandard");
- }
-
- /*
- * If valuePtr isn't NULL, the next piece of text comes from that
- * object; otherwise, take length bytes starting at p.
- */
-
- if (resultPtr == NULL) {
- if (valuePtr != NULL) {
- resultPtr = valuePtr;
- } else {
- resultPtr = Tcl_NewStringObj(p, length);
- }
- Tcl_IncrRefCount(resultPtr);
- } else {
- if (Tcl_IsShared(resultPtr)) {
- Tcl_DecrRefCount(resultPtr);
- resultPtr = Tcl_DuplicateObj(resultPtr);
- Tcl_IncrRefCount(resultPtr);
- }
- if (valuePtr != NULL) {
- p = Tcl_GetStringFromObj(valuePtr, &length);
- }
- Tcl_AppendToObj(resultPtr, p, length);
- }
- }
- if (resultPtr != NULL) {
- Tcl_SetObjResult(interp, resultPtr);
-#ifdef TCL_TIP280
- /*
- * If the code found continuation lines (which implies that this word
- * is a literal), then we store the accumulated table of locations in
- * the thread-global data structure for the bytecode compiler to find
- * later, assuming that the literal is a script which will be
- * compiled.
- */
-
- if (numCL) {
- TclContinuationsEnter(resultPtr, numCL, clPosition);
- }
-
- /*
- * Release the temp table we used to collect the locations of
- * continuation lines, if any.
- */
-
- if (maxNumCL) {
- ckfree ((char*) clPosition);
- }
-#endif
- } else {
- code = TCL_ERROR;
- }
-
- done:
- if (resultPtr != NULL) {
- Tcl_DecrRefCount(resultPtr);
- }
- return code;
+ return TclSubstTokens(interp, tokenPtr, count, /* numLeftPtr */ NULL, 1,
+ NULL, NULL);
}
/*
@@ -3850,67 +3980,62 @@ EvalTokensStandard(interp, tokenPtr, count, line, clNextOuter, outerScript)
*
* Tcl_EvalTokens --
*
- * Given an array of tokens parsed from a Tcl command (e.g., the
- * tokens that make up a word or the index for an array variable)
- * this procedure evaluates the tokens and concatenates their
- * values to form a single result value.
+ * Given an array of tokens parsed from a Tcl command (e.g., the tokens
+ * that make up a word or the index for an array variable) this function
+ * evaluates the tokens and concatenates their values to form a single
+ * result value.
*
* Results:
- * The return value is a pointer to a newly allocated Tcl_Obj
- * containing the value of the array of tokens. The reference
- * count of the returned object has been incremented. If an error
- * occurs in evaluating the tokens then a NULL value is returned
- * and an error message is left in interp's result.
+ * The return value is a pointer to a newly allocated Tcl_Obj containing
+ * the value of the array of tokens. The reference count of the returned
+ * object has been incremented. If an error occurs in evaluating the
+ * tokens then a NULL value is returned and an error message is left in
+ * interp's result.
*
* Side effects:
* A new object is allocated to hold the result.
*
*----------------------------------------------------------------------
*
- * This uses a non-standard return convention; its use is now deprecated.
- * It is a wrapper for the new function Tcl_EvalTokensStandard, and is not
- * used in the core any longer. It is only kept for backward compatibility.
+ * This uses a non-standard return convention; its use is now deprecated. It
+ * is a wrapper for the new function Tcl_EvalTokensStandard, and is not used
+ * in the core any longer. It is only kept for backward compatibility.
*/
Tcl_Obj *
-Tcl_EvalTokens(interp, tokenPtr, count)
- Tcl_Interp *interp; /* Interpreter in which to lookup
- * variables, execute nested commands,
- * and report errors. */
- Tcl_Token *tokenPtr; /* Pointer to first in an array of tokens
- * to evaluate and concatenate. */
- int count; /* Number of tokens to consider at tokenPtr.
+Tcl_EvalTokens(
+ Tcl_Interp *interp, /* Interpreter in which to lookup variables,
+ * execute nested commands, and report
+ * errors. */
+ Tcl_Token *tokenPtr, /* Pointer to first in an array of tokens to
+ * evaluate and concatenate. */
+ int count) /* Number of tokens to consider at tokenPtr.
* Must be at least 1. */
{
- int code;
Tcl_Obj *resPtr;
-
- code = Tcl_EvalTokensStandard(interp, tokenPtr, count);
- if (code == TCL_OK) {
- resPtr = Tcl_GetObjResult(interp);
- Tcl_IncrRefCount(resPtr);
- Tcl_ResetResult(interp);
- return resPtr;
- } else {
+
+ if (Tcl_EvalTokensStandard(interp, tokenPtr, count) != TCL_OK) {
return NULL;
}
+ resPtr = Tcl_GetObjResult(interp);
+ Tcl_IncrRefCount(resPtr);
+ Tcl_ResetResult(interp);
+ return resPtr;
}
-
/*
*----------------------------------------------------------------------
*
- * Tcl_EvalEx, EvalEx --
+ * Tcl_EvalEx, TclEvalEx --
*
- * This procedure evaluates a Tcl script without using the compiler
- * or byte-code interpreter. It just parses the script, creates
- * values for each word of each command, then calls EvalObjv
- * to execute each command.
+ * This function evaluates a Tcl script without using the compiler or
+ * byte-code interpreter. It just parses the script, creates values for
+ * each word of each command, then calls EvalObjv to execute each
+ * command.
*
* Results:
- * The return value is a standard Tcl completion code such as
- * TCL_OK or TCL_ERROR. A result or error message is left in
- * interp's result.
+ * The return value is a standard Tcl completion code such as TCL_OK or
+ * TCL_ERROR. A result or error message is left in interp's result.
*
* Side effects:
* Depends on the script.
@@ -3920,38 +4045,35 @@ Tcl_EvalTokens(interp, tokenPtr, count)
*/
int
-Tcl_EvalEx(interp, script, numBytes, flags)
- Tcl_Interp *interp; /* Interpreter in which to evaluate the
- * script. Also used for error reporting. */
- CONST char *script; /* First character of script to evaluate. */
- int numBytes; /* Number of bytes in script. If < 0, the
+Tcl_EvalEx(
+ Tcl_Interp *interp, /* Interpreter in which to evaluate the
+ * script. Also used for error reporting. */
+ const char *script, /* First character of script to evaluate. */
+ int numBytes, /* Number of bytes in script. If < 0, the
* script consists of all bytes up to the
* first null character. */
- int flags; /* Collection of OR-ed bits that control
- * the evaluation of the script. Only
- * TCL_EVAL_GLOBAL is currently
- * supported. */
+ int flags) /* Collection of OR-ed bits that control the
+ * evaluation of the script. Only
+ * TCL_EVAL_GLOBAL is currently supported. */
{
-#ifdef TCL_TIP280
- return EvalEx (interp, script, numBytes, flags, 1, NULL, script);
+ return TclEvalEx(interp, script, numBytes, flags, 1, NULL, script);
}
-static int
-EvalEx(interp, script, numBytes, flags, line, clNextOuter, outerScript)
- Tcl_Interp *interp; /* Interpreter in which to evaluate the
- * script. Also used for error reporting. */
- CONST char *script; /* First character of script to evaluate. */
- int numBytes; /* Number of bytes in script. If < 0, the
+int
+TclEvalEx(
+ Tcl_Interp *interp, /* Interpreter in which to evaluate the
+ * script. Also used for error reporting. */
+ const char *script, /* First character of script to evaluate. */
+ int numBytes, /* Number of bytes in script. If < 0, the
* script consists of all bytes up to the
- * first null character. */
- int flags; /* Collection of OR-ed bits that control
- * the evaluation of the script. Only
- * TCL_EVAL_GLOBAL is currently
- * supported. */
- int line; /* The line the script starts on. */
- int* clNextOuter; /* Information about an outer context for */
- CONST char* outerScript; /* continuation line data. This is set only in
- * EvalTokensStandard(), to properly handle
+ * first NUL character. */
+ int flags, /* Collection of OR-ed bits that control the
+ * evaluation of the script. Only
+ * TCL_EVAL_GLOBAL is currently supported. */
+ int line, /* The line the script starts on. */
+ int* clNextOuter, /* Information about an outer context for */
+ CONST char* outerScript) /* continuation line data. This is set only in
+ * TclSubstTokens(), to properly handle
* [...]-nested commands. The 'outerScript'
* refers to the most-outer script containing the
* embedded command, which is refered to by
@@ -3967,31 +4089,32 @@ EvalEx(interp, script, numBytes, flags, line, clNextOuter, outerScript)
* generating arguments for which this is true.
*/
{
-#endif
Interp *iPtr = (Interp *) interp;
- CONST char *p, *next;
- Tcl_Parse parse;
-#define NUM_STATIC_OBJS 20
- Tcl_Obj *staticObjArray[NUM_STATIC_OBJS], **objv;
+ const char *p, *next;
+ const unsigned int minObjs = 20;
+ Tcl_Obj **objv, **objvSpace;
+ int *expand, *lines, *lineSpace;
Tcl_Token *tokenPtr;
- int code = TCL_OK;
- int i, commandLength, bytesLeft, nested;
- CallFrame *savedVarFramePtr; /* Saves old copy of iPtr->varFramePtr
- * in case TCL_EVAL_GLOBAL was set. */
+ int commandLength, bytesLeft, expandRequested, code = TCL_OK;
+ CallFrame *savedVarFramePtr;/* Saves old copy of iPtr->varFramePtr in case
+ * TCL_EVAL_GLOBAL was set. */
int allowExceptions = (iPtr->evalFlags & TCL_ALLOW_EXCEPTIONS);
-
- /*
- * The variables below keep track of how much state has been
- * allocated while evaluating the script, so that it can be freed
- * properly if an error occurs.
- */
-
- int gotParse = 0, objectsUsed = 0;
-
-#ifdef TCL_TIP280
- /* TIP #280 Structures for tracking of command locations. */
- CmdFrame eeFrame;
-
+ int gotParse = 0;
+ unsigned int i, objectsUsed = 0;
+ /* These variables keep track of how much
+ * state has been allocated while evaluating
+ * the script, so that it can be freed
+ * properly if an error occurs. */
+ Tcl_Parse *parsePtr = (Tcl_Parse *)
+ TclStackAlloc(interp, sizeof(Tcl_Parse));
+ CmdFrame *eeFramePtr = (CmdFrame *)
+ TclStackAlloc(interp, sizeof(CmdFrame));
+ Tcl_Obj **stackObjArray = (Tcl_Obj **)
+ TclStackAlloc(interp, minObjs * sizeof(Tcl_Obj *));
+ int *expandStack = (int *) TclStackAlloc(interp, minObjs * sizeof(int));
+ int *linesStack = (int *) TclStackAlloc(interp, minObjs * sizeof(int));
+ /* TIP #280 Structures for tracking of command
+ * locations. */
/*
* Pointer for the tracking of invisible continuation lines. Initialized
* only if the caller gave us a table of locations to track, via
@@ -4009,7 +4132,6 @@ EvalEx(interp, script, numBytes, flags, line, clNextOuter, outerScript)
clNext = &iPtr->scriptCLLocPtr->loc[0];
}
}
-#endif
if (numBytes < 0) {
numBytes = strlen(script);
@@ -4018,112 +4140,102 @@ EvalEx(interp, script, numBytes, flags, line, clNextOuter, outerScript)
savedVarFramePtr = iPtr->varFramePtr;
if (flags & TCL_EVAL_GLOBAL) {
- iPtr->varFramePtr = NULL;
+ iPtr->varFramePtr = iPtr->rootFramePtr;
}
/*
- * Each iteration through the following loop parses the next
- * command from the script and then executes it.
+ * Each iteration through the following loop parses the next command from
+ * the script and then executes it.
*/
- objv = staticObjArray;
+ objv = objvSpace = stackObjArray;
+ lines = lineSpace = linesStack;
+ expand = expandStack;
p = script;
bytesLeft = numBytes;
- if (iPtr->evalFlags & TCL_BRACKET_TERM) {
- nested = 1;
- } else {
- nested = 0;
- }
-#ifdef TCL_TIP280
- /* TIP #280 Initialize tracking. Do not push on the frame stack yet. */
/*
- * We may cont. 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.
+ * 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.
*/
if (iPtr->evalFlags & TCL_EVAL_CTX) {
- /* Path information comes out of the context. */
+ /*
+ * Path information comes out of the context.
+ */
- eeFrame.type = TCL_LOCATION_SOURCE;
- eeFrame.data.eval.path = iPtr->invokeCmdFramePtr->data.eval.path;
- Tcl_IncrRefCount (eeFrame.data.eval.path);
+ 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) {
- /* Set up for a sourced file */
+ /*
+ * Set up for a sourced file.
+ */
- eeFrame.type = TCL_LOCATION_SOURCE;
+ eeFramePtr->type = TCL_LOCATION_SOURCE;
if (iPtr->scriptFile) {
- /* Normalization here, to have the correct pwd. Should have
+ /*
+ * Normalization here, to have the correct pwd. Should have
* negligible impact on performance, as the norm should have been
* done already by the 'source' invoking us, and it caches the
- * result
+ * result.
*/
- Tcl_Obj* norm = Tcl_FSGetNormalizedPath (interp, iPtr->scriptFile);
- if (!norm) {
- /* Error message in the interp result */
- return TCL_ERROR;
+ Tcl_Obj *norm = Tcl_FSGetNormalizedPath(interp, iPtr->scriptFile);
+
+ if (norm == NULL) {
+ /*
+ * Error message in the interp result.
+ */
+ code = TCL_ERROR;
+ goto error;
}
- eeFrame.data.eval.path = norm;
+ eeFramePtr->data.eval.path = norm;
} else {
- eeFrame.data.eval.path = Tcl_NewStringObj ("",-1);
+ TclNewLiteralStringObj(eeFramePtr->data.eval.path, "");
}
- Tcl_IncrRefCount (eeFrame.data.eval.path);
+ Tcl_IncrRefCount(eeFramePtr->data.eval.path);
} else {
- /* Set up for plain eval */
+ /*
+ * Set up for plain eval.
+ */
- eeFrame.type = TCL_LOCATION_EVAL;
- eeFrame.data.eval.path = NULL;
+ eeFramePtr->type = TCL_LOCATION_EVAL;
+ eeFramePtr->data.eval.path = NULL;
}
- eeFrame.level = (iPtr->cmdFramePtr == NULL
- ? 1
- : iPtr->cmdFramePtr->level + 1);
- eeFrame.framePtr = iPtr->framePtr;
- eeFrame.nextPtr = iPtr->cmdFramePtr;
- eeFrame.nline = 0;
- eeFrame.line = NULL;
-#endif
+ eeFramePtr->level = iPtr->cmdFramePtr ? iPtr->cmdFramePtr->level + 1 : 1;
+ eeFramePtr->framePtr = iPtr->framePtr;
+ eeFramePtr->nextPtr = iPtr->cmdFramePtr;
+ eeFramePtr->nline = 0;
+ eeFramePtr->line = NULL;
iPtr->evalFlags = 0;
do {
- if (Tcl_ParseCommand(interp, p, bytesLeft, nested, &parse)
- != TCL_OK) {
+ if (Tcl_ParseCommand(interp, p, bytesLeft, 0, parsePtr) != TCL_OK) {
code = TCL_ERROR;
goto error;
}
- gotParse = 1;
-
- if (nested && parse.term == (script + numBytes)) {
- /*
- * A nested script can only terminate in ']'. If
- * the parsing got terminated at the end of the script,
- * there was no closing ']'. Report the syntax error.
- */
- code = TCL_ERROR;
- goto error;
- }
-
-#ifdef TCL_TIP280
/*
* TIP #280 Track lines. The parser may have skipped text till it
- * found the command we are now at. We have count the lines in this
+ * found the command we are now at. We have to count the lines in this
* block, and do not forget invisible continuation lines.
*/
- TclAdvanceLines (&line, p, parse.commandStart);
+ TclAdvanceLines(&line, p, parsePtr->commandStart);
TclAdvanceContinuations (&line, &clNext,
- parse.commandStart - outerScript);
-#endif
+ parsePtr->commandStart - outerScript);
- if (parse.numWords > 0) {
-#ifdef TCL_TIP280
+ gotParse = 1;
+ if (parsePtr->numWords > 0) {
/*
* TIP #280. Track lines within the words of the current
* command. We use a separate pointer into the table of
@@ -4131,77 +4243,138 @@ EvalEx(interp, script, numBytes, flags, line, clNextOuter, outerScript)
* per-command parsing.
*/
- int wordLine = line;
- CONST char* wordStart = parse.commandStart;
+ int wordLine = line;
+ const char *wordStart = parsePtr->commandStart;
int* wordCLNext = clNext;
-#endif
/*
* Generate an array of objects for the words of the command.
*/
-
- if (parse.numWords <= NUM_STATIC_OBJS) {
- objv = staticObjArray;
- } else {
- objv = (Tcl_Obj **) ckalloc((unsigned)
- (parse.numWords * sizeof (Tcl_Obj *)));
- }
-#ifdef TCL_TIP280
- eeFrame.nline = parse.numWords;
- eeFrame.line = (int*) ckalloc((unsigned)
- (parse.numWords * sizeof (int)));
-#endif
+ unsigned int objectsNeeded = 0;
+ unsigned int numWords = parsePtr->numWords;
- for (objectsUsed = 0, tokenPtr = parse.tokenPtr;
- objectsUsed < parse.numWords;
- objectsUsed++, tokenPtr += (tokenPtr->numComponents + 1)) {
-#ifndef TCL_TIP280
- code = Tcl_EvalTokensStandard(interp, tokenPtr+1,
- tokenPtr->numComponents);
-#else
- /*
- * TIP #280. Track lines to current word. Save the
- * information on a per-word basis, signaling dynamic words as
- * needed. Make the information available to the recursively
- * called evaluator as well, including the type of context
- * (source vs. eval).
+ if (numWords > minObjs) {
+ expand = (int *) ckalloc(numWords * sizeof(int));
+ objvSpace = (Tcl_Obj **)
+ ckalloc(numWords * sizeof(Tcl_Obj *));
+ lineSpace = (int *) ckalloc(numWords * sizeof(int));
+ }
+ expandRequested = 0;
+ objv = objvSpace;
+ lines = lineSpace;
+
+ for (objectsUsed = 0, tokenPtr = parsePtr->tokenPtr;
+ objectsUsed < numWords;
+ objectsUsed++, tokenPtr += tokenPtr->numComponents+1) {
+ /*
+ * TIP #280. Track lines to current word. Save the information
+ * on a per-word basis, signaling dynamic words as needed.
+ * Make the information available to the recursively called
+ * evaluator as well, including the type of context (source
+ * vs. eval).
*/
- TclAdvanceLines (&wordLine, wordStart, tokenPtr->start);
+ TclAdvanceLines(&wordLine, wordStart, tokenPtr->start);
TclAdvanceContinuations (&wordLine, &wordCLNext,
tokenPtr->start - outerScript);
wordStart = tokenPtr->start;
- eeFrame.line [objectsUsed] = (TclWordKnownAtCompileTime (tokenPtr)
- ? wordLine
- : -1);
+ lines[objectsUsed] = TclWordKnownAtCompileTime(tokenPtr, NULL)
+ ? wordLine : -1;
- if (eeFrame.type == TCL_LOCATION_SOURCE) {
+ if (eeFramePtr->type == TCL_LOCATION_SOURCE) {
iPtr->evalFlags |= TCL_EVAL_FILE;
}
- code = EvalTokensStandard(interp, tokenPtr+1,
- tokenPtr->numComponents, wordLine,
- wordCLNext, outerScript);
+ code = TclSubstTokens(interp, tokenPtr+1,
+ tokenPtr->numComponents, NULL, wordLine,
+ wordCLNext, outerScript);
iPtr->evalFlags = 0;
-#endif
- if (code == TCL_OK) {
- objv[objectsUsed] = Tcl_GetObjResult(interp);
- Tcl_IncrRefCount(objv[objectsUsed]);
-#ifdef TCL_TIP280
- if (wordCLNext) {
- TclContinuationsEnterDerived (objv[objectsUsed],
- wordStart - outerScript, wordCLNext);
+ if (code != TCL_OK) {
+ goto error;
+ }
+ objv[objectsUsed] = Tcl_GetObjResult(interp);
+ Tcl_IncrRefCount(objv[objectsUsed]);
+ if (tokenPtr->type == TCL_TOKEN_EXPAND_WORD) {
+ int numElements;
+
+ code = TclListObjLength(interp, objv[objectsUsed],
+ &numElements);
+ if (code == TCL_ERROR) {
+ /*
+ * Attempt to expand a non-list.
+ */
+
+ Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+ "\n (expanding word %d)", objectsUsed));
+ Tcl_DecrRefCount(objv[objectsUsed]);
+ goto error;
}
-#endif
+ expandRequested = 1;
+ expand[objectsUsed] = 1;
+
+ objectsNeeded += (numElements ? numElements : 1);
} else {
- goto error;
+ expand[objectsUsed] = 0;
+ objectsNeeded++;
+ }
+
+ if (wordCLNext) {
+ TclContinuationsEnterDerived (objv[objectsUsed],
+ wordStart - outerScript, wordCLNext);
+ }
+ } /* for loop */
+ if (expandRequested) {
+ /*
+ * Some word expansion was requested. Check for objv resize.
+ */
+
+ Tcl_Obj **copy = objvSpace;
+ int *lcopy = lineSpace;
+ int wordIdx = numWords;
+ int objIdx = objectsNeeded - 1;
+
+ if ((numWords > minObjs) || (objectsNeeded > minObjs)) {
+ objv = objvSpace = (Tcl_Obj **)
+ ckalloc(objectsNeeded * sizeof(Tcl_Obj *));
+ lines = lineSpace = (int *)
+ ckalloc(objectsNeeded * sizeof(int));
+ }
+
+ objectsUsed = 0;
+ while (wordIdx--) {
+ if (expand[wordIdx]) {
+ int numElements;
+ Tcl_Obj **elements, *temp = copy[wordIdx];
+
+ Tcl_ListObjGetElements(NULL, temp, &numElements,
+ &elements);
+ objectsUsed += numElements;
+ while (numElements--) {
+ lines[objIdx] = -1;
+ objv[objIdx--] = elements[numElements];
+ Tcl_IncrRefCount(elements[numElements]);
+ }
+ Tcl_DecrRefCount(temp);
+ } else {
+ lines[objIdx] = lcopy[wordIdx];
+ objv[objIdx--] = copy[wordIdx];
+ objectsUsed++;
+ }
+ }
+ objv += objIdx+1;
+
+ if (copy != stackObjArray) {
+ ckfree((char *) copy);
+ }
+ if (lcopy != linesStack) {
+ ckfree((char *) lcopy);
}
}
-
+
/*
* Execute the command and free the objects for its words.
*
@@ -4212,29 +4385,28 @@ EvalEx(interp, script, numBytes, flags, line, clNextOuter, outerScript)
* have been executed.
*/
-#ifdef TCL_TIP280
- eeFrame.cmd.str.cmd = parse.commandStart;
- eeFrame.cmd.str.len = parse.commandSize;
+ eeFramePtr->cmd.str.cmd = parsePtr->commandStart;
+ eeFramePtr->cmd.str.len = parsePtr->commandSize;
- if (parse.term == parse.commandStart + parse.commandSize - 1) {
- eeFrame.cmd.str.len --;
+ if (parsePtr->term ==
+ parsePtr->commandStart + parsePtr->commandSize - 1) {
+ eeFramePtr->cmd.str.len--;
}
- TclArgumentEnter (interp, objv, objectsUsed, &eeFrame);
- iPtr->cmdFramePtr = &eeFrame;
-#endif
- iPtr->numLevels++;
- code = TclEvalObjvInternal(interp, objectsUsed, objv,
- parse.commandStart, parse.commandSize, 0);
+ eeFramePtr->nline = objectsUsed;
+ eeFramePtr->line = lines;
+
+ TclArgumentEnter (interp, objv, objectsUsed, eeFramePtr);
+ iPtr->cmdFramePtr = eeFramePtr;
+ iPtr->numLevels++;
+ code = TclEvalObjvInternal(interp, objectsUsed, objv,
+ parsePtr->commandStart, parsePtr->commandSize, 0);
iPtr->numLevels--;
-#ifdef TCL_TIP280
iPtr->cmdFramePtr = iPtr->cmdFramePtr->nextPtr;
TclArgumentRelease (interp, objv, objectsUsed);
- ckfree ((char*) eeFrame.line);
- eeFrame.line = NULL;
- eeFrame.nline = 0;
-#endif
+ eeFramePtr->line = NULL;
+ eeFramePtr->nline = 0;
if (code != TCL_OK) {
goto error;
@@ -4243,9 +4415,21 @@ EvalEx(interp, script, numBytes, flags, line, clNextOuter, outerScript)
Tcl_DecrRefCount(objv[i]);
}
objectsUsed = 0;
- if (objv != staticObjArray) {
- ckfree((char *) objv);
- objv = staticObjArray;
+ if (objvSpace != stackObjArray) {
+ ckfree((char *) objvSpace);
+ objvSpace = stackObjArray;
+ ckfree((char *) lineSpace);
+ lineSpace = linesStack;
+ }
+
+ /*
+ * Free expand separately since objvSpace could have been
+ * reallocated above.
+ */
+
+ if (expand != expandStack) {
+ ckfree((char *) expand);
+ expand = expandStack;
}
}
@@ -4256,214 +4440,91 @@ EvalEx(interp, script, numBytes, flags, line, clNextOuter, outerScript)
* executed command.
*/
- next = parse.commandStart + parse.commandSize;
+ next = parsePtr->commandStart + parsePtr->commandSize;
bytesLeft -= next - p;
p = next;
-#ifdef TCL_TIP280
- TclAdvanceLines (&line, parse.commandStart, p);
-#endif
- Tcl_FreeParse(&parse);
+ TclAdvanceLines(&line, parsePtr->commandStart, p);
+ Tcl_FreeParse(parsePtr);
gotParse = 0;
- if (nested && (*parse.term == ']')) {
- /*
- * We get here in the special case where the TCL_BRACKET_TERM
- * flag was set in the interpreter and the latest parsed command
- * was terminated by the matching close-bracket we seek.
- * Return immediately.
- */
-
- iPtr->termOffset = (p - 1) - script;
- iPtr->varFramePtr = savedVarFramePtr;
-#ifndef TCL_TIP280
- return TCL_OK;
-#else
- code = TCL_OK;
- goto cleanup_return;
-#endif
- }
} while (bytesLeft > 0);
-
- if (nested) {
- /*
- * This nested script did not terminate in ']', it is an error.
- */
-
- code = TCL_ERROR;
- goto error;
- }
-
- iPtr->termOffset = p - script;
iPtr->varFramePtr = savedVarFramePtr;
-#ifndef TCL_TIP280
- return TCL_OK;
-#else
code = TCL_OK;
goto cleanup_return;
-#endif
- error:
+ error:
/*
- * Generate various pieces of error information, such as the line
- * number where the error occurred and information to add to the
- * errorInfo variable. Then free resources that had been allocated
- * to the command.
+ * Generate and log various pieces of error information.
*/
if (iPtr->numLevels == 0) {
if (code == TCL_RETURN) {
code = TclUpdateReturnInfo(iPtr);
}
- if ((code != TCL_OK) && (code != TCL_ERROR)
- && !allowExceptions) {
+ if ((code != TCL_OK) && (code != TCL_ERROR) && !allowExceptions) {
ProcessUnexpectedResult(interp, code);
code = TCL_ERROR;
}
}
- if ((code == TCL_ERROR) && !(iPtr->flags & ERR_ALREADY_LOGGED)) {
- commandLength = parse.commandSize;
- if (parse.term == parse.commandStart + commandLength - 1) {
+ if ((code == TCL_ERROR) && !(iPtr->flags & ERR_ALREADY_LOGGED)) {
+ commandLength = parsePtr->commandSize;
+ if (parsePtr->term == parsePtr->commandStart + commandLength - 1) {
/*
* The terminator character (such as ; or ]) of the command where
* the error occurred is the last character in the parsed command.
* Reduce the length by one so that the error message doesn't
* include the terminator character.
*/
-
+
commandLength -= 1;
}
- Tcl_LogCommandInfo(interp, script, parse.commandStart, commandLength);
+ Tcl_LogCommandInfo(interp, script, parsePtr->commandStart,
+ commandLength);
}
-
+ iPtr->flags &= ~ERR_ALREADY_LOGGED;
+
+ /*
+ * Then free resources that had been allocated to the command.
+ */
+
for (i = 0; i < objectsUsed; i++) {
Tcl_DecrRefCount(objv[i]);
}
if (gotParse) {
- Tcl_FreeParse(&parse);
+ Tcl_FreeParse(parsePtr);
}
- if (objv != staticObjArray) {
- ckfree((char *) objv);
+ if (objvSpace != stackObjArray) {
+ ckfree((char *) objvSpace);
+ ckfree((char *) lineSpace);
}
- iPtr->varFramePtr = savedVarFramePtr;
-
- /*
- * All that's left to do before returning is to set iPtr->termOffset
- * to point past the end of the script we just evaluated.
- */
-
- next = parse.commandStart + parse.commandSize;
- bytesLeft -= next - p;
- p = next;
-
- if (!nested) {
- iPtr->termOffset = p - script;
-#ifndef TCL_TIP280
- return code;
-#else
- goto cleanup_return;
-#endif
+ if (expand != expandStack) {
+ ckfree((char *) expand);
}
+ iPtr->varFramePtr = savedVarFramePtr;
+ cleanup_return:
/*
- * When we are nested (the TCL_BRACKET_TERM flag was set in the
- * interpreter), we must find the matching close-bracket to
- * end the script we are evaluating.
- *
- * When our return code is TCL_CONTINUE or TCL_RETURN, we want
- * to correctly set iPtr->termOffset to point to that matching
- * close-bracket so our caller can move to the part of the
- * string beyond the script we were asked to evaluate.
- * So we try to parse past the rest of the commands.
+ * TIP #280. Release the local CmdFrame, and its contents.
*/
- next = NULL;
- while (bytesLeft && (*parse.term != ']')) {
- if (TCL_OK != Tcl_ParseCommand(NULL, p, bytesLeft, 1, &parse)) {
- /*
- * Syntax error. Set the termOffset to the beginning of
- * the last command parsed.
- */
-
- if (next == NULL) {
- iPtr->termOffset = (parse.commandStart - 1) - script;
- } else {
- iPtr->termOffset = (next - 1) - script;
- }
-#ifndef TCL_TIP280
- return code;
-#else
- goto cleanup_return;
-#endif
- }
- next = parse.commandStart + parse.commandSize;
- bytesLeft -= next - p;
- p = next;
- next = parse.commandStart;
- Tcl_FreeParse(&parse);
- }
-
- if (bytesLeft) {
- /*
- * parse.term points to the close-bracket.
- */
-
- iPtr->termOffset = parse.term - script;
- } else if (parse.term == script + numBytes) {
- /*
- * There was no close-bracket. Syntax error.
- */
-
- iPtr->termOffset = parse.term - script;
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj("missing close-bracket", -1));
-#ifndef TCL_TIP280
- return TCL_ERROR;
-#else
- code = TCL_ERROR;
- goto cleanup_return;
-#endif
- } else if (*parse.term != ']') {
- /*
- * There was no close-bracket. Syntax error.
- */
-
- iPtr->termOffset = (parse.term + 1) - script;
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj("missing close-bracket", -1));
-#ifndef TCL_TIP280
- return TCL_ERROR;
-#else
- code = TCL_ERROR;
- goto cleanup_return;
-#endif
- } else {
- /*
- * parse.term points to the close-bracket.
- */
- iPtr->termOffset = parse.term - script;
+ if (eeFramePtr->type == TCL_LOCATION_SOURCE) {
+ Tcl_DecrRefCount(eeFramePtr->data.eval.path);
}
+ TclStackFree(interp, linesStack);
+ TclStackFree(interp, expandStack);
+ TclStackFree(interp, stackObjArray);
+ TclStackFree(interp, eeFramePtr);
+ TclStackFree(interp, parsePtr);
-#ifdef TCL_TIP280
- cleanup_return:
- /* TIP #280. Release the local CmdFrame, and its contents. */
-
- if (eeFrame.line != NULL) {
- ckfree ((char*) eeFrame.line);
- }
- if (eeFrame.type == TCL_LOCATION_SOURCE) {
- Tcl_DecrRefCount (eeFrame.data.eval.path);
- }
-#endif
return code;
}
-#ifdef TCL_TIP280
/*
*----------------------------------------------------------------------
*
* TclAdvanceLines --
*
- * This procedure is a helper which counts the number of lines
- * in a block of text and advances an external counter.
+ * This function is a helper which counts the number of lines in a block
+ * of text and advances an external counter.
*
* Results:
* None.
@@ -4476,15 +4537,16 @@ EvalEx(interp, script, numBytes, flags, line, clNextOuter, outerScript)
*/
void
-TclAdvanceLines (line,start,end)
- int* line;
- CONST char* start;
- CONST char* end;
+TclAdvanceLines(
+ int *line,
+ const char *start,
+ const char *end)
{
- CONST char* p;
+ register const char *p;
+
for (p = start; p < end; p++) {
- if (*p == '\n') {
- (*line) ++;
+ if (*p == '\n') {
+ (*line)++;
}
}
}
@@ -4518,11 +4580,11 @@ TclAdvanceContinuations (line,clNextPtrPtr,loc)
/*
* Track the invisible continuation lines embedded in a script, if
* any. Here they are just spaces (already). They were removed by
- * EvalTokensStandard() via TclParseBackslash().
+ * TclSubstTokens() via TclParseBackslash().
*
- * *clNextPtrPtr <=> We have continuation lines to track.
- * **clNextPtrPtr >= 0 <=> We are not beyond the last possible location.
- * loc >= **clNextPtrPtr <=> We stepped beyond the current cont. line.
+ * *clNextPtrPtr <=> We have continuation lines to track.
+ * **clNextPtrPtr >= 0 <=> We are not beyond the last possible location.
+ * loc >= **clNextPtrPtr <=> We stepped beyond the current cont. line.
*/
while (*clNextPtrPtr && (**clNextPtrPtr >= 0) && (loc >= **clNextPtrPtr)) {
@@ -4661,7 +4723,7 @@ TclArgumentRelease(interp,objv,objc)
*
* This procedure is a helper for the TIP #280 uplevel extension.
* It enters location references for the literal arguments of commands
- * in bytecode about to be executed. Only the first entry has the actual
+ * in bytecode about to be invoked. Only the first entry has the actual
* data, further entries simply count the usage up.
*
* Results:
@@ -4675,7 +4737,7 @@ TclArgumentRelease(interp,objv,objc)
*/
void
-TclArgumentBCEnter(interp, objv, objc, codePtr, cfPtr, pc)
+TclArgumentBCEnter(interp,objv,objc,codePtr,cfPtr,pc)
Tcl_Interp* interp;
Tcl_Obj* objv[];
int objc;
@@ -4688,12 +4750,12 @@ TclArgumentBCEnter(interp, objv, objc, codePtr, cfPtr, pc)
if (hePtr) {
ExtCmdLoc* eclPtr = (ExtCmdLoc*) Tcl_GetHashValue (hePtr);
- hePtr = Tcl_FindHashEntry(&eclPtr->litInfo, (char*) pc);
+ hePtr = Tcl_FindHashEntry(&eclPtr->litInfo, INT2PTR(pc));
if (hePtr) {
- int word;
- int cmd = (int) Tcl_GetHashValue(hePtr);
+ int cmd = PTR2INT(Tcl_GetHashValue(hePtr));
ECL* ePtr = &eclPtr->loc[cmd];
+ int word;
/*
* A few truths ...
@@ -4705,6 +4767,10 @@ TclArgumentBCEnter(interp, objv, objc, codePtr, cfPtr, pc)
* have to save them at compile time.
*/
+ if (ePtr->nline != objc) {
+ Tcl_Panic ("TIP 280 data structure inconsistency");
+ }
+
for (word = 1; word < objc; word++) {
if (ePtr->line[word] >= 0) {
int isnew;
@@ -4761,7 +4827,7 @@ TclArgumentBCEnter(interp, objv, objc, codePtr, cfPtr, pc)
*/
void
-TclArgumentBCRelease(interp, objv, objc, codePtr, pc)
+TclArgumentBCRelease(interp,objv,objc,codePtr,pc)
Tcl_Interp* interp;
Tcl_Obj* objv[];
int objc;
@@ -4773,10 +4839,10 @@ TclArgumentBCRelease(interp, objv, objc, codePtr, pc)
if (hePtr) {
ExtCmdLoc* eclPtr = (ExtCmdLoc*) Tcl_GetHashValue (hePtr);
- hePtr = Tcl_FindHashEntry(&eclPtr->litInfo, (char*) pc);
+ hePtr = Tcl_FindHashEntry(&eclPtr->litInfo, INT2PTR(pc));
if (hePtr) {
- int cmd = (int) Tcl_GetHashValue(hePtr);
+ int cmd = PTR2INT(Tcl_GetHashValue(hePtr));
ECL* ePtr = &eclPtr->loc[cmd];
int word;
@@ -4790,7 +4856,7 @@ TclArgumentBCRelease(interp, objv, objc, codePtr, pc)
(char *) objv[word]);
if (hPtr) {
CFWordBC* cfwPtr = (CFWordBC*) Tcl_GetHashValue (hPtr);
-
+
if (cfwPtr->prevPtr) {
Tcl_SetHashValue(hPtr, cfwPtr->prevPtr);
} else {
@@ -4835,16 +4901,16 @@ TclArgumentGet(interp,obj,cfPtrPtr,wordPtr)
CmdFrame* framePtr;
/*
- * An object which either has no string rep guaranteed to have been
- * generated dynamically: bail out, this cannot have a usable absolute
- * location. _Do not touch_ the information the set up by the caller. It
- * knows better than us.
+ * An object which either has no string rep or else is a canonical list is
+ * guaranteed to have been generated dynamically: bail out, this cannot
+ * have a usable absolute location. _Do not touch_ the information the set
+ * up by the caller. It knows better than us.
*/
- if (!obj->bytes) {
+ if ((obj->bytes == NULL) || TclListObjIsCanonical(obj)) {
return;
}
-
+
/*
* First look for location information recorded in the argument
* stack. That is nearest.
@@ -4864,36 +4930,34 @@ TclArgumentGet(interp,obj,cfPtrPtr,wordPtr)
*/
hPtr = Tcl_FindHashEntry (iPtr->lineLABCPtr, (char *) obj);
+
if (hPtr) {
CFWordBC* cfwPtr = (CFWordBC*) Tcl_GetHashValue (hPtr);
framePtr = cfwPtr->framePtr;
- framePtr->data.tebc.pc = (char*) ((ByteCode*)
- framePtr->data.tebc.codePtr)->codeStart + cfwPtr->pc;
+ framePtr->data.tebc.pc = (char *) (((ByteCode*)
+ framePtr->data.tebc.codePtr)->codeStart + cfwPtr->pc);
*cfPtrPtr = cfwPtr->framePtr;
*wordPtr = cfwPtr->word;
return;
}
}
-#endif
/*
*----------------------------------------------------------------------
*
* Tcl_Eval --
*
- * Execute a Tcl command in a string. This procedure executes the
- * script directly, rather than compiling it to bytecodes. Before
- * the arrival of the bytecode compiler in Tcl 8.0 Tcl_Eval was
- * the main procedure used for executing Tcl commands, but nowadays
- * it isn't used much.
+ * Execute a Tcl command in a string. This function executes the script
+ * directly, rather than compiling it to bytecodes. Before the arrival of
+ * the bytecode compiler in Tcl 8.0 Tcl_Eval was the main function used
+ * for executing Tcl commands, but nowadays it isn't used much.
*
* Results:
- * The return value is one of the return codes defined in tcl.h
- * (such as TCL_OK), and interp's result contains a value
- * to supplement the return code. The value of the result
- * will persist only until the next call to Tcl_Eval or Tcl_EvalObj:
- * you must copy it or lose it!
+ * The return value is one of the return codes defined in tcl.h (such as
+ * TCL_OK), and interp's result contains a value to supplement the return
+ * code. The value of the result will persist only until the next call to
+ * Tcl_Eval or Tcl_EvalObj: you must copy it or lose it!
*
* Side effects:
* Can be almost arbitrary, depending on the commands in the script.
@@ -4902,21 +4966,20 @@ TclArgumentGet(interp,obj,cfPtrPtr,wordPtr)
*/
int
-Tcl_Eval(interp, string)
- Tcl_Interp *interp; /* Token for command interpreter (returned
- * by previous call to Tcl_CreateInterp). */
- CONST char *string; /* Pointer to TCL command to execute. */
+Tcl_Eval(
+ Tcl_Interp *interp, /* Token for command interpreter (returned by
+ * previous call to Tcl_CreateInterp). */
+ const char *script) /* Pointer to TCL command to execute. */
{
- int code = Tcl_EvalEx(interp, string, -1, 0);
+ int code = Tcl_EvalEx(interp, script, -1, 0);
/*
- * For backwards compatibility with old C code that predates the
- * object system in Tcl 8.0, we have to mirror the object result
- * back into the string result (some callers may expect it there).
+ * For backwards compatibility with old C code that predates the object
+ * system in Tcl 8.0, we have to mirror the object result back into the
+ * string result (some callers may expect it there).
*/
- Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
- TCL_VOLATILE);
+ (void) Tcl_GetStringResult(interp);
return code;
}
@@ -4939,18 +5002,18 @@ Tcl_Eval(interp, string)
#undef Tcl_EvalObj
int
-Tcl_EvalObj(interp, objPtr)
- Tcl_Interp * interp;
- Tcl_Obj * objPtr;
+Tcl_EvalObj(
+ Tcl_Interp *interp,
+ Tcl_Obj *objPtr)
{
return Tcl_EvalObjEx(interp, objPtr, 0);
}
#undef Tcl_GlobalEvalObj
int
-Tcl_GlobalEvalObj(interp, objPtr)
- Tcl_Interp * interp;
- Tcl_Obj * objPtr;
+Tcl_GlobalEvalObj(
+ Tcl_Interp *interp,
+ Tcl_Obj *objPtr)
{
return Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_GLOBAL);
}
@@ -4961,322 +5024,272 @@ Tcl_GlobalEvalObj(interp, objPtr)
* Tcl_EvalObjEx, TclEvalObjEx --
*
* Execute Tcl commands stored in a Tcl object. These commands are
- * compiled into bytecodes if necessary, unless TCL_EVAL_DIRECT
- * is specified.
+ * compiled into bytecodes if necessary, unless TCL_EVAL_DIRECT is
+ * specified.
*
* 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 the return code.
+ * 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
+ * the return code.
*
* Side effects:
- * The object is converted, if necessary, to a ByteCode object that
- * holds the bytecode instructions for the commands. Executing the
- * commands will almost certainly have side effects that depend
- * on those commands.
- *
- * Just as in Tcl_Eval, interp->termOffset is set to the offset of the
- * last character executed in the objPtr's string.
+ * The object is converted, if necessary, to a ByteCode object that holds
+ * the bytecode instructions for the commands. Executing the commands
+ * will almost certainly have side effects that depend on those commands.
*
* TIP #280 : Keep public API, internally extended API.
*----------------------------------------------------------------------
*/
int
-Tcl_EvalObjEx(interp, objPtr, flags)
- Tcl_Interp *interp; /* Token for command interpreter
- * (returned by a previous call to
- * Tcl_CreateInterp). */
- register Tcl_Obj *objPtr; /* Pointer to object containing
- * commands to execute. */
- int flags; /* Collection of OR-ed bits that
- * control the evaluation of the
- * script. Supported values are
- * TCL_EVAL_GLOBAL and
- * TCL_EVAL_DIRECT. */
+Tcl_EvalObjEx(
+ Tcl_Interp *interp, /* Token for command interpreter (returned by
+ * a previous call to Tcl_CreateInterp). */
+ register Tcl_Obj *objPtr, /* Pointer to object containing commands to
+ * execute. */
+ int flags) /* Collection of OR-ed bits that control the
+ * evaluation of the script. Supported values
+ * are TCL_EVAL_GLOBAL and TCL_EVAL_DIRECT. */
{
-#ifdef TCL_TIP280
- return TclEvalObjEx (interp, objPtr, flags, NULL, 0);
+ return TclEvalObjEx(interp, objPtr, flags, NULL, 0);
}
int
-TclEvalObjEx(interp, objPtr, flags, invoker, word)
- Tcl_Interp *interp; /* Token for command interpreter
- * (returned by a previous call to
- * Tcl_CreateInterp). */
- register Tcl_Obj *objPtr; /* Pointer to object containing
- * commands to execute. */
- int flags; /* Collection of OR-ed bits that
- * control the evaluation of the
- * script. Supported values are
- * TCL_EVAL_GLOBAL and
- * TCL_EVAL_DIRECT. */
- CONST CmdFrame* invoker; /* Frame of the command doing the eval */
- int word; /* Index of the word which is in objPtr */
+TclEvalObjEx(
+ Tcl_Interp *interp, /* Token for command interpreter (returned by
+ * a previous call to Tcl_CreateInterp). */
+ register Tcl_Obj *objPtr, /* Pointer to object containing commands to
+ * execute. */
+ int flags, /* Collection of OR-ed bits that control the
+ * evaluation of the script. Supported values
+ * are TCL_EVAL_GLOBAL and TCL_EVAL_DIRECT. */
+ const CmdFrame *invoker, /* Frame of the command doing the eval. */
+ int word) /* Index of the word which is in objPtr. */
{
-#endif
register Interp *iPtr = (Interp *) interp;
char *script;
int numSrcBytes;
int result;
- CallFrame *savedVarFramePtr; /* Saves old copy of iPtr->varFramePtr
- * in case TCL_EVAL_GLOBAL was set. */
- int allowExceptions = (iPtr->evalFlags & TCL_ALLOW_EXCEPTIONS);
+ CallFrame *savedVarFramePtr;/* Saves old copy of iPtr->varFramePtr in case
+ * TCL_EVAL_GLOBAL was set. */
Tcl_IncrRefCount(objPtr);
- if ((iPtr->flags & USE_EVAL_DIRECT) || (flags & TCL_EVAL_DIRECT)) {
+ /* Pure List Optimization (no string representation). 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 string and back out again.
+ *
+ * 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).
+ */
+
+ if (TclListObjIsCanonical(objPtr)) {
+ /*
+ * TIP #280 Structures for tracking lines. As we know that this is
+ * dynamic execution we ignore the invoker, even if known.
+ */
+
+ int nelements;
+ Tcl_Obj **elements, *copyPtr = TclListObjCopy(NULL, objPtr);
+ CmdFrame *eoFramePtr = (CmdFrame *)
+ TclStackAlloc(interp, sizeof(CmdFrame));
+
+ eoFramePtr->type = TCL_LOCATION_EVAL_LIST;
+ eoFramePtr->level = (iPtr->cmdFramePtr == NULL? 1
+ : iPtr->cmdFramePtr->level + 1);
+ eoFramePtr->framePtr = iPtr->framePtr;
+ eoFramePtr->nextPtr = iPtr->cmdFramePtr;
+
+ eoFramePtr->nline = 0;
+ eoFramePtr->line = NULL;
+
+ eoFramePtr->cmd.listPtr = objPtr;
+ Tcl_IncrRefCount(eoFramePtr->cmd.listPtr);
+ eoFramePtr->data.eval.path = NULL;
+
+ /*
+ * TIP #280 We do _not_ compute all the line numbers for the words
+ * in the command. For the eval of a pure list the most sensible
+ * choice is to put all words on line 1. Given that we neither
+ * need memory for them nor compute anything. 'line' is left
+ * NULL. The two places using this information (TclInfoFrame, and
+ * TclInitCompileEnv), are special-cased to use the proper line
+ * number directly instead of accessing the 'line' array.
+ */
+
+ Tcl_ListObjGetElements(NULL, copyPtr, &nelements, &elements);
+
+ iPtr->cmdFramePtr = eoFramePtr;
+ result = Tcl_EvalObjv(interp, nelements, elements, flags);
+
+ Tcl_DecrRefCount(copyPtr);
+ iPtr->cmdFramePtr = iPtr->cmdFramePtr->nextPtr;
+ Tcl_DecrRefCount(eoFramePtr->cmd.listPtr);
+ TclStackFree(interp, eoFramePtr);
+ } else if (flags & TCL_EVAL_DIRECT) {
/*
* We're not supposed to use the compiler or byte-code interpreter.
- * Let Tcl_EvalEx evaluate the command directly (and probably
- * more slowly).
+ * 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.
*
- * Pure List Optimization (no string representation). 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 string and back out again.
+ * See also tclCompile.c, TclInitCompileEnv, for the equivalent code
+ * in the bytecode compiler.
+ */
+
+ /*
+ * Now we check if we have data about invisible continuation lines for
+ * the script, and make it available to the direct script parser and
+ * evaluator we are about to call, if so.
*
- * USE_EVAL_DIRECT is a special flag used for testing purpose only
- * (ensure we go into the TCL_EVAL_DIRECT path, avoiding opt)
+ * It may be possible that the script Tcl_Obj* can be free'd while the
+ * evaluator is using it, leading to the release of the associated
+ * ContLineLoc structure as well. To ensure that the latter doesn't
+ * happen we set a lock on it. We release this lock later in this
+ * function, after the evaluator is done. The relevant "lineCLPtr"
+ * hashtable is managed in the file "tclObj.c".
+ *
+ * Another important action is to save (and later restore) the
+ * continuation line information of the caller, in case we are
+ * executing nested commands in the eval/direct path.
*/
- if (!(iPtr->flags & USE_EVAL_DIRECT) &&
- (objPtr->typePtr == &tclListType) && /* is a list... */
- (objPtr->bytes == NULL) /* ...without a string rep */) {
- register List *listRepPtr =
- (List *) objPtr->internalRep.twoPtrValue.ptr1;
- int i, objc = listRepPtr->elemCount;
-
-#define TEOE_PREALLOC 10
- Tcl_Obj *staticObjv[TEOE_PREALLOC], **objv = staticObjv;
-
-#ifdef TCL_TIP280
- /* TIP #280 Structures for tracking lines.
- * As we know that this is dynamic execution we ignore the
- * invoker, even if known.
- */
- CmdFrame eoFrame;
-
- eoFrame.type = TCL_LOCATION_EVAL_LIST;
- eoFrame.level = (iPtr->cmdFramePtr == NULL ?
- 1 :
- iPtr->cmdFramePtr->level + 1);
- eoFrame.framePtr = iPtr->framePtr;
- eoFrame.nextPtr = iPtr->cmdFramePtr;
- eoFrame.nline = 0;
- eoFrame.line = NULL;
-
- /* NOTE: Getting the string rep of the list to eval to fill the
- * command information required by 'info frame' implies that
- * further calls for the same list would not be optimized, as it
- * would not be 'pure' anymore. It would also be a waste of time
- * as most of the time this information is not needed at all. What
- * we do instead is to keep the list obj itself around and have
- * 'info frame' sort it out.
- */
- eoFrame.cmd.listPtr = objPtr;
- Tcl_IncrRefCount (eoFrame.cmd.listPtr);
- eoFrame.data.eval.path = NULL;
-#endif
- if (objc > TEOE_PREALLOC) {
- objv = (Tcl_Obj **) ckalloc(objc*sizeof(Tcl_Obj *));
- }
-#undef TEOE_PREALLOC
- /*
- * Copy the list elements here, to avoid a segfault if
- * objPtr loses its List internal rep [Bug 1119369].
- *
- * TIP #280 We do _not_ compute all the line numbers for the words
- * in the command. For the eval of a pure list the most sensible
- * choice is to put all words on line 1. Given that we neither
- * need memory for them nor compute anything. 'line' is left
- * NULL. The two places using this information (TclInfoFrame, and
- * TclInitCompileEnv), are special-cased to use the proper line
- * number directly instead of accessing the 'line' array.
- */
+ ContLineLoc* saveCLLocPtr = iPtr->scriptCLLocPtr;
+ ContLineLoc* clLocPtr = TclContinuationsGet (objPtr);
- for (i=0; i < objc; i++) {
- objv[i] = listRepPtr->elements[i];
- Tcl_IncrRefCount(objv[i]);
- }
+ if (clLocPtr) {
+ iPtr->scriptCLLocPtr = clLocPtr;
+ Tcl_Preserve (iPtr->scriptCLLocPtr);
+ } else {
+ iPtr->scriptCLLocPtr = NULL;
+ }
-#ifdef TCL_TIP280
- iPtr->cmdFramePtr = &eoFrame;
-#endif
- result = Tcl_EvalObjv(interp, objc, objv, flags);
-#ifdef TCL_TIP280
- iPtr->cmdFramePtr = iPtr->cmdFramePtr->nextPtr;
- Tcl_DecrRefCount (eoFrame.cmd.listPtr);
-#endif
+ if (invoker == NULL) {
+ /*
+ * No context, force opening of our own.
+ */
- for (i=0; i < objc; i++) {
- TclDecrRefCount(objv[i]);
- }
- if (objv != staticObjv) {
- ckfree((char *) objv);
- }
-#ifdef TCL_TIP280
- ckfree ((char*) eoFrame.line);
- eoFrame.line = NULL;
- eoFrame.nline = 0;
-#endif
- } else {
-#ifndef TCL_TIP280
script = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
result = Tcl_EvalEx(interp, script, numSrcBytes, flags);
-#else
+ } else {
/*
- * 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.
+ * 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.
*
- * See also tclCompile.c, TclInitCompileEnv, for the equivalent
- * code in the bytecode compiler.
+ * 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.
*/
- /*
- * Now we check if we have data about invisible continuation lines
- * for the script, and make it available to the direct script
- * parser and evaluator we are about to call, if so.
- *
- * It may be possible that the script Tcl_Obj* can be free'd while
- * the evaluator is using it, leading to the release of the
- * associated ContLineLoc structure as well. To ensure that the
- * latter doesn't happen we set a lock on it. We release this lock
- * later in this function, after the evaluator is done. The
- * relevant "lineCLPtr" hashtable is managed in the file
- * "tclObj.c".
- *
- * Another important action is to save (and later restore) the
- * continuation line information of the caller, in case we are
- * executing nested commands in the eval/direct path.
- */
+ int pc = 0;
+ CmdFrame *ctxPtr = (CmdFrame *)
+ TclStackAlloc(interp, sizeof(CmdFrame));
- ContLineLoc* saveCLLocPtr = iPtr->scriptCLLocPtr;
- ContLineLoc* clLocPtr = TclContinuationsGet (objPtr);
+ *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.
+ */
- if (clLocPtr) {
- iPtr->scriptCLLocPtr = clLocPtr;
- Tcl_Preserve (iPtr->scriptCLLocPtr);
- } else {
- iPtr->scriptCLLocPtr = NULL;
+ TclGetSrcInfoForPc(ctxPtr);
+ pc = 1;
}
- 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.
- */
+ script = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
- CmdFrame ctx = *invoker;
- int pc = 0;
+ if ((ctxPtr->nline <= word) ||
+ (ctxPtr->line[word] < 0) ||
+ (ctxPtr->type != TCL_LOCATION_SOURCE)) {
+ /*
+ * Dynamic script, or dynamic context, force our own
+ * context.
+ */
- if (invoker->type == TCL_LOCATION_BC) {
- /* Note: Type BC => ctx.data.eval.path is not used.
- * ctx.data.tebc.codePtr is used instead.
- */
- TclGetSrcInfoForPc (&ctx);
- pc = 1;
- }
+ result = Tcl_EvalEx(interp, script, numSrcBytes, flags);
- script = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
+ } else {
+ /*
+ * Absolute context to reuse.
+ */
- if ((ctx.nline <= word) ||
- (ctx.line[word] < 0) ||
- (ctx.type != TCL_LOCATION_SOURCE)) {
- /* Dynamic script, or dynamic context, force our own
- * context */
+ iPtr->invokeCmdFramePtr = ctxPtr;
+ iPtr->evalFlags |= TCL_EVAL_CTX;
- result = Tcl_EvalEx(interp, script, numSrcBytes, flags);
- } else {
- /* Absolute context available to reuse. */
+ result = TclEvalEx(interp, script, numSrcBytes, flags,
+ ctxPtr->line[word], NULL, script);
+ }
- iPtr->invokeCmdFramePtr = &ctx;
- iPtr->evalFlags |= TCL_EVAL_CTX;
+ if (pc && (ctxPtr->type == TCL_LOCATION_SOURCE)) {
+ /*
+ * Death of SrcInfo reference.
+ */
- result = EvalEx(interp, script, numSrcBytes, flags,
- ctx.line [word], NULL, script);
- }
- if (pc && (ctx.type == TCL_LOCATION_SOURCE)) {
- /* Death of SrcInfo reference. */
- Tcl_DecrRefCount(ctx.data.eval.path);
- }
+ Tcl_DecrRefCount(ctxPtr->data.eval.path);
}
+ TclStackFree(interp, ctxPtr);
+ }
- /*
- * Now release the lock on the continuation line information, if
- * any, and restore the caller's settings.
- */
+ /*
+ * Now release the lock on the continuation line information, if
+ * any, and restore the caller's settings.
+ */
- if (iPtr->scriptCLLocPtr) {
- Tcl_Release (iPtr->scriptCLLocPtr);
- }
- iPtr->scriptCLLocPtr = saveCLLocPtr;
-#endif
+ if (iPtr->scriptCLLocPtr) {
+ Tcl_Release (iPtr->scriptCLLocPtr);
}
+ iPtr->scriptCLLocPtr = saveCLLocPtr;
} else {
/*
* Let the compiler/engine subsystem do the evaluation.
*
- * TIP #280 The invoker provides us with the context for the
- * script. We transfer this to the byte code compiler.
+ * TIP #280 The invoker provides us with the context for the script.
+ * We transfer this to the byte code compiler.
*/
+ int allowExceptions = (iPtr->evalFlags & TCL_ALLOW_EXCEPTIONS);
savedVarFramePtr = iPtr->varFramePtr;
if (flags & TCL_EVAL_GLOBAL) {
- iPtr->varFramePtr = NULL;
+ iPtr->varFramePtr = iPtr->rootFramePtr;
}
-#ifndef TCL_TIP280
- result = TclCompEvalObj(interp, objPtr);
-#else
result = TclCompEvalObj(interp, objPtr, invoker, word);
-#endif
/*
- * If we are again at the top level, process any unusual
- * return code returned by the evaluated code.
+ * If we are again at the top level, process any unusual return code
+ * returned by the evaluated code.
*/
-
+
if (iPtr->numLevels == 0) {
if (result == TCL_RETURN) {
result = TclUpdateReturnInfo(iPtr);
}
- if ((result != TCL_OK) && (result != TCL_ERROR)
- && !allowExceptions) {
+ if ((result != TCL_OK) && (result != TCL_ERROR)
+ && !allowExceptions) {
ProcessUnexpectedResult(interp, result);
result = TCL_ERROR;
-
- /*
- * If an error was created here, record information about
- * what was being executed when the error occurred. Remove
- * the extra \n added by tclMain.c in the command sent to
- * Tcl_LogCommandInfo [Bug 833150].
- */
-
- if (!(iPtr->flags & ERR_ALREADY_LOGGED)) {
- script = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
- Tcl_LogCommandInfo(interp, script, script, --numSrcBytes);
- iPtr->flags &= ~ERR_ALREADY_LOGGED;
- }
+ script = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
+ Tcl_LogCommandInfo(interp, script, script, numSrcBytes);
}
}
iPtr->evalFlags = 0;
- iPtr->varFramePtr = savedVarFramePtr;
+ iPtr->varFramePtr = savedVarFramePtr;
}
TclDecrRefCount(objPtr);
@@ -5288,39 +5301,37 @@ TclEvalObjEx(interp, objPtr, flags, invoker, word)
*
* ProcessUnexpectedResult --
*
- * Procedure called by Tcl_EvalObj to set the interpreter's result
- * value to an appropriate error message when the code it evaluates
- * returns an unexpected result code (not TCL_OK and not TCL_ERROR) to
- * the topmost evaluation level.
+ * Function called by Tcl_EvalObj to set the interpreter's result value
+ * to an appropriate error message when the code it evaluates returns an
+ * unexpected result code (not TCL_OK and not TCL_ERROR) to the topmost
+ * evaluation level.
*
* Results:
* None.
*
* Side effects:
- * The interpreter result is set to an error message appropriate to
- * the result code.
+ * The interpreter result is set to an error message appropriate to the
+ * result code.
*
*----------------------------------------------------------------------
*/
static void
-ProcessUnexpectedResult(interp, returnCode)
- Tcl_Interp *interp; /* The interpreter in which the unexpected
+ProcessUnexpectedResult(
+ Tcl_Interp *interp, /* The interpreter in which the unexpected
* result code was returned. */
- int returnCode; /* The unexpected result code. */
+ int returnCode) /* The unexpected result code. */
{
Tcl_ResetResult(interp);
if (returnCode == TCL_BREAK) {
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "invoked \"break\" outside of a loop", -1);
+ Tcl_AppendResult(interp,
+ "invoked \"break\" outside of a loop", NULL);
} else if (returnCode == TCL_CONTINUE) {
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "invoked \"continue\" outside of a loop", -1);
+ Tcl_AppendResult(interp,
+ "invoked \"continue\" outside of a loop", NULL);
} else {
- char buf[30 + TCL_INTEGER_SPACE];
-
- sprintf(buf, "command returned bad code: %d", returnCode);
- Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "command returned bad code: %d", returnCode));
}
}
@@ -5329,15 +5340,15 @@ ProcessUnexpectedResult(interp, returnCode)
*
* Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean --
*
- * Procedures to evaluate an expression and return its value in a
+ * Functions to evaluate an expression and return its value in a
* particular form.
*
* Results:
- * Each of the procedures below returns a standard Tcl result. If an
- * error occurs then an error message is left in the interp's result.
- * Otherwise the value of the expression, in the appropriate form,
- * is stored at *ptr. If the expression had a result that was
- * incompatible with the desired form then an error is returned.
+ * Each of the functions below returns a standard Tcl result. If an error
+ * occurs then an error message is left in the interp's result. Otherwise
+ * the value of the expression, in the appropriate form, is stored at
+ * *ptr. If the expression had a result that was incompatible with the
+ * desired form then an error is returned.
*
* Side effects:
* None.
@@ -5346,197 +5357,92 @@ ProcessUnexpectedResult(interp, returnCode)
*/
int
-Tcl_ExprLong(interp, string, ptr)
- Tcl_Interp *interp; /* Context in which to evaluate the
+Tcl_ExprLong(
+ Tcl_Interp *interp, /* Context in which to evaluate the
* expression. */
- CONST char *string; /* Expression to evaluate. */
- long *ptr; /* Where to store result. */
+ const char *exprstring, /* Expression to evaluate. */
+ long *ptr) /* Where to store result. */
{
register Tcl_Obj *exprPtr;
- Tcl_Obj *resultPtr;
- int length = strlen(string);
int result = TCL_OK;
-
- if (length > 0) {
- exprPtr = Tcl_NewStringObj(string, length);
- Tcl_IncrRefCount(exprPtr);
- result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
- if (result == TCL_OK) {
- /*
- * Store an integer based on the expression result.
- */
-
- if (resultPtr->typePtr == &tclIntType) {
- *ptr = resultPtr->internalRep.longValue;
- } else if (resultPtr->typePtr == &tclDoubleType) {
- *ptr = (long) resultPtr->internalRep.doubleValue;
- } else if (resultPtr->typePtr == &tclWideIntType) {
-#ifndef TCL_WIDE_INT_IS_LONG
- /*
- * See Tcl_GetIntFromObj for conversion comments.
- */
- Tcl_WideInt w = resultPtr->internalRep.wideValue;
- if ((w >= -(Tcl_WideInt)(ULONG_MAX))
- && (w <= (Tcl_WideInt)(ULONG_MAX))) {
- *ptr = Tcl_WideAsLong(w);
- } else {
- Tcl_SetResult(interp,
- "integer value too large to represent as non-long integer",
- TCL_STATIC);
- result = TCL_ERROR;
- }
-#else
- *ptr = resultPtr->internalRep.longValue;
-#endif
- } else {
- Tcl_SetResult(interp,
- "expression didn't have numeric value", TCL_STATIC);
- result = TCL_ERROR;
- }
- Tcl_DecrRefCount(resultPtr); /* discard the result object */
- } else {
- /*
- * Move the interpreter's object result to the string result,
- * then reset the object result.
- */
-
- Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
- TCL_VOLATILE);
- }
- Tcl_DecrRefCount(exprPtr); /* discard the expression object */
- } else {
+ if (*exprstring == '\0') {
/*
- * An empty string. Just set the result integer to 0.
+ * Legacy compatibility - return 0 for the zero-length string.
*/
-
+
*ptr = 0;
+ } else {
+ exprPtr = Tcl_NewStringObj(exprstring, -1);
+ Tcl_IncrRefCount(exprPtr);
+ result = Tcl_ExprLongObj(interp, exprPtr, ptr);
+ Tcl_DecrRefCount(exprPtr);
+ if (result != TCL_OK) {
+ (void) Tcl_GetStringResult(interp);
+ }
}
return result;
}
int
-Tcl_ExprDouble(interp, string, ptr)
- Tcl_Interp *interp; /* Context in which to evaluate the
+Tcl_ExprDouble(
+ Tcl_Interp *interp, /* Context in which to evaluate the
* expression. */
- CONST char *string; /* Expression to evaluate. */
- double *ptr; /* Where to store result. */
+ const char *exprstring, /* Expression to evaluate. */
+ double *ptr) /* Where to store result. */
{
register Tcl_Obj *exprPtr;
- Tcl_Obj *resultPtr;
- int length = strlen(string);
int result = TCL_OK;
- if (length > 0) {
- exprPtr = Tcl_NewStringObj(string, length);
- Tcl_IncrRefCount(exprPtr);
- result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
- if (result == TCL_OK) {
- /*
- * Store a double based on the expression result.
- */
-
- if (resultPtr->typePtr == &tclIntType) {
- *ptr = (double) resultPtr->internalRep.longValue;
- } else if (resultPtr->typePtr == &tclDoubleType) {
- *ptr = resultPtr->internalRep.doubleValue;
- } else if (resultPtr->typePtr == &tclWideIntType) {
-#ifndef TCL_WIDE_INT_IS_LONG
- /*
- * See Tcl_GetIntFromObj for conversion comments.
- */
- Tcl_WideInt w = resultPtr->internalRep.wideValue;
- if ((w >= -(Tcl_WideInt)(ULONG_MAX))
- && (w <= (Tcl_WideInt)(ULONG_MAX))) {
- *ptr = (double) Tcl_WideAsLong(w);
- } else {
- Tcl_SetResult(interp,
- "integer value too large to represent as non-long integer",
- TCL_STATIC);
- result = TCL_ERROR;
- }
-#else
- *ptr = (double) resultPtr->internalRep.longValue;
-#endif
- } else {
- Tcl_SetResult(interp,
- "expression didn't have numeric value", TCL_STATIC);
- result = TCL_ERROR;
- }
- Tcl_DecrRefCount(resultPtr); /* discard the result object */
- } else {
- /*
- * Move the interpreter's object result to the string result,
- * then reset the object result.
- */
-
- Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
- TCL_VOLATILE);
- }
- Tcl_DecrRefCount(exprPtr); /* discard the expression object */
- } else {
+ if (*exprstring == '\0') {
/*
- * An empty string. Just set the result double to 0.0.
+ * Legacy compatibility - return 0 for the zero-length string.
*/
-
+
*ptr = 0.0;
+ } else {
+ exprPtr = Tcl_NewStringObj(exprstring, -1);
+ Tcl_IncrRefCount(exprPtr);
+ result = Tcl_ExprDoubleObj(interp, exprPtr, ptr);
+ Tcl_DecrRefCount(exprPtr);
+ /* Discard the expression object. */
+ if (result != TCL_OK) {
+ (void) Tcl_GetStringResult(interp);
+ }
}
return result;
}
int
-Tcl_ExprBoolean(interp, string, ptr)
- Tcl_Interp *interp; /* Context in which to evaluate the
- * expression. */
- CONST char *string; /* Expression to evaluate. */
- int *ptr; /* Where to store 0/1 result. */
+Tcl_ExprBoolean(
+ Tcl_Interp *interp, /* Context in which to evaluate the
+ * expression. */
+ const char *exprstring, /* Expression to evaluate. */
+ int *ptr) /* Where to store 0/1 result. */
{
- register Tcl_Obj *exprPtr;
- Tcl_Obj *resultPtr;
- int length = strlen(string);
- int result = TCL_OK;
+ if (*exprstring == '\0') {
+ /*
+ * An empty string. Just set the result boolean to 0 (false).
+ */
- if (length > 0) {
- exprPtr = Tcl_NewStringObj(string, length);
- Tcl_IncrRefCount(exprPtr);
- result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
- if (result == TCL_OK) {
- /*
- * Store a boolean based on the expression result.
- */
+ *ptr = 0;
+ return TCL_OK;
+ } else {
+ int result;
+ Tcl_Obj *exprPtr = Tcl_NewStringObj(exprstring, -1);
- if (resultPtr->typePtr == &tclIntType) {
- *ptr = (resultPtr->internalRep.longValue != 0);
- } else if (resultPtr->typePtr == &tclDoubleType) {
- *ptr = (resultPtr->internalRep.doubleValue != 0.0);
- } else if (resultPtr->typePtr == &tclWideIntType) {
-#ifndef TCL_WIDE_INT_IS_LONG
- *ptr = (resultPtr->internalRep.wideValue != 0);
-#else
- *ptr = (resultPtr->internalRep.longValue != 0);
-#endif
- } else {
- result = Tcl_GetBooleanFromObj(interp, resultPtr, ptr);
- }
- Tcl_DecrRefCount(resultPtr); /* discard the result object */
- }
+ Tcl_IncrRefCount(exprPtr);
+ result = Tcl_ExprBooleanObj(interp, exprPtr, ptr);
+ Tcl_DecrRefCount(exprPtr);
if (result != TCL_OK) {
/*
- * Move the interpreter's object result to the string result,
- * then reset the object result.
+ * Move the interpreter's object result to the string result, then
+ * reset the object result.
*/
- Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
- TCL_VOLATILE);
+ (void) Tcl_GetStringResult(interp);
}
- Tcl_DecrRefCount(exprPtr); /* discard the expression object */
- } else {
- /*
- * An empty string. Just set the result boolean to 0 (false).
- */
-
- *ptr = 0;
+ return result;
}
- return result;
}
/*
@@ -5544,16 +5450,15 @@ Tcl_ExprBoolean(interp, string, ptr)
*
* Tcl_ExprLongObj, Tcl_ExprDoubleObj, Tcl_ExprBooleanObj --
*
- * Procedures to evaluate an expression in an object and return its
- * value in a particular form.
+ * Functions to evaluate an expression in an object and return its value
+ * in a particular form.
*
* Results:
- * Each of the procedures below returns a standard Tcl result
- * object. If an error occurs then an error message is left in the
- * interpreter's result. Otherwise the value of the expression, in the
- * appropriate form, is stored at *ptr. If the expression had a result
- * that was incompatible with the desired form then an error is
- * returned.
+ * Each of the functions below returns a standard Tcl result object. If
+ * an error occurs then an error message is left in the interpreter's
+ * result. Otherwise the value of the expression, in the appropriate
+ * form, is stored at *ptr. If the expression had a result that was
+ * incompatible with the desired form then an error is returned.
*
* Side effects:
* None.
@@ -5562,230 +5467,117 @@ Tcl_ExprBoolean(interp, string, ptr)
*/
int
-Tcl_ExprLongObj(interp, objPtr, ptr)
- Tcl_Interp *interp; /* Context in which to evaluate the
- * expression. */
- register Tcl_Obj *objPtr; /* Expression to evaluate. */
- long *ptr; /* Where to store long result. */
+Tcl_ExprLongObj(
+ Tcl_Interp *interp, /* Context in which to evaluate the
+ * expression. */
+ register Tcl_Obj *objPtr, /* Expression to evaluate. */
+ long *ptr) /* Where to store long result. */
{
Tcl_Obj *resultPtr;
- int result;
+ int result, type;
+ double d;
+ ClientData internalPtr;
result = Tcl_ExprObj(interp, objPtr, &resultPtr);
- if (result == TCL_OK) {
- if (resultPtr->typePtr == &tclIntType) {
- *ptr = resultPtr->internalRep.longValue;
- } else if (resultPtr->typePtr == &tclDoubleType) {
- *ptr = (long) resultPtr->internalRep.doubleValue;
- } else {
- result = Tcl_GetLongFromObj(interp, resultPtr, ptr);
- if (result != TCL_OK) {
- return result;
- }
+ if (result != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (TclGetNumberFromObj(interp, resultPtr, &internalPtr, &type) != TCL_OK){
+ return TCL_ERROR;
+ }
+
+ switch (type) {
+ case TCL_NUMBER_DOUBLE: {
+ mp_int big;
+
+ d = *((const double *) internalPtr);
+ Tcl_DecrRefCount(resultPtr);
+ if (Tcl_InitBignumFromDouble(interp, d, &big) != TCL_OK) {
+ return TCL_ERROR;
}
- Tcl_DecrRefCount(resultPtr); /* discard the result object */
+ resultPtr = Tcl_NewBignumObj(&big);
+ /* FALLTHROUGH */
}
+ case TCL_NUMBER_LONG:
+ case TCL_NUMBER_WIDE:
+ case TCL_NUMBER_BIG:
+ result = TclGetLongFromObj(interp, resultPtr, ptr);
+ break;
+
+ case TCL_NUMBER_NAN:
+ Tcl_GetDoubleFromObj(interp, resultPtr, &d);
+ result = TCL_ERROR;
+ }
+
+ Tcl_DecrRefCount(resultPtr);/* Discard the result object. */
return result;
}
int
-Tcl_ExprDoubleObj(interp, objPtr, ptr)
- Tcl_Interp *interp; /* Context in which to evaluate the
- * expression. */
- register Tcl_Obj *objPtr; /* Expression to evaluate. */
- double *ptr; /* Where to store double result. */
+Tcl_ExprDoubleObj(
+ Tcl_Interp *interp, /* Context in which to evaluate the
+ * expression. */
+ register Tcl_Obj *objPtr, /* Expression to evaluate. */
+ double *ptr) /* Where to store double result. */
{
Tcl_Obj *resultPtr;
- int result;
+ int result, type;
+ ClientData internalPtr;
result = Tcl_ExprObj(interp, objPtr, &resultPtr);
+ if (result != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ result = TclGetNumberFromObj(interp, resultPtr, &internalPtr, &type);
if (result == TCL_OK) {
- if (resultPtr->typePtr == &tclIntType) {
- *ptr = (double) resultPtr->internalRep.longValue;
- } else if (resultPtr->typePtr == &tclDoubleType) {
- *ptr = resultPtr->internalRep.doubleValue;
- } else {
+ switch (type) {
+ case TCL_NUMBER_NAN:
+#ifndef ACCEPT_NAN
+ result = Tcl_GetDoubleFromObj(interp, resultPtr, ptr);
+ break;
+#endif
+ case TCL_NUMBER_DOUBLE:
+ *ptr = *((const double *) internalPtr);
+ result = TCL_OK;
+ break;
+ default:
result = Tcl_GetDoubleFromObj(interp, resultPtr, ptr);
- if (result != TCL_OK) {
- return result;
- }
}
- Tcl_DecrRefCount(resultPtr); /* discard the result object */
}
+ Tcl_DecrRefCount(resultPtr);/* Discard the result object. */
return result;
}
int
-Tcl_ExprBooleanObj(interp, objPtr, ptr)
- Tcl_Interp *interp; /* Context in which to evaluate the
- * expression. */
- register Tcl_Obj *objPtr; /* Expression to evaluate. */
- int *ptr; /* Where to store 0/1 result. */
+Tcl_ExprBooleanObj(
+ Tcl_Interp *interp, /* Context in which to evaluate the
+ * expression. */
+ register Tcl_Obj *objPtr, /* Expression to evaluate. */
+ int *ptr) /* Where to store 0/1 result. */
{
Tcl_Obj *resultPtr;
int result;
result = Tcl_ExprObj(interp, objPtr, &resultPtr);
if (result == TCL_OK) {
- if (resultPtr->typePtr == &tclIntType) {
- *ptr = (resultPtr->internalRep.longValue != 0);
- } else if (resultPtr->typePtr == &tclDoubleType) {
- *ptr = (resultPtr->internalRep.doubleValue != 0.0);
- } else {
- result = Tcl_GetBooleanFromObj(interp, resultPtr, ptr);
- }
- Tcl_DecrRefCount(resultPtr); /* discard the result object */
- }
- return result;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclInvoke --
- *
- * Invokes a Tcl command, given an argv/argc, from either the
- * exposed or the hidden sets of commands in the given interpreter.
- * NOTE: The command is invoked in the current stack frame of
- * the interpreter, thus it can modify local variables.
- *
- * Results:
- * A standard Tcl result.
- *
- * Side effects:
- * Whatever the command does.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TclInvoke(interp, argc, argv, flags)
- Tcl_Interp *interp; /* Where to invoke the command. */
- int argc; /* Count of args. */
- register CONST char **argv; /* The arg strings; argv[0] is the name of
- * the command to invoke. */
- int flags; /* Combination of flags controlling the
- * call: TCL_INVOKE_HIDDEN and
- * TCL_INVOKE_NO_UNKNOWN. */
-{
- register Tcl_Obj *objPtr;
- register int i;
- int length, result;
-
- /*
- * This procedure generates an objv array for object arguments that hold
- * the argv strings. It starts out with stack-allocated space but uses
- * dynamically-allocated storage if needed.
- */
-
-#define NUM_ARGS 20
- Tcl_Obj *(objStorage[NUM_ARGS]);
- register Tcl_Obj **objv = objStorage;
-
- /*
- * Create the object argument array "objv". Make sure objv is large
- * enough to hold the objc arguments plus 1 extra for the zero
- * end-of-objv word.
- */
-
- if ((argc + 1) > NUM_ARGS) {
- objv = (Tcl_Obj **)
- ckalloc((unsigned)(argc + 1) * sizeof(Tcl_Obj *));
- }
-
- for (i = 0; i < argc; i++) {
- length = strlen(argv[i]);
- objv[i] = Tcl_NewStringObj(argv[i], length);
- Tcl_IncrRefCount(objv[i]);
- }
- objv[argc] = 0;
-
- /*
- * Use TclObjInterpProc to actually invoke the command.
- */
-
- result = TclObjInvoke(interp, argc, objv, flags);
-
- /*
- * Move the interpreter's object result to the string result,
- * then reset the object result.
- */
-
- Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
- TCL_VOLATILE);
-
- /*
- * Decrement the ref counts on the objv elements since we are done
- * with them.
- */
-
- for (i = 0; i < argc; i++) {
- objPtr = objv[i];
- Tcl_DecrRefCount(objPtr);
- }
-
- /*
- * Free the objv array if malloc'ed storage was used.
- */
-
- if (objv != objStorage) {
- ckfree((char *) objv);
+ result = Tcl_GetBooleanFromObj(interp, resultPtr, ptr);
+ Tcl_DecrRefCount(resultPtr);
+ /* Discard the result object. */
}
return result;
-#undef NUM_ARGS
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclGlobalInvoke --
- *
- * Invokes a Tcl command, given an argv/argc, from either the
- * exposed or hidden sets of commands in the given interpreter.
- * NOTE: The command is invoked in the global stack frame of
- * the interpreter, thus it cannot see any current state on
- * the stack for that interpreter.
- *
- * Results:
- * A standard Tcl result.
- *
- * Side effects:
- * Whatever the command does.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TclGlobalInvoke(interp, argc, argv, flags)
- Tcl_Interp *interp; /* Where to invoke the command. */
- int argc; /* Count of args. */
- register CONST char **argv; /* The arg strings; argv[0] is the name of
- * the command to invoke. */
- int flags; /* Combination of flags controlling the
- * call: TCL_INVOKE_HIDDEN and
- * TCL_INVOKE_NO_UNKNOWN. */
-{
- register Interp *iPtr = (Interp *) interp;
- int result;
- CallFrame *savedVarFramePtr;
-
- savedVarFramePtr = iPtr->varFramePtr;
- iPtr->varFramePtr = NULL;
- result = TclInvoke(interp, argc, argv, flags);
- iPtr->varFramePtr = savedVarFramePtr;
- return result;
}
/*
*----------------------------------------------------------------------
*
- * TclObjInvokeGlobal --
+ * TclObjInvokeNamespace --
*
- * Object version: Invokes a Tcl command, given an objv/objc, from
- * either the exposed or hidden set of commands in the given
- * interpreter.
+ * Object version: Invokes a Tcl command, given an objv/objc, from either
+ * the exposed or hidden set of commands in the given interpreter.
* NOTE: The command is invoked in the global stack frame of the
- * interpreter, thus it cannot see any current state on the
+ * interpreter or namespace, thus it cannot see any current state on the
* stack of that interpreter.
*
* Results:
@@ -5798,25 +5590,33 @@ TclGlobalInvoke(interp, argc, argv, flags)
*/
int
-TclObjInvokeGlobal(interp, objc, objv, flags)
- Tcl_Interp *interp; /* Interpreter in which command is to be
+TclObjInvokeNamespace(
+ Tcl_Interp *interp, /* Interpreter in which command is to be
* invoked. */
- int objc; /* Count of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects; objv[0] points to the
+ int objc, /* Count of arguments. */
+ Tcl_Obj *const objv[], /* Argument objects; objv[0] points to the
* name of the command to invoke. */
- int flags; /* Combination of flags controlling the
- * call: TCL_INVOKE_HIDDEN,
- * TCL_INVOKE_NO_UNKNOWN, or
- * TCL_INVOKE_NO_TRACEBACK. */
+ Tcl_Namespace *nsPtr, /* The namespace to use. */
+ int flags) /* Combination of flags controlling the call:
+ * TCL_INVOKE_HIDDEN, TCL_INVOKE_NO_UNKNOWN,
+ * or TCL_INVOKE_NO_TRACEBACK. */
{
- register Interp *iPtr = (Interp *) interp;
int result;
- CallFrame *savedVarFramePtr;
+ Tcl_CallFrame *framePtr;
+
+ /*
+ * Make the specified namespace the current namespace and invoke the
+ * command.
+ */
+
+ result = TclPushStackFrame(interp, &framePtr, nsPtr, /*isProcFrame*/0);
+ if (result != TCL_OK) {
+ return TCL_ERROR;
+ }
- savedVarFramePtr = iPtr->varFramePtr;
- iPtr->varFramePtr = NULL;
result = TclObjInvoke(interp, objc, objv, flags);
- iPtr->varFramePtr = savedVarFramePtr;
+
+ TclPopStackFrame(interp);
return result;
}
@@ -5825,8 +5625,8 @@ TclObjInvokeGlobal(interp, objc, objv, flags)
*
* TclObjInvoke --
*
- * Invokes a Tcl command, given an objv/objc, from either the
- * exposed or the hidden sets of commands in the given interpreter.
+ * Invokes a Tcl command, given an objv/objc, from either the exposed or
+ * the hidden sets of commands in the given interpreter.
*
* Results:
* A standard Tcl object result.
@@ -5838,165 +5638,77 @@ TclObjInvokeGlobal(interp, objc, objv, flags)
*/
int
-TclObjInvoke(interp, objc, objv, flags)
- Tcl_Interp *interp; /* Interpreter in which command is to be
+TclObjInvoke(
+ Tcl_Interp *interp, /* Interpreter in which command is to be
* invoked. */
- int objc; /* Count of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects; objv[0] points to the
+ int objc, /* Count of arguments. */
+ Tcl_Obj *const objv[], /* Argument objects; objv[0] points to the
* name of the command to invoke. */
- int flags; /* Combination of flags controlling the
- * call: TCL_INVOKE_HIDDEN,
- * TCL_INVOKE_NO_UNKNOWN, or
- * TCL_INVOKE_NO_TRACEBACK. */
+ int flags) /* Combination of flags controlling the call:
+ * TCL_INVOKE_HIDDEN, TCL_INVOKE_NO_UNKNOWN,
+ * or TCL_INVOKE_NO_TRACEBACK. */
{
register Interp *iPtr = (Interp *) interp;
Tcl_HashTable *hTblPtr; /* Table of hidden commands. */
char *cmdName; /* Name of the command from objv[0]. */
- register Tcl_HashEntry *hPtr;
- Tcl_Command cmd;
+ Tcl_HashEntry *hPtr = NULL;
Command *cmdPtr;
- int localObjc; /* Used to invoke "unknown" if the */
- Tcl_Obj **localObjv = NULL; /* command is not found. */
- register int i;
int result;
- if (interp == (Tcl_Interp *) NULL) {
- return TCL_ERROR;
+ if (interp == NULL) {
+ return TCL_ERROR;
+ }
+
+ if ((objc < 1) || (objv == NULL)) {
+ Tcl_AppendResult(interp, "illegal argument vector", NULL);
+ return TCL_ERROR;
}
- if ((objc < 1) || (objv == (Tcl_Obj **) NULL)) {
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "illegal argument vector", -1);
- return TCL_ERROR;
+ if ((flags & TCL_INVOKE_HIDDEN) == 0) {
+ Tcl_Panic("TclObjInvoke: called without TCL_INVOKE_HIDDEN");
}
- cmdName = Tcl_GetString(objv[0]);
- if (flags & TCL_INVOKE_HIDDEN) {
- /*
- * We never invoke "unknown" for hidden commands.
- */
-
- hPtr = NULL;
- hTblPtr = ((Interp *) interp)->hiddenCmdTablePtr;
- if (hTblPtr != NULL) {
- hPtr = Tcl_FindHashEntry(hTblPtr, cmdName);
- }
- if (hPtr == NULL) {
- Tcl_ResetResult(interp);
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "invalid hidden command name \"", cmdName, "\"",
- (char *) NULL);
- return TCL_ERROR;
- }
- cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
- } else {
- cmdPtr = NULL;
- cmd = Tcl_FindCommand(interp, cmdName,
- (Tcl_Namespace *) NULL, /*flags*/ TCL_GLOBAL_ONLY);
- if (cmd != (Tcl_Command) NULL) {
- cmdPtr = (Command *) cmd;
- }
- if (cmdPtr == NULL) {
- if (!(flags & TCL_INVOKE_NO_UNKNOWN)) {
- cmd = Tcl_FindCommand(interp, "unknown",
- (Tcl_Namespace *) NULL, /*flags*/ TCL_GLOBAL_ONLY);
- if (cmd != (Tcl_Command) NULL) {
- cmdPtr = (Command *) cmd;
- }
- if (cmdPtr != NULL) {
- localObjc = (objc + 1);
- localObjv = (Tcl_Obj **)
- ckalloc((unsigned) (sizeof(Tcl_Obj *) * localObjc));
- localObjv[0] = Tcl_NewStringObj("unknown", -1);
- Tcl_IncrRefCount(localObjv[0]);
- for (i = 0; i < objc; i++) {
- localObjv[i+1] = objv[i];
- }
- objc = localObjc;
- objv = localObjv;
- }
- }
-
- /*
- * Check again if we found the command. If not, "unknown" is
- * not present and we cannot help, or the caller said not to
- * call "unknown" (they specified TCL_INVOKE_NO_UNKNOWN).
- */
-
- if (cmdPtr == NULL) {
- Tcl_ResetResult(interp);
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "invalid command name \"", cmdName, "\"",
- (char *) NULL);
- return TCL_ERROR;
- }
- }
- }
-
- /*
- * Invoke the command procedure. First reset the interpreter's string
- * and object results to their default empty values since they could
- * have gotten changed by earlier invocations.
+ if (TclInterpReady(interp) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+
+ cmdName = TclGetString(objv[0]);
+ hTblPtr = iPtr->hiddenCmdTablePtr;
+ if (hTblPtr != NULL) {
+ hPtr = Tcl_FindHashEntry(hTblPtr, cmdName);
+ }
+ if (hPtr == NULL) {
+ Tcl_AppendResult(interp, "invalid hidden command name \"",
+ cmdName, "\"", NULL);
+ return TCL_ERROR;
+ }
+ cmdPtr = Tcl_GetHashValue(hPtr);
+
+ /*
+ * Invoke the command function.
*/
- Tcl_ResetResult(interp);
iPtr->cmdCount++;
- result = (*cmdPtr->objProc)(cmdPtr->objClientData, interp, objc, objv);
+ result = cmdPtr->objProc(cmdPtr->objClientData, interp, objc, objv);
/*
- * If an error occurred, record information about what was being
- * executed when the error occurred.
+ * If an error occurred, record information about what was being executed
+ * when the error occurred.
*/
if ((result == TCL_ERROR)
&& ((flags & TCL_INVOKE_NO_TRACEBACK) == 0)
&& ((iPtr->flags & ERR_ALREADY_LOGGED) == 0)) {
- Tcl_Obj *msg;
-
- if (!(iPtr->flags & ERR_IN_PROGRESS)) {
- msg = Tcl_NewStringObj("\n while invoking\n\"", -1);
- } else {
- msg = Tcl_NewStringObj("\n invoked from within\n\"", -1);
- }
- Tcl_IncrRefCount(msg);
- for (i = 0; i < objc; i++) {
- CONST char *bytes;
- int length;
-
- Tcl_AppendObjToObj(msg, objv[i]);
- bytes = Tcl_GetStringFromObj(msg, &length);
- if (length > 100) {
- /*
- * Back up truncation point so that we don't truncate
- * in the middle of a multi-byte character.
- */
- length = 100;
- while ( (bytes[length] & 0xC0) == 0x80 ) {
- length--;
- }
- Tcl_SetObjLength(msg, length);
- Tcl_AppendToObj(msg, "...", -1);
- break;
- }
- if (i != (objc - 1)) {
- Tcl_AppendToObj(msg, " ", -1);
- }
- }
-
- Tcl_AppendToObj(msg, "\"", -1);
- Tcl_AddObjErrorInfo(interp, Tcl_GetString(msg), -1);
- Tcl_DecrRefCount(msg);
+ int length;
+ Tcl_Obj *command = Tcl_NewListObj(objc, objv);
+ const char *cmdString;
+
+ Tcl_IncrRefCount(command);
+ cmdString = Tcl_GetStringFromObj(command, &length);
+ Tcl_LogCommandInfo(interp, cmdString, cmdString, length);
+ Tcl_DecrRefCount(command);
iPtr->flags &= ~ERR_ALREADY_LOGGED;
}
-
- /*
- * Free any locally allocated storage used to call "unknown".
- */
-
- if (localObjv != (Tcl_Obj **) NULL) {
- Tcl_DecrRefCount(localObjv[0]);
- ckfree((char *) localObjv);
- }
return result;
}
@@ -6010,413 +5722,81 @@ TclObjInvoke(interp, objc, objv, flags)
*
* Results:
* A standard Tcl result. If the result is TCL_OK, then the interp's
- * result is set to the string value of the expression. If the result
- * is TCL_ERROR, then the interp's result contains an error message.
+ * result is set to the string value of the expression. If the result is
+ * TCL_ERROR, then the interp's result contains an error message.
*
* Side effects:
* A Tcl object is allocated to hold a copy of the expression string.
- * This expression object is passed to Tcl_ExprObj and then
- * deallocated.
+ * This expression object is passed to Tcl_ExprObj and then deallocated.
*
*---------------------------------------------------------------------------
*/
int
-Tcl_ExprString(interp, string)
- Tcl_Interp *interp; /* Context in which to evaluate the
+Tcl_ExprString(
+ Tcl_Interp *interp, /* Context in which to evaluate the
* expression. */
- CONST char *string; /* Expression to evaluate. */
+ const char *expr) /* Expression to evaluate. */
{
- register Tcl_Obj *exprPtr;
- Tcl_Obj *resultPtr;
- int length = strlen(string);
- char buf[TCL_DOUBLE_SPACE];
- int result = TCL_OK;
-
- if (length > 0) {
- TclNewObj(exprPtr);
- TclInitStringRep(exprPtr, string, length);
- Tcl_IncrRefCount(exprPtr);
+ int code = TCL_OK;
- result = Tcl_ExprObj(interp, exprPtr, &resultPtr);
- if (result == TCL_OK) {
- /*
- * Set the interpreter's string result from the result object.
- */
-
- if (resultPtr->typePtr == &tclIntType) {
- sprintf(buf, "%ld", resultPtr->internalRep.longValue);
- Tcl_SetResult(interp, buf, TCL_VOLATILE);
- } else if (resultPtr->typePtr == &tclDoubleType) {
- Tcl_PrintDouble((Tcl_Interp *) NULL,
- resultPtr->internalRep.doubleValue, buf);
- Tcl_SetResult(interp, buf, TCL_VOLATILE);
- } else {
- /*
- * Set interpreter's string result from the result object.
- */
-
- Tcl_SetResult(interp, TclGetString(resultPtr),
- TCL_VOLATILE);
- }
- Tcl_DecrRefCount(resultPtr); /* discard the result object */
- } else {
- /*
- * Move the interpreter's object result to the string result,
- * then reset the object result.
- */
-
- Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
- TCL_VOLATILE);
- }
- Tcl_DecrRefCount(exprPtr); /* discard the expression object */
- } else {
+ if (expr[0] == '\0') {
/*
* An empty string. Just set the interpreter's result to 0.
*/
-
- Tcl_SetResult(interp, "0", TCL_VOLATILE);
- }
- return result;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tcl_CreateObjTrace --
- *
- * Arrange for a procedure to be called to trace command execution.
- *
- * Results:
- * The return value is a token for the trace, which may be passed
- * to Tcl_DeleteTrace to eliminate the trace.
- *
- * Side effects:
- * From now on, proc will be called just before a command procedure
- * is called to execute a Tcl command. Calls to proc will have the
- * following form:
- *
- * void proc( ClientData clientData,
- * Tcl_Interp* interp,
- * int level,
- * CONST char* command,
- * Tcl_Command commandInfo,
- * int objc,
- * Tcl_Obj *CONST objv[] );
- *
- * The 'clientData' and 'interp' arguments to 'proc' will be the
- * same as the arguments to Tcl_CreateObjTrace. The 'level'
- * argument gives the nesting depth of command interpretation within
- * the interpreter. The 'command' argument is the ASCII text of
- * the command being evaluated -- before any substitutions are
- * performed. The 'commandInfo' argument gives a handle to the
- * command procedure that will be evaluated. The 'objc' and 'objv'
- * parameters give the parameter vector that will be passed to the
- * command procedure. proc does not return a value.
- *
- * It is permissible for 'proc' to call Tcl_SetCommandTokenInfo
- * to change the command procedure or client data for the command
- * being evaluated, and these changes will take effect with the
- * current evaluation.
- *
- * The 'level' argument specifies the maximum nesting level of calls
- * to be traced. If the execution depth of the interpreter exceeds
- * 'level', the trace callback is not executed.
- *
- * The 'flags' argument is either zero or the value,
- * TCL_ALLOW_INLINE_COMPILATION. If the TCL_ALLOW_INLINE_COMPILATION
- * flag is not present, the bytecode compiler will not generate inline
- * code for Tcl's built-in commands. This behavior will have a significant
- * impact on performance, but will ensure that all command evaluations are
- * traced. If the TCL_ALLOW_INLINE_COMPILATION flag is present, the
- * bytecode compiler will have its normal behavior of compiling in-line
- * code for some of Tcl's built-in commands. In this case, the tracing
- * will be imprecise -- in-line code will not be traced -- but run-time
- * performance will be improved. The latter behavior is desired for
- * many applications such as profiling of run time.
- *
- * When the trace is deleted, the 'delProc' procedure will be invoked,
- * passing it the original client data.
- *
- *----------------------------------------------------------------------
- */
-Tcl_Trace
-Tcl_CreateObjTrace( interp, level, flags, proc, clientData, delProc )
- Tcl_Interp* interp; /* Tcl interpreter */
- int level; /* Maximum nesting level */
- int flags; /* Flags, see above */
- Tcl_CmdObjTraceProc* proc; /* Trace callback */
- ClientData clientData; /* Client data for the callback */
- Tcl_CmdObjTraceDeleteProc* delProc;
- /* Procedure to call when trace is deleted */
-{
- register Trace *tracePtr;
- register Interp *iPtr = (Interp *) interp;
-
- /* Test if this trace allows inline compilation of commands */
-
- if (!(flags & TCL_ALLOW_INLINE_COMPILATION)) {
- if (iPtr->tracesForbiddingInline == 0) {
-
- /*
- * When the first trace forbidding inline compilation is
- * created, invalidate existing compiled code for this
- * interpreter and arrange (by setting the
- * DONT_COMPILE_CMDS_INLINE flag) that when compiling new
- * code, no commands will be compiled inline (i.e., into
- * an inline sequence of instructions). We do this because
- * commands that were compiled inline will never result in
- * a command trace being called.
- */
-
- iPtr->compileEpoch++;
- iPtr->flags |= DONT_COMPILE_CMDS_INLINE;
+ Tcl_SetResult(interp, "0", TCL_VOLATILE);
+ } else {
+ Tcl_Obj *resultPtr, *exprObj = Tcl_NewStringObj(expr, -1);
+
+ Tcl_IncrRefCount(exprObj);
+ code = Tcl_ExprObj(interp, exprObj, &resultPtr);
+ Tcl_DecrRefCount(exprObj);
+ if (code == TCL_OK) {
+ Tcl_SetObjResult(interp, resultPtr);
+ Tcl_DecrRefCount(resultPtr);
}
- iPtr->tracesForbiddingInline++;
- }
-
- tracePtr = (Trace *) ckalloc(sizeof(Trace));
- tracePtr->level = level;
- tracePtr->proc = proc;
- tracePtr->clientData = clientData;
- tracePtr->delProc = delProc;
- tracePtr->nextPtr = iPtr->tracePtr;
- tracePtr->flags = flags;
- iPtr->tracePtr = tracePtr;
-
- return (Tcl_Trace) tracePtr;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tcl_CreateTrace --
- *
- * Arrange for a procedure to be called to trace command execution.
- *
- * Results:
- * The return value is a token for the trace, which may be passed
- * to Tcl_DeleteTrace to eliminate the trace.
- *
- * Side effects:
- * From now on, proc will be called just before a command procedure
- * is called to execute a Tcl command. Calls to proc will have the
- * following form:
- *
- * void
- * proc(clientData, interp, level, command, cmdProc, cmdClientData,
- * argc, argv)
- * ClientData clientData;
- * Tcl_Interp *interp;
- * int level;
- * char *command;
- * int (*cmdProc)();
- * ClientData cmdClientData;
- * int argc;
- * char **argv;
- * {
- * }
- *
- * The clientData and interp arguments to proc will be the same
- * as the corresponding arguments to this procedure. Level gives
- * the nesting level of command interpretation for this interpreter
- * (0 corresponds to top level). Command gives the ASCII text of
- * the raw command, cmdProc and cmdClientData give the procedure that
- * will be called to process the command and the ClientData value it
- * will receive, and argc and argv give the arguments to the
- * command, after any argument parsing and substitution. Proc
- * does not return a value.
- *
- *----------------------------------------------------------------------
- */
-Tcl_Trace
-Tcl_CreateTrace(interp, level, proc, clientData)
- Tcl_Interp *interp; /* Interpreter in which to create trace. */
- int level; /* Only call proc for commands at nesting
- * level<=argument level (1=>top level). */
- Tcl_CmdTraceProc *proc; /* Procedure to call before executing each
- * command. */
- ClientData clientData; /* Arbitrary value word to pass to proc. */
-{
- StringTraceData* data;
- data = (StringTraceData*) ckalloc( sizeof( *data ));
- data->clientData = clientData;
- data->proc = proc;
- return Tcl_CreateObjTrace( interp, level, 0, StringTraceProc,
- (ClientData) data, StringTraceDeleteProc );
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * StringTraceProc --
- *
- * Invoke a string-based trace procedure from an object-based
- * callback.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Whatever the string-based trace procedure does.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-StringTraceProc( clientData, interp, level, command, commandInfo, objc, objv )
- ClientData clientData;
- Tcl_Interp* interp;
- int level;
- CONST char* command;
- Tcl_Command commandInfo;
- int objc;
- Tcl_Obj *CONST *objv;
-{
- StringTraceData* data = (StringTraceData*) clientData;
- Command* cmdPtr = (Command*) commandInfo;
-
- CONST char** argv; /* Args to pass to string trace proc */
-
- int i;
+ /*
+ * Force the string rep of the interp result.
+ */
- /*
- * This is a bit messy because we have to emulate the old trace
- * interface, which uses strings for everything.
- */
-
- argv = (CONST char **) ckalloc((unsigned) ( (objc + 1)
- * sizeof(CONST char *) ));
- for (i = 0; i < objc; i++) {
- argv[i] = Tcl_GetString(objv[i]);
+ (void) Tcl_GetStringResult(interp);
}
- argv[objc] = 0;
-
- /*
- * Invoke the command procedure. Note that we cast away const-ness
- * on two parameters for compatibility with legacy code; the code
- * MUST NOT modify either command or argv.
- */
-
- ( data->proc )( data->clientData, interp, level,
- (char*) command, cmdPtr->proc, cmdPtr->clientData,
- objc, argv );
- ckfree( (char*) argv );
-
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * StringTraceDeleteProc --
- *
- * Clean up memory when a string-based trace is deleted.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Allocated memory is returned to the system.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-StringTraceDeleteProc( clientData )
- ClientData clientData;
-{
- ckfree( (char*) clientData );
+ return code;
}
/*
*----------------------------------------------------------------------
*
- * Tcl_DeleteTrace --
+ * Tcl_AppendObjToErrorInfo --
*
- * Remove a trace.
+ * Add a Tcl_Obj value to the errorInfo field that describes the current
+ * error.
*
* Results:
* None.
*
* Side effects:
- * From now on there will be no more calls to the procedure given
- * in trace.
+ * The value of the Tcl_obj is appended to the errorInfo field. If we are
+ * just starting to log an error, errorInfo is initialized from the error
+ * message in the interpreter's result.
*
*----------------------------------------------------------------------
*/
void
-Tcl_DeleteTrace(interp, trace)
- Tcl_Interp *interp; /* Interpreter that contains trace. */
- Tcl_Trace trace; /* Token for trace (returned previously by
- * Tcl_CreateTrace). */
+Tcl_AppendObjToErrorInfo(
+ Tcl_Interp *interp, /* Interpreter to which error information
+ * pertains. */
+ Tcl_Obj *objPtr) /* Message to record. */
{
- Interp *iPtr = (Interp *) interp;
- Trace *prevPtr, *tracePtr = (Trace *) trace;
- register Trace **tracePtr2 = &(iPtr->tracePtr);
- ActiveInterpTrace *activePtr;
-
- /*
- * Locate the trace entry in the interpreter's trace list,
- * and remove it from the list.
- */
+ int length;
+ const char *message = TclGetStringFromObj(objPtr, &length);
- prevPtr = NULL;
- while ((*tracePtr2) != NULL && (*tracePtr2) != tracePtr) {
- prevPtr = *tracePtr2;
- tracePtr2 = &((*tracePtr2)->nextPtr);
- }
- if (*tracePtr2 == NULL) {
- return;
- }
- (*tracePtr2) = (*tracePtr2)->nextPtr;
-
- /*
- * The code below makes it possible to delete traces while traces
- * are active: it makes sure that the deleted trace won't be
- * processed by TclCheckInterpTraces.
- */
-
- for (activePtr = iPtr->activeInterpTracePtr; activePtr != NULL;
- activePtr = activePtr->nextPtr) {
- if (activePtr->nextTracePtr == tracePtr) {
- if (activePtr->reverseScan) {
- activePtr->nextTracePtr = prevPtr;
- } else {
- activePtr->nextTracePtr = tracePtr->nextPtr;
- }
- }
- }
-
- /*
- * If the trace forbids bytecode compilation, change the interpreter's
- * state. If bytecode compilation is now permitted, flag the fact and
- * advance the compilation epoch so that procs will be recompiled to
- * take advantage of it.
- */
-
- if (!(tracePtr->flags & TCL_ALLOW_INLINE_COMPILATION)) {
- iPtr->tracesForbiddingInline--;
- if (iPtr->tracesForbiddingInline == 0) {
- iPtr->flags &= ~DONT_COMPILE_CMDS_INLINE;
- iPtr->compileEpoch++;
- }
- }
-
- /*
- * Execute any delete callback.
- */
-
- if (tracePtr->delProc != NULL) {
- (tracePtr->delProc)(tracePtr->clientData);
- }
-
- /* Delete the trace object */
-
- Tcl_EventuallyFree((char*)tracePtr, TCL_DYNAMIC);
+ Tcl_IncrRefCount(objPtr);
+ Tcl_AddObjErrorInfo(interp, message, length);
+ Tcl_DecrRefCount(objPtr);
}
/*
@@ -6424,27 +5804,25 @@ Tcl_DeleteTrace(interp, trace)
*
* Tcl_AddErrorInfo --
*
- * Add information to the "errorInfo" variable that describes the
- * current error.
+ * Add information to the errorInfo field that describes the current
+ * error.
*
* Results:
* None.
*
* Side effects:
- * The contents of message are added to the "errorInfo" variable.
- * If Tcl_Eval has been called since the current value of errorInfo
- * was set, errorInfo is cleared before adding the new message.
- * If we are just starting to log an error, errorInfo is initialized
- * from the error message in the interpreter's result.
+ * The contents of message are appended to the errorInfo field. If we are
+ * just starting to log an error, errorInfo is initialized from the error
+ * message in the interpreter's result.
*
*----------------------------------------------------------------------
*/
void
-Tcl_AddErrorInfo(interp, message)
- Tcl_Interp *interp; /* Interpreter to which error information
+Tcl_AddErrorInfo(
+ Tcl_Interp *interp, /* Interpreter to which error information
* pertains. */
- CONST char *message; /* Message to record. */
+ const char *message) /* Message to record. */
{
Tcl_AddObjErrorInfo(interp, message, -1);
}
@@ -6454,67 +5832,56 @@ Tcl_AddErrorInfo(interp, message)
*
* Tcl_AddObjErrorInfo --
*
- * Add information to the "errorInfo" variable that describes the
- * current error. This routine differs from Tcl_AddErrorInfo by
- * taking a byte pointer and length.
+ * Add information to the errorInfo field that describes the current
+ * error. This routine differs from Tcl_AddErrorInfo by taking a byte
+ * pointer and length.
*
* Results:
* None.
*
* Side effects:
- * "length" bytes from "message" are added to the "errorInfo" variable.
- * If "length" is negative, use bytes up to the first NULL byte.
- * If Tcl_EvalObj has been called since the current value of errorInfo
- * was set, errorInfo is cleared before adding the new message.
- * If we are just starting to log an error, errorInfo is initialized
- * from the error message in the interpreter's result.
+ * "length" bytes from "message" are appended to the errorInfo field. If
+ * "length" is negative, use bytes up to the first NULL byte. If we are
+ * just starting to log an error, errorInfo is initialized from the error
+ * message in the interpreter's result.
*
*----------------------------------------------------------------------
*/
void
-Tcl_AddObjErrorInfo(interp, message, length)
- Tcl_Interp *interp; /* Interpreter to which error information
+Tcl_AddObjErrorInfo(
+ Tcl_Interp *interp, /* Interpreter to which error information
* pertains. */
- CONST char *message; /* Points to the first byte of an array of
+ const char *message, /* Points to the first byte of an array of
* bytes of the message. */
- int length; /* The number of bytes in the message.
- * If < 0, then append all bytes up to a
- * NULL byte. */
+ int length) /* The number of bytes in the message. If < 0,
+ * then append all bytes up to a NULL byte. */
{
register Interp *iPtr = (Interp *) interp;
- Tcl_Obj *objPtr;
-
+
/*
- * If we are just starting to log an error, errorInfo is initialized
- * from the error message in the interpreter's result.
+ * If we are just starting to log an error, errorInfo is initialized from
+ * the error message in the interpreter's result.
*/
- if (!(iPtr->flags & ERR_IN_PROGRESS)) { /* just starting to log error */
- iPtr->flags |= ERR_IN_PROGRESS;
+ iPtr->flags |= ERR_LEGACY_COPY;
+ if (iPtr->errorInfo == NULL) {
+ if (iPtr->result[0] != 0) {
+ /*
+ * The interp's string result is set, apparently by some extension
+ * making a deprecated direct write to it. That extension may
+ * expect interp->result to continue to be set, so we'll take
+ * special pains to avoid clearing it, until we drop support for
+ * interp->result completely.
+ */
- if (iPtr->result[0] == 0) {
- Tcl_ObjSetVar2(interp, iPtr->execEnvPtr->errorInfo, NULL,
- iPtr->objResultPtr, TCL_GLOBAL_ONLY);
- } else { /* use the string result */
- objPtr = Tcl_NewStringObj(interp->result, -1);
- Tcl_IncrRefCount(objPtr);
- Tcl_ObjSetVar2(interp, iPtr->execEnvPtr->errorInfo, NULL,
- objPtr, TCL_GLOBAL_ONLY);
- Tcl_DecrRefCount(objPtr);
+ iPtr->errorInfo = Tcl_NewStringObj(interp->result, -1);
+ } else {
+ iPtr->errorInfo = iPtr->objResultPtr;
}
-
- /*
- * If the errorCode variable wasn't set by the code that generated
- * the error, set it to "NONE".
- */
-
- if (!(iPtr->flags & ERROR_CODE_SET)) {
- objPtr = Tcl_NewStringObj("NONE", -1);
- Tcl_IncrRefCount(objPtr);
- Tcl_ObjSetVar2(interp, iPtr->execEnvPtr->errorCode, NULL,
- objPtr, TCL_GLOBAL_ONLY);
- Tcl_DecrRefCount(objPtr);
+ Tcl_IncrRefCount(iPtr->errorInfo);
+ if (!iPtr->errorCode) {
+ Tcl_SetErrorCode(interp, "NONE", NULL);
}
}
@@ -6523,11 +5890,12 @@ Tcl_AddObjErrorInfo(interp, message, length)
*/
if (length != 0) {
- objPtr = Tcl_NewStringObj(message, length);
- Tcl_IncrRefCount(objPtr);
- Tcl_ObjSetVar2(interp, iPtr->execEnvPtr->errorInfo, NULL,
- objPtr, (TCL_GLOBAL_ONLY | TCL_APPEND_VALUE));
- Tcl_DecrRefCount(objPtr); /* free msg object appended above */
+ if (Tcl_IsShared(iPtr->errorInfo)) {
+ Tcl_DecrRefCount(iPtr->errorInfo);
+ iPtr->errorInfo = Tcl_DuplicateObj(iPtr->errorInfo);
+ Tcl_IncrRefCount(iPtr->errorInfo);
+ }
+ Tcl_AppendToObj(iPtr->errorInfo, message, length);
}
}
@@ -6536,12 +5904,12 @@ Tcl_AddObjErrorInfo(interp, message, length)
*
* Tcl_VarEvalVA --
*
- * Given a variable number of string arguments, concatenate them
- * all together and execute the result as a Tcl command.
+ * Given a variable number of string arguments, concatenate them all
+ * together and execute the result as a Tcl command.
*
* Results:
- * A standard Tcl return result. An error message or other result may
- * be left in the interp's result.
+ * A standard Tcl return result. An error message or other result may be
+ * left in the interp's result.
*
* Side effects:
* Depends on what was done by the command.
@@ -6550,19 +5918,18 @@ Tcl_AddObjErrorInfo(interp, message, length)
*/
int
-Tcl_VarEvalVA (interp, argList)
- Tcl_Interp *interp; /* Interpreter in which to evaluate command. */
- va_list argList; /* Variable argument list. */
+Tcl_VarEvalVA(
+ Tcl_Interp *interp, /* Interpreter in which to evaluate command. */
+ va_list argList) /* Variable argument list. */
{
Tcl_DString buf;
char *string;
int result;
/*
- * Copy the strings one after the other into a single larger
- * string. Use stack-allocated space for small commands, but if
- * the command gets too large than call ckalloc to create the
- * space.
+ * Copy the strings one after the other into a single larger string. Use
+ * stack-allocated space for small commands, but if the command gets too
+ * large than call ckalloc to create the space.
*/
Tcl_DStringInit(&buf);
@@ -6584,27 +5951,28 @@ Tcl_VarEvalVA (interp, argList)
*
* Tcl_VarEval --
*
- * Given a variable number of string arguments, concatenate them
- * all together and execute the result as a Tcl command.
+ * Given a variable number of string arguments, concatenate them all
+ * together and execute the result as a Tcl command.
*
* Results:
- * A standard Tcl return result. An error message or other
- * result may be left in interp->result.
+ * A standard Tcl return result. An error message or other result may be
+ * left in interp->result.
*
* Side effects:
* Depends on what was done by the command.
*
*----------------------------------------------------------------------
*/
- /* VARARGS2 */ /* ARGSUSED */
+ /* ARGSUSED */
int
-Tcl_VarEval TCL_VARARGS_DEF(Tcl_Interp *,arg1)
+Tcl_VarEval(
+ Tcl_Interp *interp,
+ ...)
{
- Tcl_Interp *interp;
va_list argList;
int result;
- interp = TCL_VARARGS_START(Tcl_Interp *,arg1,argList);
+ va_start(argList, interp);
result = Tcl_VarEvalVA(interp, argList);
va_end(argList);
@@ -6612,36 +5980,35 @@ Tcl_VarEval TCL_VARARGS_DEF(Tcl_Interp *,arg1)
}
/*
- *---------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* Tcl_GlobalEval --
*
* Evaluate a command at global level in an interpreter.
*
* Results:
- * A standard Tcl result is returned, and the interp's result is
- * modified accordingly.
+ * A standard Tcl result is returned, and the interp's result is modified
+ * accordingly.
*
* Side effects:
- * The command string is executed in interp, and the execution
- * is carried out in the variable context of global level (no
- * procedures active), just as if an "uplevel #0" command were
- * being executed.
+ * The command string is executed in interp, and the execution is carried
+ * out in the variable context of global level (no functions active),
+ * just as if an "uplevel #0" command were being executed.
*
- ---------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
int
-Tcl_GlobalEval(interp, command)
- Tcl_Interp *interp; /* Interpreter in which to evaluate command. */
- CONST char *command; /* Command to evaluate. */
+Tcl_GlobalEval(
+ Tcl_Interp *interp, /* Interpreter in which to evaluate command. */
+ const char *command) /* Command to evaluate. */
{
register Interp *iPtr = (Interp *) interp;
int result;
CallFrame *savedVarFramePtr;
savedVarFramePtr = iPtr->varFramePtr;
- iPtr->varFramePtr = NULL;
+ iPtr->varFramePtr = iPtr->rootFramePtr;
result = Tcl_Eval(interp, command);
iPtr->varFramePtr = savedVarFramePtr;
return result;
@@ -6652,8 +6019,8 @@ Tcl_GlobalEval(interp, command)
*
* Tcl_SetRecursionLimit --
*
- * Set the maximum number of recursive calls that may be active
- * for an interpreter at once.
+ * Set the maximum number of recursive calls that may be active for an
+ * interpreter at once.
*
* Results:
* The return value is the old limit on nesting for interp.
@@ -6665,10 +6032,10 @@ Tcl_GlobalEval(interp, command)
*/
int
-Tcl_SetRecursionLimit(interp, depth)
- Tcl_Interp *interp; /* Interpreter whose nesting limit
- * is to be set. */
- int depth; /* New value for maximimum depth. */
+Tcl_SetRecursionLimit(
+ Tcl_Interp *interp, /* Interpreter whose nesting limit is to be
+ * set. */
+ int depth) /* New value for maximimum depth. */
{
Interp *iPtr = (Interp *) interp;
int old;
@@ -6685,39 +6052,36 @@ Tcl_SetRecursionLimit(interp, depth)
*
* Tcl_AllowExceptions --
*
- * Sets a flag in an interpreter so that exceptions can occur
- * in the next call to Tcl_Eval without them being turned into
- * errors.
+ * Sets a flag in an interpreter so that exceptions can occur in the next
+ * call to Tcl_Eval without them being turned into errors.
*
* Results:
* None.
*
* Side effects:
- * The TCL_ALLOW_EXCEPTIONS flag gets set in the interpreter's
- * evalFlags structure. See the reference documentation for
- * more details.
+ * The TCL_ALLOW_EXCEPTIONS flag gets set in the interpreter's evalFlags
+ * structure. See the reference documentation for more details.
*
*----------------------------------------------------------------------
*/
void
-Tcl_AllowExceptions(interp)
- Tcl_Interp *interp; /* Interpreter in which to set flag. */
+Tcl_AllowExceptions(
+ Tcl_Interp *interp) /* Interpreter in which to set flag. */
{
Interp *iPtr = (Interp *) interp;
iPtr->evalFlags |= TCL_ALLOW_EXCEPTIONS;
}
-
/*
*----------------------------------------------------------------------
*
- * Tcl_GetVersion
+ * Tcl_GetVersion --
*
- * Get the Tcl major, minor, and patchlevel version numbers and
- * the release type. A patch is a release type TCL_FINAL_RELEASE
- * with a patchLevel > 0.
+ * Get the Tcl major, minor, and patchlevel version numbers and the
+ * release type. A patch is a release type TCL_FINAL_RELEASE with a
+ * patchLevel > 0.
*
* Results:
* None.
@@ -6729,24 +6093,898 @@ Tcl_AllowExceptions(interp)
*/
void
-Tcl_GetVersion(majorV, minorV, patchLevelV, type)
- int *majorV;
- int *minorV;
- int *patchLevelV;
- int *type;
+Tcl_GetVersion(
+ int *majorV,
+ int *minorV,
+ int *patchLevelV,
+ int *type)
{
if (majorV != NULL) {
- *majorV = TCL_MAJOR_VERSION;
+ *majorV = TCL_MAJOR_VERSION;
}
if (minorV != NULL) {
- *minorV = TCL_MINOR_VERSION;
+ *minorV = TCL_MINOR_VERSION;
}
if (patchLevelV != NULL) {
- *patchLevelV = TCL_RELEASE_SERIAL;
+ *patchLevelV = TCL_RELEASE_SERIAL;
}
if (type != NULL) {
- *type = TCL_RELEASE_LEVEL;
+ *type = TCL_RELEASE_LEVEL;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Math Functions --
+ *
+ * This page contains the functions that implement all of the built-in
+ * math functions for expressions.
+ *
+ * Results:
+ * Each function returns TCL_OK if it succeeds and pushes an Tcl object
+ * holding the result. If it fails it returns TCL_ERROR and leaves an
+ * error message in the interpreter's result.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ExprCeilFunc(
+ ClientData clientData, /* Ignored */
+ Tcl_Interp *interp, /* The interpreter in which to execute the
+ * function. */
+ int objc, /* Actual parameter count. */
+ Tcl_Obj *const *objv) /* Actual parameter list. */
+{
+ int code;
+ double d;
+ mp_int big;
+
+ if (objc != 2) {
+ MathFuncWrongNumArgs(interp, 2, objc, objv);
+ return TCL_ERROR;
}
+ code = Tcl_GetDoubleFromObj(interp, objv[1], &d);
+#ifdef ACCEPT_NAN
+ if ((code != TCL_OK) && (objv[1]->typePtr == &tclDoubleType)) {
+ Tcl_SetObjResult(interp, objv[1]);
+ return TCL_OK;
+ }
+#endif
+ if (code != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (Tcl_GetBignumFromObj(NULL, objv[1], &big) == TCL_OK) {
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(TclCeil(&big)));
+ mp_clear(&big);
+ } else {
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(ceil(d)));
+ }
+ return TCL_OK;
+}
+
+static int
+ExprFloorFunc(
+ ClientData clientData, /* Ignored */
+ Tcl_Interp *interp, /* The interpreter in which to execute the
+ * function. */
+ int objc, /* Actual parameter count. */
+ Tcl_Obj *const *objv) /* Actual parameter list. */
+{
+ int code;
+ double d;
+ mp_int big;
+
+ if (objc != 2) {
+ MathFuncWrongNumArgs(interp, 2, objc, objv);
+ return TCL_ERROR;
+ }
+ code = Tcl_GetDoubleFromObj(interp, objv[1], &d);
+#ifdef ACCEPT_NAN
+ if ((code != TCL_OK) && (objv[1]->typePtr == &tclDoubleType)) {
+ Tcl_SetObjResult(interp, objv[1]);
+ return TCL_OK;
+ }
+#endif
+ if (code != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (Tcl_GetBignumFromObj(NULL, objv[1], &big) == TCL_OK) {
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(TclFloor(&big)));
+ mp_clear(&big);
+ } else {
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(floor(d)));
+ }
+ return TCL_OK;
+}
+
+static int
+ExprIsqrtFunc(
+ ClientData clientData, /* Ignored */
+ Tcl_Interp *interp, /* The interpreter in which to execute. */
+ int objc, /* Actual parameter count. */
+ Tcl_Obj *const *objv) /* Actual parameter list. */
+{
+ ClientData ptr;
+ int type;
+ double d;
+ Tcl_WideInt w;
+ mp_int big;
+ int exact = 0; /* Flag == 1 if the argument can be
+ * represented in a double as an exact
+ * integer. */
+
+ /*
+ * Check syntax.
+ */
+
+ if (objc != 2) {
+ MathFuncWrongNumArgs(interp, 2, objc, objv);
+ return TCL_ERROR;
+ }
+
+ /*
+ * Make sure that the arg is a number.
+ */
+
+ if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ switch (type) {
+ case TCL_NUMBER_NAN:
+ Tcl_GetDoubleFromObj(interp, objv[1], &d);
+ return TCL_ERROR;
+ case TCL_NUMBER_DOUBLE:
+ d = *((const double *) ptr);
+ if (d < 0) {
+ goto negarg;
+ }
+#ifdef IEEE_FLOATING_POINT
+ if (d <= MAX_EXACT) {
+ exact = 1;
+ }
+#endif
+ if (!exact) {
+ if (Tcl_InitBignumFromDouble(interp, d, &big) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ }
+ break;
+ case TCL_NUMBER_BIG:
+ if (Tcl_GetBignumFromObj(interp, objv[1], &big) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (SIGN(&big) == MP_NEG) {
+ mp_clear(&big);
+ goto negarg;
+ }
+ break;
+ default:
+ if (Tcl_GetWideIntFromObj(interp, objv[1], &w) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (w < 0) {
+ goto negarg;
+ }
+ d = (double) w;
+#ifdef IEEE_FLOATING_POINT
+ if (d < MAX_EXACT) {
+ exact = 1;
+ }
+#endif
+ if (!exact) {
+ Tcl_GetBignumFromObj(interp, objv[1], &big);
+ }
+ break;
+ }
+
+ if (exact) {
+ Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt) sqrt(d)));
+ } else {
+ mp_int root;
+
+ mp_init(&root);
+ mp_sqrt(&big, &root);
+ mp_clear(&big);
+ Tcl_SetObjResult(interp, Tcl_NewBignumObj(&root));
+ }
+
+ return TCL_OK;
+
+ negarg:
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj("square root of negative argument", -1));
+ return TCL_ERROR;
+}
+
+static int
+ExprSqrtFunc(
+ ClientData clientData, /* Ignored */
+ Tcl_Interp *interp, /* The interpreter in which to execute the
+ * function. */
+ int objc, /* Actual parameter count. */
+ Tcl_Obj *const *objv) /* Actual parameter list. */
+{
+ int code;
+ double d;
+ mp_int big;
+
+ if (objc != 2) {
+ MathFuncWrongNumArgs(interp, 2, objc, objv);
+ return TCL_ERROR;
+ }
+ code = Tcl_GetDoubleFromObj(interp, objv[1], &d);
+#ifdef ACCEPT_NAN
+ if ((code != TCL_OK) && (objv[1]->typePtr == &tclDoubleType)) {
+ Tcl_SetObjResult(interp, objv[1]);
+ return TCL_OK;
+ }
+#endif
+ if (code != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if ((d >= 0.0) && TclIsInfinite(d)
+ && (Tcl_GetBignumFromObj(NULL, objv[1], &big) == TCL_OK)) {
+ mp_int root;
+
+ mp_init(&root);
+ mp_sqrt(&big, &root);
+ mp_clear(&big);
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(TclBignumToDouble(&root)));
+ mp_clear(&root);
+ } else {
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(sqrt(d)));
+ }
+ return TCL_OK;
+}
+
+static int
+ExprUnaryFunc(
+ ClientData clientData, /* Contains the address of a function that
+ * takes one double argument and returns a
+ * double result. */
+ Tcl_Interp *interp, /* The interpreter in which to execute the
+ * function. */
+ int objc, /* Actual parameter count */
+ Tcl_Obj *const *objv) /* Actual parameter list */
+{
+ int code;
+ double d;
+ double (*func)(double) = (double (*)(double)) clientData;
+
+ if (objc != 2) {
+ MathFuncWrongNumArgs(interp, 2, objc, objv);
+ return TCL_ERROR;
+ }
+ code = Tcl_GetDoubleFromObj(interp, objv[1], &d);
+#ifdef ACCEPT_NAN
+ if ((code != TCL_OK) && (objv[1]->typePtr == &tclDoubleType)) {
+ d = objv[1]->internalRep.doubleValue;
+ Tcl_ResetResult(interp);
+ code = TCL_OK;
+ }
+#endif
+ if (code != TCL_OK) {
+ return TCL_ERROR;
+ }
+ errno = 0;
+ return CheckDoubleResult(interp, (*func)(d));
+}
+
+static int
+CheckDoubleResult(
+ Tcl_Interp *interp,
+ double dResult)
+{
+#ifndef ACCEPT_NAN
+ if (TclIsNaN(dResult)) {
+ TclExprFloatError(interp, dResult);
+ return TCL_ERROR;
+ }
+#endif
+ if ((errno == ERANGE) && ((dResult == 0.0) || TclIsInfinite(dResult))) {
+ /*
+ * When ERANGE signals under/overflow, just accept 0.0 or +/-Inf
+ */
+ } else if (errno != 0) {
+ /*
+ * Report other errno values as errors.
+ */
+
+ TclExprFloatError(interp, dResult);
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(dResult));
+ return TCL_OK;
+}
+
+static int
+ExprBinaryFunc(
+ ClientData clientData, /* Contains the address of a function that
+ * takes two double arguments and returns a
+ * double result. */
+ Tcl_Interp *interp, /* The interpreter in which to execute the
+ * function. */
+ int objc, /* Actual parameter count. */
+ Tcl_Obj *const *objv) /* Parameter vector. */
+{
+ int code;
+ double d1, d2;
+ double (*func)(double, double) = (double (*)(double, double)) clientData;
+
+ if (objc != 3) {
+ MathFuncWrongNumArgs(interp, 3, objc, objv);
+ return TCL_ERROR;
+ }
+ code = Tcl_GetDoubleFromObj(interp, objv[1], &d1);
+#ifdef ACCEPT_NAN
+ if ((code != TCL_OK) && (objv[1]->typePtr == &tclDoubleType)) {
+ d1 = objv[1]->internalRep.doubleValue;
+ Tcl_ResetResult(interp);
+ code = TCL_OK;
+ }
+#endif
+ if (code != TCL_OK) {
+ return TCL_ERROR;
+ }
+ code = Tcl_GetDoubleFromObj(interp, objv[2], &d2);
+#ifdef ACCEPT_NAN
+ if ((code != TCL_OK) && (objv[2]->typePtr == &tclDoubleType)) {
+ d2 = objv[2]->internalRep.doubleValue;
+ Tcl_ResetResult(interp);
+ code = TCL_OK;
+ }
+#endif
+ if (code != TCL_OK) {
+ return TCL_ERROR;
+ }
+ errno = 0;
+ return CheckDoubleResult(interp, (*func)(d1, d2));
+}
+
+static int
+ExprAbsFunc(
+ ClientData clientData, /* Ignored. */
+ Tcl_Interp *interp, /* The interpreter in which to execute the
+ * function. */
+ int objc, /* Actual parameter count. */
+ Tcl_Obj *const *objv) /* Parameter vector. */
+{
+ ClientData ptr;
+ int type;
+ mp_int big;
+
+ if (objc != 2) {
+ MathFuncWrongNumArgs(interp, 2, objc, objv);
+ return TCL_ERROR;
+ }
+
+ if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (type == TCL_NUMBER_LONG) {
+ long l = *((const long *) ptr);
+
+ if (l > (long)0) {
+ goto unChanged;
+ } else if (l == (long)0) {
+ const char *string = objv[1]->bytes;
+ if (string) {
+ while (*string != '0') {
+ if (*string == '-') {
+ Tcl_SetObjResult(interp, Tcl_NewLongObj(0));
+ return TCL_OK;
+ }
+ string++;
+ }
+ }
+ goto unChanged;
+ } else if (l == LONG_MIN) {
+ TclBNInitBignumFromLong(&big, l);
+ goto tooLarge;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewLongObj(-l));
+ return TCL_OK;
+ }
+
+ if (type == TCL_NUMBER_DOUBLE) {
+ double d = *((const double *) ptr);
+ static const double poszero = 0.0;
+
+ /* We need to distinguish here between positive 0.0 and
+ * negative -0.0, see Bug ID #2954959.
+ */
+ if (d == -0.0) {
+ if (!memcmp(&d, &poszero, sizeof(double))) {
+ goto unChanged;
+ }
+ } else {
+ if (d > -0.0) {
+ goto unChanged;
+ }
+ }
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(-d));
+ return TCL_OK;
+ }
+
+#ifndef NO_WIDE_TYPE
+ if (type == TCL_NUMBER_WIDE) {
+ Tcl_WideInt w = *((const Tcl_WideInt *) ptr);
+
+ if (w >= (Tcl_WideInt)0) {
+ goto unChanged;
+ }
+ if (w == LLONG_MIN) {
+ TclBNInitBignumFromWideInt(&big, w);
+ goto tooLarge;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewWideIntObj(-w));
+ return TCL_OK;
+ }
+#endif
+
+ if (type == TCL_NUMBER_BIG) {
+ /* TODO: const correctness ? */
+ if (mp_cmp_d((mp_int *) ptr, 0) == MP_LT) {
+ Tcl_GetBignumFromObj(NULL, objv[1], &big);
+ tooLarge:
+ mp_neg(&big, &big);
+ Tcl_SetObjResult(interp, Tcl_NewBignumObj(&big));
+ } else {
+ unChanged:
+ Tcl_SetObjResult(interp, objv[1]);
+ }
+ return TCL_OK;
+ }
+
+ if (type == TCL_NUMBER_NAN) {
+#ifdef ACCEPT_NAN
+ Tcl_SetObjResult(interp, objv[1]);
+ return TCL_OK;
+#else
+ double d;
+ Tcl_GetDoubleFromObj(interp, objv[1], &d);
+ return TCL_ERROR;
+#endif
+ }
+ return TCL_OK;
+}
+
+static int
+ExprBoolFunc(
+ ClientData clientData, /* Ignored. */
+ Tcl_Interp *interp, /* The interpreter in which to execute the
+ * function. */
+ int objc, /* Actual parameter count. */
+ Tcl_Obj *const *objv) /* Actual parameter vector. */
+{
+ int value;
+
+ if (objc != 2) {
+ MathFuncWrongNumArgs(interp, 2, objc, objv);
+ return TCL_ERROR;
+ }
+ if (Tcl_GetBooleanFromObj(interp, objv[1], &value) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(value));
+ return TCL_OK;
+}
+
+static int
+ExprDoubleFunc(
+ ClientData clientData, /* Ignored. */
+ Tcl_Interp *interp, /* The interpreter in which to execute the
+ * function. */
+ int objc, /* Actual parameter count. */
+ Tcl_Obj *const *objv) /* Actual parameter vector. */
+{
+ double dResult;
+ if (objc != 2) {
+ MathFuncWrongNumArgs(interp, 2, objc, objv);
+ return TCL_ERROR;
+ }
+ if (Tcl_GetDoubleFromObj(interp, objv[1], &dResult) != TCL_OK) {
+#ifdef ACCEPT_NAN
+ if (objv[1]->typePtr == &tclDoubleType) {
+ Tcl_SetObjResult(interp, objv[1]);
+ return TCL_OK;
+ }
+#endif
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(dResult));
+ return TCL_OK;
+}
+
+static int
+ExprEntierFunc(
+ ClientData clientData, /* Ignored. */
+ Tcl_Interp *interp, /* The interpreter in which to execute the
+ * function. */
+ int objc, /* Actual parameter count. */
+ Tcl_Obj *const *objv) /* Actual parameter vector. */
+{
+ double d;
+ int type;
+ ClientData ptr;
+
+ if (objc != 2) {
+ MathFuncWrongNumArgs(interp, 2, objc, objv);
+ return TCL_ERROR;
+ }
+ if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (type == TCL_NUMBER_DOUBLE) {
+ d = *((const double *) ptr);
+ if ((d >= (double)LONG_MAX) || (d <= (double)LONG_MIN)) {
+ mp_int big;
+
+ if (Tcl_InitBignumFromDouble(interp, d, &big) != TCL_OK) {
+ /* Infinity */
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewBignumObj(&big));
+ return TCL_OK;
+ } else {
+ long result = (long) d;
+
+ Tcl_SetObjResult(interp, Tcl_NewLongObj(result));
+ return TCL_OK;
+ }
+ }
+
+ if (type != TCL_NUMBER_NAN) {
+ /*
+ * All integers are already of integer type.
+ */
+
+ Tcl_SetObjResult(interp, objv[1]);
+ return TCL_OK;
+ }
+
+ /*
+ * Get the error message for NaN.
+ */
+
+ Tcl_GetDoubleFromObj(interp, objv[1], &d);
+ return TCL_ERROR;
+}
+
+static int
+ExprIntFunc(
+ ClientData clientData, /* Ignored. */
+ Tcl_Interp *interp, /* The interpreter in which to execute the
+ * function. */
+ int objc, /* Actual parameter count. */
+ Tcl_Obj *const *objv) /* Actual parameter vector. */
+{
+ long iResult;
+ Tcl_Obj *objPtr;
+ if (ExprEntierFunc(NULL, interp, objc, objv) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ objPtr = Tcl_GetObjResult(interp);
+ if (TclGetLongFromObj(NULL, objPtr, &iResult) != TCL_OK) {
+ /*
+ * Truncate the bignum; keep only bits in long range.
+ */
+
+ mp_int big;
+
+ Tcl_GetBignumFromObj(NULL, objPtr, &big);
+ mp_mod_2d(&big, (int) CHAR_BIT * sizeof(long), &big);
+ objPtr = Tcl_NewBignumObj(&big);
+ Tcl_IncrRefCount(objPtr);
+ TclGetLongFromObj(NULL, objPtr, &iResult);
+ Tcl_DecrRefCount(objPtr);
+ }
+ Tcl_SetObjResult(interp, Tcl_NewLongObj(iResult));
+ return TCL_OK;
+}
+
+static int
+ExprWideFunc(
+ ClientData clientData, /* Ignored. */
+ Tcl_Interp *interp, /* The interpreter in which to execute the
+ * function. */
+ int objc, /* Actual parameter count. */
+ Tcl_Obj *const *objv) /* Actual parameter vector. */
+{
+ Tcl_WideInt wResult;
+ Tcl_Obj *objPtr;
+ if (ExprEntierFunc(NULL, interp, objc, objv) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ objPtr = Tcl_GetObjResult(interp);
+ if (Tcl_GetWideIntFromObj(NULL, objPtr, &wResult) != TCL_OK) {
+ /*
+ * Truncate the bignum; keep only bits in wide int range.
+ */
+
+ mp_int big;
+
+ Tcl_GetBignumFromObj(NULL, objPtr, &big);
+ mp_mod_2d(&big, (int) CHAR_BIT * sizeof(Tcl_WideInt), &big);
+ objPtr = Tcl_NewBignumObj(&big);
+ Tcl_IncrRefCount(objPtr);
+ Tcl_GetWideIntFromObj(NULL, objPtr, &wResult);
+ Tcl_DecrRefCount(objPtr);
+ }
+ Tcl_SetObjResult(interp, Tcl_NewWideIntObj(wResult));
+ return TCL_OK;
+}
+
+static int
+ExprRandFunc(
+ ClientData clientData, /* Ignored. */
+ Tcl_Interp *interp, /* The interpreter in which to execute the
+ * function. */
+ int objc, /* Actual parameter count. */
+ Tcl_Obj *const *objv) /* Actual parameter vector. */
+{
+ Interp *iPtr = (Interp *) interp;
+ double dResult;
+ long tmp; /* Algorithm assumes at least 32 bits. Only
+ * long guarantees that. See below. */
+ Tcl_Obj *oResult;
+
+ if (objc != 1) {
+ MathFuncWrongNumArgs(interp, 1, objc, objv);
+ return TCL_ERROR;
+ }
+
+ if (!(iPtr->flags & RAND_SEED_INITIALIZED)) {
+ iPtr->flags |= RAND_SEED_INITIALIZED;
+
+ /*
+ * Take into consideration the thread this interp is running in order
+ * to insure different seeds in different threads (bug #416643)
+ */
+
+ iPtr->randSeed = TclpGetClicks() + (PTR2INT(Tcl_GetCurrentThread())<<12);
+
+ /*
+ * Make sure 1 <= randSeed <= (2^31) - 2. See below.
+ */
+
+ iPtr->randSeed &= (unsigned long) 0x7fffffff;
+ if ((iPtr->randSeed == 0) || (iPtr->randSeed == 0x7fffffff)) {
+ iPtr->randSeed ^= 123459876;
+ }
+ }
+
+ /*
+ * Generate the random number using the linear congruential generator
+ * defined by the following recurrence:
+ * seed = ( IA * seed ) mod IM
+ * where IA is 16807 and IM is (2^31) - 1. The recurrence maps a seed in
+ * the range [1, IM - 1] to a new seed in that same range. The recurrence
+ * maps IM to 0, and maps 0 back to 0, so those two values must not be
+ * allowed as initial values of seed.
+ *
+ * In order to avoid potential problems with integer overflow, the
+ * recurrence is implemented in terms of additional constants IQ and IR
+ * such that
+ * IM = IA*IQ + IR
+ * None of the operations in the implementation overflows a 32-bit signed
+ * integer, and the C type long is guaranteed to be at least 32 bits wide.
+ *
+ * For more details on how this algorithm works, refer to the following
+ * papers:
+ *
+ * S.K. Park & K.W. Miller, "Random number generators: good ones are hard
+ * to find," Comm ACM 31(10):1192-1201, Oct 1988
+ *
+ * W.H. Press & S.A. Teukolsky, "Portable random number generators,"
+ * Computers in Physics 6(5):522-524, Sep/Oct 1992.
+ */
+
+#define RAND_IA 16807
+#define RAND_IM 2147483647
+#define RAND_IQ 127773
+#define RAND_IR 2836
+#define RAND_MASK 123459876
+
+ tmp = iPtr->randSeed/RAND_IQ;
+ iPtr->randSeed = RAND_IA*(iPtr->randSeed - tmp*RAND_IQ) - RAND_IR*tmp;
+ if (iPtr->randSeed < 0) {
+ iPtr->randSeed += RAND_IM;
+ }
+
+ /*
+ * Since the recurrence keeps seed values in the range [1, RAND_IM - 1],
+ * dividing by RAND_IM yields a double in the range (0, 1).
+ */
+
+ dResult = iPtr->randSeed * (1.0/RAND_IM);
+
+ /*
+ * Push a Tcl object with the result.
+ */
+
+ TclNewDoubleObj(oResult, dResult);
+ Tcl_SetObjResult(interp, oResult);
+ return TCL_OK;
+}
+
+static int
+ExprRoundFunc(
+ ClientData clientData, /* Ignored. */
+ Tcl_Interp *interp, /* The interpreter in which to execute the
+ * function. */
+ int objc, /* Actual parameter count. */
+ Tcl_Obj *const *objv) /* Parameter vector. */
+{
+ double d;
+ ClientData ptr;
+ int type;
+
+ if (objc != 2) {
+ MathFuncWrongNumArgs(interp, 2, objc, objv);
+ return TCL_ERROR;
+ }
+
+ if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (type == TCL_NUMBER_DOUBLE) {
+ double fractPart, intPart;
+ long max = LONG_MAX, min = LONG_MIN;
+
+ fractPart = modf(*((const double *) ptr), &intPart);
+ if (fractPart <= -0.5) {
+ min++;
+ } else if (fractPart >= 0.5) {
+ max--;
+ }
+ if ((intPart >= (double)max) || (intPart <= (double)min)) {
+ mp_int big;
+
+ if (Tcl_InitBignumFromDouble(interp, intPart, &big) != TCL_OK) {
+ /* Infinity */
+ return TCL_ERROR;
+ }
+ if (fractPart <= -0.5) {
+ mp_sub_d(&big, 1, &big);
+ } else if (fractPart >= 0.5) {
+ mp_add_d(&big, 1, &big);
+ }
+ Tcl_SetObjResult(interp, Tcl_NewBignumObj(&big));
+ return TCL_OK;
+ } else {
+ long result = (long)intPart;
+
+ if (fractPart <= -0.5) {
+ result--;
+ } else if (fractPart >= 0.5) {
+ result++;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewLongObj(result));
+ return TCL_OK;
+ }
+ }
+
+ if (type != TCL_NUMBER_NAN) {
+ /*
+ * All integers are already rounded
+ */
+
+ Tcl_SetObjResult(interp, objv[1]);
+ return TCL_OK;
+ }
+
+ /*
+ * Get the error message for NaN.
+ */
+
+ Tcl_GetDoubleFromObj(interp, objv[1], &d);
+ return TCL_ERROR;
+}
+
+static int
+ExprSrandFunc(
+ ClientData clientData, /* Ignored. */
+ Tcl_Interp *interp, /* The interpreter in which to execute the
+ * function. */
+ int objc, /* Actual parameter count. */
+ Tcl_Obj *const *objv) /* Parameter vector. */
+{
+ Interp *iPtr = (Interp *) interp;
+ long i = 0; /* Initialized to avoid compiler warning. */
+
+ /*
+ * Convert argument and use it to reset the seed.
+ */
+
+ if (objc != 2) {
+ MathFuncWrongNumArgs(interp, 2, objc, objv);
+ return TCL_ERROR;
+ }
+
+ if (TclGetLongFromObj(NULL, objv[1], &i) != TCL_OK) {
+ Tcl_Obj *objPtr;
+ mp_int big;
+
+ if (Tcl_GetBignumFromObj(interp, objv[1], &big) != TCL_OK) {
+ /* TODO: more ::errorInfo here? or in caller? */
+ return TCL_ERROR;
+ }
+
+ mp_mod_2d(&big, (int) CHAR_BIT * sizeof(long), &big);
+ objPtr = Tcl_NewBignumObj(&big);
+ Tcl_IncrRefCount(objPtr);
+ TclGetLongFromObj(NULL, objPtr, &i);
+ Tcl_DecrRefCount(objPtr);
+ }
+
+ /*
+ * Reset the seed. Make sure 1 <= randSeed <= 2^31 - 2. See comments in
+ * ExprRandFunc() for more details.
+ */
+
+ iPtr->flags |= RAND_SEED_INITIALIZED;
+ iPtr->randSeed = i;
+ iPtr->randSeed &= (unsigned long) 0x7fffffff;
+ if ((iPtr->randSeed == 0) || (iPtr->randSeed == 0x7fffffff)) {
+ iPtr->randSeed ^= 123459876;
+ }
+
+ /*
+ * To avoid duplicating the random number generation code we simply clean
+ * up our state and call the real random number function. That function
+ * will always succeed.
+ */
+
+ return ExprRandFunc(clientData, interp, 1, objv);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * MathFuncWrongNumArgs --
+ *
+ * Generate an error message when a math function presents the wrong
+ * number of arguments.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * An error message is stored in the interpreter result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+MathFuncWrongNumArgs(
+ Tcl_Interp *interp, /* Tcl interpreter */
+ int expected, /* Formal parameter count. */
+ int found, /* Actual parameter count. */
+ Tcl_Obj *const *objv) /* Actual parameter vector. */
+{
+ const char *name = Tcl_GetString(objv[0]);
+ const char *tail = name + strlen(name);
+
+ while (tail > name+1) {
+ --tail;
+ if (*tail == ':' && tail[-1] == ':') {
+ name = tail+1;
+ break;
+ }
+ }
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "too %s arguments for math function \"%s\"",
+ (found < expected ? "few" : "many"), name));
}
#ifdef USE_DTRACE
@@ -6771,7 +7009,7 @@ DTraceObjCmd(
ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
- Tcl_Obj *CONST objv[]) /* Argument objects. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
if (TCL_DTRACE_TCL_PROBE_ENABLED()) {
char *a[10];
@@ -6785,6 +7023,60 @@ DTraceObjCmd(
}
return TCL_OK;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclDTraceInfo --
+ *
+ * Extract information from a TIP280 dict for use by DTrace probes.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclDTraceInfo(
+ Tcl_Obj *info,
+ char **args,
+ int *argsi)
+{
+ static Tcl_Obj *keys[7] = { NULL };
+ Tcl_Obj **k = keys, *val;
+ int i;
+
+ if (!*k) {
+ TclNewLiteralStringObj(keys[0], "cmd");
+ TclNewLiteralStringObj(keys[1], "type");
+ TclNewLiteralStringObj(keys[2], "proc");
+ TclNewLiteralStringObj(keys[3], "file");
+ TclNewLiteralStringObj(keys[4], "lambda");
+ TclNewLiteralStringObj(keys[5], "line");
+ TclNewLiteralStringObj(keys[6], "level");
+ }
+ for (i = 0; i < 4; i++) {
+ Tcl_DictObjGet(NULL, info, *k++, &val);
+ args[i] = val ? TclGetString(val) : NULL;
+ }
+ if (!args[2]) {
+ Tcl_DictObjGet(NULL, info, *k, &val);
+ args[2] = val ? TclGetString(val) : NULL;
+ }
+ k++;
+ for (i = 0; i < 2; i++) {
+ Tcl_DictObjGet(NULL, info, *k++, &val);
+ if (val) {
+ TclGetIntFromObj(NULL, val, &(argsi[i]));
+ } else {
+ argsi[i] = 0;
+ }
+ }
+}
TCL_DTRACE_DEBUG_LOG()
diff --git a/generic/tclBinary.c b/generic/tclBinary.c
index 8d258b3..f321b28 100644
--- a/generic/tclBinary.c
+++ b/generic/tclBinary.c
@@ -1,4 +1,4 @@
-/*
+/*
* tclBinary.c --
*
* This file contains the implementation of the "binary" Tcl built-in
@@ -7,12 +7,13 @@
* Copyright (c) 1997 by 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.
*/
#include "tclInt.h"
-#include "tclPort.h"
+#include "tommath.h"
+
#include <math.h>
/*
@@ -24,21 +25,27 @@
#define BINARY_NOCOUNT -2 /* No count was specified in format. */
/*
- * The following defines the maximum number of different (integer)
- * numbers placed in the object cache by 'binary scan' before it bails
- * out and switches back to Plan A (creating a new object for each
- * value.) Theoretically, it would be possible to keep the cache
- * about for the values that are already in it, but that makes the
- * code slower in practise when overflow happens, and makes little
- * odds the rest of the time (as measured on my machine.) It is also
- * slower (on the sample I tried at least) to grow the cache to hold
- * all items we might want to put in it; presumably the extra cost of
- * managing the memory for the enlarged table outweighs the benefit
- * from allocating fewer objects. This is probably because as the
- * number of objects increases, the likelihood of reuse of any
- * particular one drops, and there is very little gain from larger
- * maximum cache sizes (the value below is chosen to allow caching to
- * work in full with conversion of bytes.) - DKF
+ * The following flags may be ORed together and returned by GetFormatSpec
+ */
+
+#define BINARY_SIGNED 0 /* Field to be read as signed data */
+#define BINARY_UNSIGNED 1 /* Field to be read as unsigned data */
+
+/*
+ * The following defines the maximum number of different (integer) numbers
+ * placed in the object cache by 'binary scan' before it bails out and
+ * switches back to Plan A (creating a new object for each value.)
+ * Theoretically, it would be possible to keep the cache about for the values
+ * that are already in it, but that makes the code slower in practise when
+ * overflow happens, and makes little odds the rest of the time (as measured
+ * on my machine.) It is also slower (on the sample I tried at least) to grow
+ * the cache to hold all items we might want to put in it; presumably the
+ * extra cost of managing the memory for the enlarged table outweighs the
+ * benefit from allocating fewer objects. This is probably because as the
+ * number of objects increases, the likelihood of reuse of any particular one
+ * drops, and there is very little gain from larger maximum cache sizes (the
+ * value below is chosen to allow caching to work in full with conversion of
+ * bytes.) - DKF
*/
#define BINARY_SCAN_MAX_CACHE 260
@@ -47,46 +54,46 @@
* Prototypes for local procedures defined in this file:
*/
-static void DupByteArrayInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr,
- Tcl_Obj *copyPtr));
-static int FormatNumber _ANSI_ARGS_((Tcl_Interp *interp, int type,
- Tcl_Obj *src, unsigned char **cursorPtr));
-static void CopyNumber _ANSI_ARGS_((CONST VOID *from, VOID *to,
- unsigned int length));
-static void FreeByteArrayInternalRep _ANSI_ARGS_((Tcl_Obj *objPtr));
-static int GetFormatSpec _ANSI_ARGS_((char **formatPtr,
- char *cmdPtr, int *countPtr));
-static Tcl_Obj * ScanNumber _ANSI_ARGS_((unsigned char *buffer,
- int type, Tcl_HashTable **numberCachePtr));
-static int SetByteArrayFromAny _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_Obj *objPtr));
-static void UpdateStringOfByteArray _ANSI_ARGS_((Tcl_Obj *listPtr));
-static void DeleteScanNumberCache _ANSI_ARGS_((
- Tcl_HashTable *numberCachePtr));
+static void DupByteArrayInternalRep(Tcl_Obj *srcPtr,
+ Tcl_Obj *copyPtr);
+static int FormatNumber(Tcl_Interp *interp, int type,
+ Tcl_Obj *src, unsigned char **cursorPtr);
+static void FreeByteArrayInternalRep(Tcl_Obj *objPtr);
+static int GetFormatSpec(char **formatPtr, char *cmdPtr,
+ int *countPtr, int *flagsPtr);
+static Tcl_Obj * ScanNumber(unsigned char *buffer, int type,
+ int flags, Tcl_HashTable **numberCachePtr);
+static int SetByteArrayFromAny(Tcl_Interp *interp,
+ Tcl_Obj *objPtr);
+static void UpdateStringOfByteArray(Tcl_Obj *listPtr);
+static void DeleteScanNumberCache(Tcl_HashTable *numberCachePtr);
+static int NeedReversing(int format);
+static void CopyNumber(const void *from, void *to,
+ unsigned int length, int type);
/*
- * 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 UTF-8 characters, while a ByteArray is an array of 8-bit quantities.
+ * 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
+ * UTF-8 characters, while a ByteArray is an array of 8-bit quantities.
* Accessor functions are provided to convert a ByteArray to a String or a
- * String to a ByteArray. Two or more consecutive bytes in an array of bytes
+ * String to a ByteArray. Two or more consecutive bytes in an array of bytes
* may look like a single UTF-8 character if the array is casually treated as
- * a string. But obtaining the String from a ByteArray is guaranteed to
- * produced properly formed UTF-8 sequences so that there is a one-to-one
- * map between bytes and characters.
+ * a string. But obtaining the String from a ByteArray is guaranteed to
+ * produced properly formed UTF-8 sequences so that there is a one-to-one map
+ * between bytes and characters.
*
* Converting a ByteArray to a String proceeds by casting each byte in the
* array to a 16-bit quantity, treating that number as a Unicode character,
- * and storing the UTF-8 version of that Unicode character in the String.
- * For ByteArrays consisting entirely of values 1..127, the corresponding
- * String representation is the same as the ByteArray representation.
+ * and storing the UTF-8 version of that Unicode character in the String. For
+ * ByteArrays consisting entirely of values 1..127, the corresponding String
+ * representation is the same as the ByteArray representation.
*
* Converting a String to a ByteArray proceeds by getting the Unicode
- * representation of each character in the String, casting it to a
- * byte by truncating the upper 8 bits, and then storing the byte in the
- * ByteArray. Converting from ByteArray to String and back to ByteArray
- * is not lossy, but converting an arbitrary String to a ByteArray may be.
+ * representation of each character in the String, casting it to a byte by
+ * truncating the upper 8 bits, and then storing the byte in the ByteArray.
+ * Converting from ByteArray to String and back to ByteArray is not lossy, but
+ * converting an arbitrary String to a ByteArray may be.
*/
Tcl_ObjType tclByteArrayType = {
@@ -98,10 +105,10 @@ Tcl_ObjType tclByteArrayType = {
};
/*
- * The following structure is the internal rep for a ByteArray object.
- * Keeps track of how much memory has been used and how much has been
- * allocated for the byte array to enable growing and shrinking of the
- * ByteArray object with fewer mallocs.
+ * The following structure is the internal rep for a ByteArray object. Keeps
+ * track of how much memory has been used and how much has been allocated for
+ * the byte array to enable growing and shrinking of the ByteArray object with
+ * fewer mallocs.
*/
typedef struct ByteArray {
@@ -109,12 +116,12 @@ typedef struct ByteArray {
* array. */
int allocated; /* The amount of space actually allocated
* minus 1 byte. */
- unsigned char bytes[4]; /* The array of bytes. The actual size of
- * this field depends on the 'allocated' field
+ unsigned char bytes[4]; /* The array of bytes. The actual size of this
+ * field depends on the 'allocated' field
* above. */
} ByteArray;
-#define BYTEARRAY_SIZE(len) \
+#define BYTEARRAY_SIZE(len) \
((unsigned) (sizeof(ByteArray) - 4 + (len)))
#define GET_BYTEARRAY(objPtr) \
((ByteArray *) (objPtr)->internalRep.otherValuePtr)
@@ -123,34 +130,32 @@ typedef struct ByteArray {
/*
- *---------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* Tcl_NewByteArrayObj --
*
- * This procedure is creates a new ByteArray object and initializes
- * it from the given array of bytes.
+ * This procedure is creates a new ByteArray object and initializes it
+ * from the given array of bytes.
*
* Results:
- * The newly create object is returned. This object will have no
- * initial string representation. The returned object has a ref count
- * of 0.
+ * The newly create object is returned. This object will have no initial
+ * string representation. The returned object has a ref count of 0.
*
* Side effects:
* Memory allocated for new object and copy of byte array argument.
*
- *---------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
#ifdef TCL_MEM_DEBUG
#undef Tcl_NewByteArrayObj
-
Tcl_Obj *
-Tcl_NewByteArrayObj(bytes, length)
- CONST unsigned char *bytes; /* The array of bytes used to initialize
- * the new object. */
- int length; /* Length of the array of bytes, which must
- * be >= 0. */
+Tcl_NewByteArrayObj(
+ const unsigned char *bytes, /* The array of bytes used to initialize the
+ * new object. */
+ int length) /* Length of the array of bytes, which must be
+ * >= 0. */
{
return Tcl_DbNewByteArrayObj(bytes, length, "unknown", 0);
}
@@ -158,11 +163,11 @@ Tcl_NewByteArrayObj(bytes, length)
#else /* if not TCL_MEM_DEBUG */
Tcl_Obj *
-Tcl_NewByteArrayObj(bytes, length)
- CONST unsigned char *bytes; /* The array of bytes used to initialize
- * the new object. */
- int length; /* Length of the array of bytes, which must
- * be >= 0. */
+Tcl_NewByteArrayObj(
+ const unsigned char *bytes, /* The array of bytes used to initialize the
+ * new object. */
+ int length) /* Length of the array of bytes, which must be
+ * >= 0. */
{
Tcl_Obj *objPtr;
@@ -173,7 +178,7 @@ Tcl_NewByteArrayObj(bytes, length)
#endif /* TCL_MEM_DEBUG */
/*
- *---------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* Tcl_DbNewByteArrayObj --
*
@@ -188,28 +193,27 @@ Tcl_NewByteArrayObj(bytes, length)
* result of calling Tcl_NewByteArrayObj.
*
* Results:
- * The newly create object is returned. This object will have no
- * initial string representation. The returned object has a ref count
- * of 0.
+ * The newly create object is returned. This object will have no initial
+ * string representation. The returned object has a ref count of 0.
*
* Side effects:
* Memory allocated for new object and copy of byte array argument.
*
- *---------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
#ifdef TCL_MEM_DEBUG
Tcl_Obj *
-Tcl_DbNewByteArrayObj(bytes, length, file, line)
- CONST unsigned char *bytes; /* The array of bytes used to initialize
- * the new object. */
- int length; /* Length of the array of bytes, which must
- * be >= 0. */
- CONST char *file; /* The name of the source file calling this
+Tcl_DbNewByteArrayObj(
+ const unsigned char *bytes, /* The array of bytes used to initialize the
+ * new object. */
+ int length, /* Length of the array of bytes, which must be
+ * >= 0. */
+ const char *file, /* The name of the source file calling this
* procedure; used for debugging. */
- int line; /* Line number in the source file; used
- * for debugging. */
+ int line) /* Line number in the source file; used for
+ * debugging. */
{
Tcl_Obj *objPtr;
@@ -221,15 +225,15 @@ Tcl_DbNewByteArrayObj(bytes, length, file, line)
#else /* if not TCL_MEM_DEBUG */
Tcl_Obj *
-Tcl_DbNewByteArrayObj(bytes, length, file, line)
- CONST unsigned char *bytes; /* The array of bytes used to initialize
- * the new object. */
- int length; /* Length of the array of bytes, which must
- * be >= 0. */
- CONST char *file; /* The name of the source file calling this
+Tcl_DbNewByteArrayObj(
+ const unsigned char *bytes, /* The array of bytes used to initialize the
+ * new object. */
+ int length, /* Length of the array of bytes, which must be
+ * >= 0. */
+ const char *file, /* The name of the source file calling this
* procedure; used for debugging. */
- int line; /* Line number in the source file; used
- * for debugging. */
+ int line) /* Line number in the source file; used for
+ * debugging. */
{
return Tcl_NewByteArrayObj(bytes, length);
}
@@ -247,36 +251,32 @@ Tcl_DbNewByteArrayObj(bytes, length, file, line)
* None.
*
* Side effects:
- * The object's old string rep and internal rep is freed.
- * Memory allocated for copy of byte array argument.
+ * The object's old string rep and internal rep is freed. Memory
+ * allocated for copy of byte array argument.
*
*----------------------------------------------------------------------
*/
void
-Tcl_SetByteArrayObj(objPtr, bytes, length)
- Tcl_Obj *objPtr; /* Object to initialize as a ByteArray. */
- CONST unsigned char *bytes; /* The array of bytes to use as the new
+Tcl_SetByteArrayObj(
+ Tcl_Obj *objPtr, /* Object to initialize as a ByteArray. */
+ const unsigned char *bytes, /* The array of bytes to use as the new
* value. */
- int length; /* Length of the array of bytes, which must
- * be >= 0. */
+ int length) /* Length of the array of bytes, which must be
+ * >= 0. */
{
- Tcl_ObjType *typePtr;
ByteArray *byteArrayPtr;
if (Tcl_IsShared(objPtr)) {
- panic("Tcl_SetByteArrayObj called with shared object");
- }
- typePtr = objPtr->typePtr;
- if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
- (*typePtr->freeIntRepProc)(objPtr);
+ Tcl_Panic("%s called with shared object", "Tcl_SetByteArrayObj");
}
+ TclFreeIntRep(objPtr);
Tcl_InvalidateStringRep(objPtr);
byteArrayPtr = (ByteArray *) ckalloc(BYTEARRAY_SIZE(length));
byteArrayPtr->used = length;
byteArrayPtr->allocated = length;
- memcpy((VOID *) byteArrayPtr->bytes, (VOID *) bytes, (size_t) length);
+ memcpy(byteArrayPtr->bytes, bytes, (size_t) length);
objPtr->typePtr = &tclByteArrayType;
SET_BYTEARRAY(objPtr, byteArrayPtr);
@@ -287,28 +287,30 @@ Tcl_SetByteArrayObj(objPtr, bytes, length)
*
* Tcl_GetByteArrayFromObj --
*
- * Attempt to get the array of bytes from the Tcl object. If the
- * object is not already a ByteArray object, an attempt will be
- * made to convert it to one.
+ * Attempt to get the array of bytes from the Tcl object. If the object
+ * is not already a ByteArray object, an attempt will be made to convert
+ * it to one.
*
* Results:
* Pointer to array of bytes representing the ByteArray object.
*
* Side effects:
- * Frees old internal rep. Allocates memory for new internal rep.
+ * Frees old internal rep. Allocates memory for new internal rep.
*
*----------------------------------------------------------------------
*/
unsigned char *
-Tcl_GetByteArrayFromObj(objPtr, lengthPtr)
- Tcl_Obj *objPtr; /* The ByteArray object. */
- int *lengthPtr; /* If non-NULL, filled with length of the
+Tcl_GetByteArrayFromObj(
+ Tcl_Obj *objPtr, /* The ByteArray object. */
+ int *lengthPtr) /* If non-NULL, filled with length of the
* array of bytes in the ByteArray object. */
{
ByteArray *baPtr;
-
- SetByteArrayFromAny(NULL, objPtr);
+
+ if (objPtr->typePtr != &tclByteArrayType) {
+ SetByteArrayFromAny(NULL, objPtr);
+ }
baPtr = GET_BYTEARRAY(objPtr);
if (lengthPtr != NULL) {
@@ -322,32 +324,32 @@ Tcl_GetByteArrayFromObj(objPtr, lengthPtr)
*
* Tcl_SetByteArrayLength --
*
- * This procedure changes the length of the byte array for this
- * object. Once the caller has set the length of the array, it
- * is acceptable to directly modify the bytes in the array up until
- * Tcl_GetStringFromObj() has been called on this object.
+ * This procedure changes the length of the byte array for this object.
+ * Once the caller has set the length of the array, it is acceptable to
+ * directly modify the bytes in the array up until Tcl_GetStringFromObj()
+ * has been called on this object.
*
* Results:
* The new byte array of the specified length.
*
* Side effects:
- * Allocates enough memory for an array of bytes of the requested
- * size. When growing the array, the old array is copied to the
- * new array; new bytes are undefined. When shrinking, the
- * old array is truncated to the specified length.
+ * Allocates enough memory for an array of bytes of the requested size.
+ * When growing the array, the old array is copied to the new array; new
+ * bytes are undefined. When shrinking, the old array is truncated to the
+ * specified length.
*
- *---------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
unsigned char *
-Tcl_SetByteArrayLength(objPtr, length)
- Tcl_Obj *objPtr; /* The ByteArray object. */
- int length; /* New length for internal byte array. */
+Tcl_SetByteArrayLength(
+ Tcl_Obj *objPtr, /* The ByteArray object. */
+ int length) /* New length for internal byte array. */
{
- ByteArray *byteArrayPtr, *newByteArrayPtr;
-
+ ByteArray *byteArrayPtr;
+
if (Tcl_IsShared(objPtr)) {
- panic("Tcl_SetObjLength called with shared object");
+ Tcl_Panic("%s called with shared object", "Tcl_SetByteArrayLength");
}
if (objPtr->typePtr != &tclByteArrayType) {
SetByteArrayFromAny(NULL, objPtr);
@@ -355,13 +357,9 @@ Tcl_SetByteArrayLength(objPtr, length)
byteArrayPtr = GET_BYTEARRAY(objPtr);
if (length > byteArrayPtr->allocated) {
- newByteArrayPtr = (ByteArray *) ckalloc(BYTEARRAY_SIZE(length));
- newByteArrayPtr->used = length;
- newByteArrayPtr->allocated = length;
- memcpy((VOID *) newByteArrayPtr->bytes,
- (VOID *) byteArrayPtr->bytes, (size_t) byteArrayPtr->used);
- ckfree((char *) byteArrayPtr);
- byteArrayPtr = newByteArrayPtr;
+ byteArrayPtr = (ByteArray *) ckrealloc(
+ (char *) byteArrayPtr, BYTEARRAY_SIZE(length));
+ byteArrayPtr->allocated = length;
SET_BYTEARRAY(objPtr, byteArrayPtr);
}
Tcl_InvalidateStringRep(objPtr);
@@ -370,7 +368,7 @@ Tcl_SetByteArrayLength(objPtr, length)
}
/*
- *---------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* SetByteArrayFromAny --
*
@@ -382,24 +380,22 @@ Tcl_SetByteArrayLength(objPtr, length)
* Side effects:
* A ByteArray object is stored as the internal rep of objPtr.
*
- *---------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
static int
-SetByteArrayFromAny(interp, objPtr)
- Tcl_Interp *interp; /* Not used. */
- Tcl_Obj *objPtr; /* The object to convert to type ByteArray. */
+SetByteArrayFromAny(
+ Tcl_Interp *interp, /* Not used. */
+ Tcl_Obj *objPtr) /* The object to convert to type ByteArray. */
{
- Tcl_ObjType *typePtr;
int length;
char *src, *srcEnd;
unsigned char *dst;
ByteArray *byteArrayPtr;
Tcl_UniChar ch;
-
- typePtr = objPtr->typePtr;
- if (typePtr != &tclByteArrayType) {
- src = Tcl_GetStringFromObj(objPtr, &length);
+
+ if (objPtr->typePtr != &tclByteArrayType) {
+ src = TclGetStringFromObj(objPtr, &length);
srcEnd = src + length;
byteArrayPtr = (ByteArray *) ckalloc(BYTEARRAY_SIZE(length));
@@ -411,9 +407,7 @@ SetByteArrayFromAny(interp, objPtr)
byteArrayPtr->used = dst - byteArrayPtr->bytes;
byteArrayPtr->allocated = length;
- if ((typePtr != NULL) && (typePtr->freeIntRepProc) != NULL) {
- (*typePtr->freeIntRepProc)(objPtr);
- }
+ TclFreeIntRep(objPtr);
objPtr->typePtr = &tclByteArrayType;
SET_BYTEARRAY(objPtr, byteArrayPtr);
}
@@ -432,26 +426,26 @@ SetByteArrayFromAny(interp, objPtr)
* None.
*
* Side effects:
- * Frees memory.
+ * Frees memory.
*
*----------------------------------------------------------------------
*/
static void
-FreeByteArrayInternalRep(objPtr)
- Tcl_Obj *objPtr; /* Object with internal rep to free. */
+FreeByteArrayInternalRep(
+ Tcl_Obj *objPtr) /* Object with internal rep to free. */
{
ckfree((char *) GET_BYTEARRAY(objPtr));
+ objPtr->typePtr = NULL;
}
/*
- *---------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* DupByteArrayInternalRep --
*
- * Initialize the internal representation of a ByteArray Tcl_Obj
- * to a copy of the internal representation of an existing ByteArray
- * object.
+ * Initialize the internal representation of a ByteArray Tcl_Obj to a
+ * copy of the internal representation of an existing ByteArray object.
*
* Results:
* None.
@@ -459,16 +453,16 @@ FreeByteArrayInternalRep(objPtr)
* Side effects:
* Allocates memory.
*
- *---------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
static void
-DupByteArrayInternalRep(srcPtr, copyPtr)
- Tcl_Obj *srcPtr; /* Object with internal rep to copy. */
- Tcl_Obj *copyPtr; /* Object with internal rep to set. */
+DupByteArrayInternalRep(
+ Tcl_Obj *srcPtr, /* Object with internal rep to copy. */
+ Tcl_Obj *copyPtr) /* Object with internal rep to set. */
{
int length;
- ByteArray *srcArrayPtr, *copyArrayPtr;
+ ByteArray *srcArrayPtr, *copyArrayPtr;
srcArrayPtr = GET_BYTEARRAY(srcPtr);
length = srcArrayPtr->used;
@@ -476,38 +470,37 @@ DupByteArrayInternalRep(srcPtr, copyPtr)
copyArrayPtr = (ByteArray *) ckalloc(BYTEARRAY_SIZE(length));
copyArrayPtr->used = length;
copyArrayPtr->allocated = length;
- memcpy((VOID *) copyArrayPtr->bytes, (VOID *) srcArrayPtr->bytes,
- (size_t) length);
+ memcpy(copyArrayPtr->bytes, srcArrayPtr->bytes, (size_t) length);
SET_BYTEARRAY(copyPtr, copyArrayPtr);
copyPtr->typePtr = &tclByteArrayType;
}
/*
- *---------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*
* UpdateStringOfByteArray --
*
- * Update the string representation for a ByteArray data object.
- * Note: This procedure does not invalidate an existing old string rep
- * so storage will be lost if this has not already been done.
+ * Update the string representation for a ByteArray data object. Note:
+ * This procedure does not invalidate an existing old string rep so
+ * storage will be lost if this has not already been done.
*
* Results:
* None.
*
* Side effects:
- * The object's string is set to a valid string that results from
- * the ByteArray-to-string conversion.
+ * The object's string is set to a valid string that results from the
+ * ByteArray-to-string conversion.
*
- * The object becomes a string object -- the internal rep is
- * discarded and the typePtr becomes NULL.
+ * The object becomes a string object -- the internal rep is discarded
+ * and the typePtr becomes NULL.
*
- *---------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
static void
-UpdateStringOfByteArray(objPtr)
- Tcl_Obj *objPtr; /* ByteArray object whose string rep to
+UpdateStringOfByteArray(
+ Tcl_Obj *objPtr) /* ByteArray object whose string rep to
* update. */
{
int i, length, size;
@@ -522,20 +515,23 @@ UpdateStringOfByteArray(objPtr)
/*
* How much space will string rep need?
*/
-
+
size = length;
- for (i = 0; i < length; i++) {
+ for (i = 0; i < length && size >= 0; i++) {
if ((src[i] == 0) || (src[i] > 127)) {
size++;
}
}
+ if (size < 0) {
+ Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
+ }
dst = (char *) ckalloc((unsigned) (size + 1));
objPtr->bytes = dst;
objPtr->length = size;
if (size == length) {
- memcpy((VOID *) dst, (VOID *) src, (size_t) size);
+ memcpy(dst, src, (size_t) size);
dst[size] = '\0';
} else {
for (i = 0; i < length; i++) {
@@ -562,11 +558,11 @@ UpdateStringOfByteArray(objPtr)
*/
int
-Tcl_BinaryObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_BinaryObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
int arg; /* Index of next argument to consume. */
int value = 0; /* Current integer value to be packed.
@@ -574,19 +570,21 @@ Tcl_BinaryObjCmd(dummy, interp, objc, objv)
char cmd; /* Current format character. */
int count; /* Count associated with current format
* character. */
+ int flags; /* Format field flags */
char *format; /* Pointer to current position in format
* string. */
- Tcl_Obj *resultPtr; /* Object holding result buffer. */
+ Tcl_Obj *resultPtr = NULL; /* Object holding result buffer. */
unsigned char *buffer; /* Start of result buffer. */
unsigned char *cursor; /* Current position within result buffer. */
unsigned char *maxPos; /* Greatest position within result buffer that
* cursor has visited.*/
- char *errorString, *errorValue, *str;
+ const char *errorString;
+ char *errorValue, *str;
int offset, size, length, index;
- static CONST char *options[] = {
- "format", "scan", NULL
+ static const char *options[] = {
+ "format", "scan", NULL
};
- enum options {
+ enum options {
BINARY_FORMAT, BINARY_SCAN
};
@@ -601,760 +599,765 @@ Tcl_BinaryObjCmd(dummy, interp, objc, objv)
}
switch ((enum options) index) {
- case BINARY_FORMAT: {
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "formatString ?arg arg ...?");
- return TCL_ERROR;
- }
+ case BINARY_FORMAT:
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "formatString ?arg arg ...?");
+ return TCL_ERROR;
+ }
- /*
- * To avoid copying the data, we format the string in two passes.
- * The first pass computes the size of the output buffer. The
- * second pass places the formatted data into the buffer.
- */
+ /*
+ * To avoid copying the data, we format the string in two passes. The
+ * first pass computes the size of the output buffer. The second pass
+ * places the formatted data into the buffer.
+ */
- format = Tcl_GetString(objv[2]);
- arg = 3;
- offset = 0;
- length = 0;
- while (*format != '\0') {
- str = format;
- if (!GetFormatSpec(&format, &cmd, &count)) {
- break;
+ format = TclGetString(objv[2]);
+ arg = 3;
+ offset = 0;
+ length = 0;
+ while (*format != '\0') {
+ str = format;
+ flags = 0;
+ if (!GetFormatSpec(&format, &cmd, &count, &flags)) {
+ break;
+ }
+ switch (cmd) {
+ case 'a':
+ case 'A':
+ case 'b':
+ case 'B':
+ case 'h':
+ case 'H':
+ /*
+ * For string-type specifiers, the count corresponds to the
+ * number of bytes in a single argument.
+ */
+
+ if (arg >= objc) {
+ goto badIndex;
+ }
+ if (count == BINARY_ALL) {
+ Tcl_GetByteArrayFromObj(objv[arg], &count);
+ } else if (count == BINARY_NOCOUNT) {
+ count = 1;
+ }
+ arg++;
+ if (cmd == 'a' || cmd == 'A') {
+ offset += count;
+ } else if (cmd == 'b' || cmd == 'B') {
+ offset += (count + 7) / 8;
+ } else {
+ offset += (count + 1) / 2;
+ }
+ break;
+ case 'c':
+ size = 1;
+ goto doNumbers;
+ case 't':
+ case 's':
+ case 'S':
+ size = 2;
+ goto doNumbers;
+ case 'n':
+ case 'i':
+ case 'I':
+ size = 4;
+ goto doNumbers;
+ case 'm':
+ case 'w':
+ case 'W':
+ size = 8;
+ goto doNumbers;
+ case 'r':
+ case 'R':
+ case 'f':
+ size = sizeof(float);
+ goto doNumbers;
+ case 'q':
+ case 'Q':
+ case 'd':
+ size = sizeof(double);
+
+ doNumbers:
+ if (arg >= objc) {
+ goto badIndex;
}
- switch (cmd) {
- case 'a':
- case 'A':
- case 'b':
- case 'B':
- case 'h':
- case 'H': {
- /*
- * For string-type specifiers, the count corresponds
- * to the number of bytes in a single argument.
- */
-
- if (arg >= objc) {
- goto badIndex;
- }
- if (count == BINARY_ALL) {
- Tcl_GetByteArrayFromObj(objv[arg], &count);
- } else if (count == BINARY_NOCOUNT) {
- count = 1;
- }
- arg++;
- if (cmd == 'a' || cmd == 'A') {
- offset += count;
- } else if (cmd == 'b' || cmd == 'B') {
- offset += (count + 7) / 8;
- } else {
- offset += (count + 1) / 2;
- }
- break;
- }
- case 'c': {
- size = 1;
- goto doNumbers;
- }
- case 's':
- case 'S': {
- size = 2;
- goto doNumbers;
- }
- case 'i':
- case 'I': {
- size = 4;
- goto doNumbers;
- }
- case 'w':
- case 'W': {
- size = 8;
- goto doNumbers;
- }
- case 'f': {
- size = sizeof(float);
- goto doNumbers;
- }
- case 'd': {
- size = sizeof(double);
-
- doNumbers:
- if (arg >= objc) {
- goto badIndex;
- }
- /*
- * For number-type specifiers, the count corresponds
- * to the number of elements in the list stored in
- * a single argument. If no count is specified, then
- * the argument is taken as a single non-list value.
- */
+ /*
+ * For number-type specifiers, the count corresponds to the
+ * number of elements in the list stored in a single argument.
+ * If no count is specified, then the argument is taken as a
+ * single non-list value.
+ */
- if (count == BINARY_NOCOUNT) {
- arg++;
- count = 1;
- } else {
- int listc;
- Tcl_Obj **listv;
- if (Tcl_ListObjGetElements(interp, objv[arg++],
- &listc, &listv) != TCL_OK) {
- return TCL_ERROR;
- }
- if (count == BINARY_ALL) {
- count = listc;
- } else if (count > listc) {
- Tcl_AppendResult(interp,
- "number of elements in list does not match count",
- (char *) NULL);
- return TCL_ERROR;
- }
- }
- offset += count*size;
- break;
- }
- case 'x': {
- if (count == BINARY_ALL) {
- Tcl_AppendResult(interp,
- "cannot use \"*\" in format string with \"x\"",
- (char *) NULL);
- return TCL_ERROR;
- } else if (count == BINARY_NOCOUNT) {
- count = 1;
- }
- offset += count;
- break;
- }
- case 'X': {
- if (count == BINARY_NOCOUNT) {
- count = 1;
- }
- if ((count > offset) || (count == BINARY_ALL)) {
- count = offset;
- }
- if (offset > length) {
- length = offset;
- }
- offset -= count;
- break;
- }
- case '@': {
- if (offset > length) {
- length = offset;
- }
- if (count == BINARY_ALL) {
- offset = length;
- } else if (count == BINARY_NOCOUNT) {
- goto badCount;
- } else {
- offset = count;
- }
- break;
+ if (count == BINARY_NOCOUNT) {
+ arg++;
+ count = 1;
+ } else {
+ int listc;
+ Tcl_Obj **listv;
+
+ /* The macro evals its args more than once: avoid arg++ */
+ if (TclListObjGetElements(interp, objv[arg], &listc,
+ &listv) != TCL_OK) {
+ return TCL_ERROR;
}
- default: {
- errorString = str;
- goto badField;
+ arg++;
+
+ if (count == BINARY_ALL) {
+ count = listc;
+ } else if (count > listc) {
+ Tcl_AppendResult(interp,
+ "number of elements in list does not match count",
+ NULL);
+ return TCL_ERROR;
}
}
+ offset += count*size;
+ break;
+
+ case 'x':
+ if (count == BINARY_ALL) {
+ Tcl_AppendResult(interp,
+ "cannot use \"*\" in format string with \"x\"",
+ NULL);
+ return TCL_ERROR;
+ } else if (count == BINARY_NOCOUNT) {
+ count = 1;
+ }
+ offset += count;
+ break;
+ case 'X':
+ if (count == BINARY_NOCOUNT) {
+ count = 1;
+ }
+ if ((count > offset) || (count == BINARY_ALL)) {
+ count = offset;
+ }
+ if (offset > length) {
+ length = offset;
+ }
+ offset -= count;
+ break;
+ case '@':
+ if (offset > length) {
+ length = offset;
+ }
+ if (count == BINARY_ALL) {
+ offset = length;
+ } else if (count == BINARY_NOCOUNT) {
+ goto badCount;
+ } else {
+ offset = count;
+ }
+ break;
+ default:
+ errorString = str;
+ goto badField;
}
- if (offset > length) {
- length = offset;
- }
- if (length == 0) {
- return TCL_OK;
- }
+ }
+ if (offset > length) {
+ length = offset;
+ }
+ if (length == 0) {
+ return TCL_OK;
+ }
- /*
- * Prepare the result object by preallocating the caclulated
- * number of bytes and filling with nulls.
- */
+ /*
+ * Prepare the result object by preallocating the caclulated number of
+ * bytes and filling with nulls.
+ */
- resultPtr = Tcl_GetObjResult(interp);
- if (Tcl_IsShared(resultPtr)) {
- TclNewObj(resultPtr);
- Tcl_SetObjResult(interp, resultPtr);
- }
- buffer = Tcl_SetByteArrayLength(resultPtr, length);
- memset((VOID *) buffer, 0, (size_t) length);
+ resultPtr = Tcl_NewObj();
+ buffer = Tcl_SetByteArrayLength(resultPtr, length);
+ memset(buffer, 0, (size_t) length);
- /*
- * Pack the data into the result object. Note that we can skip
- * the error checking during this pass, since we have already
- * parsed the string once.
- */
+ /*
+ * Pack the data into the result object. Note that we can skip the
+ * error checking during this pass, since we have already parsed the
+ * string once.
+ */
- arg = 3;
- format = Tcl_GetString(objv[2]);
- cursor = buffer;
- maxPos = cursor;
- while (*format != 0) {
- if (!GetFormatSpec(&format, &cmd, &count)) {
- break;
+ arg = 3;
+ format = TclGetString(objv[2]);
+ cursor = buffer;
+ maxPos = cursor;
+ while (*format != 0) {
+ flags = 0;
+ if (!GetFormatSpec(&format, &cmd, &count, &flags)) {
+ break;
+ }
+ if ((count == 0) && (cmd != '@')) {
+ if (cmd != 'x') {
+ arg++;
}
- if ((count == 0) && (cmd != '@')) {
- if (cmd != 'x') {
- arg++;
- }
- continue;
+ continue;
+ }
+ switch (cmd) {
+ case 'a':
+ case 'A': {
+ char pad = (char) (cmd == 'a' ? '\0' : ' ');
+ unsigned char *bytes;
+
+ bytes = Tcl_GetByteArrayFromObj(objv[arg++], &length);
+
+ if (count == BINARY_ALL) {
+ count = length;
+ } else if (count == BINARY_NOCOUNT) {
+ count = 1;
}
- switch (cmd) {
- case 'a':
- case 'A': {
- char pad = (char) (cmd == 'a' ? '\0' : ' ');
- unsigned char *bytes;
-
- bytes = Tcl_GetByteArrayFromObj(objv[arg++], &length);
-
- if (count == BINARY_ALL) {
- count = length;
- } else if (count == BINARY_NOCOUNT) {
- count = 1;
+ if (length >= count) {
+ memcpy(cursor, bytes, (size_t) count);
+ } else {
+ memcpy(cursor, bytes, (size_t) length);
+ memset(cursor + length, pad, (size_t) (count - length));
+ }
+ cursor += count;
+ break;
+ }
+ case 'b':
+ case 'B': {
+ unsigned char *last;
+
+ str = TclGetStringFromObj(objv[arg], &length);
+ arg++;
+ if (count == BINARY_ALL) {
+ count = length;
+ } else if (count == BINARY_NOCOUNT) {
+ count = 1;
+ }
+ last = cursor + ((count + 7) / 8);
+ if (count > length) {
+ count = length;
+ }
+ value = 0;
+ errorString = "binary";
+ if (cmd == 'B') {
+ for (offset = 0; offset < count; offset++) {
+ value <<= 1;
+ if (str[offset] == '1') {
+ value |= 1;
+ } else if (str[offset] != '0') {
+ errorValue = str;
+ Tcl_DecrRefCount(resultPtr);
+ goto badValue;
}
- if (length >= count) {
- memcpy((VOID *) cursor, (VOID *) bytes,
- (size_t) count);
- } else {
- memcpy((VOID *) cursor, (VOID *) bytes,
- (size_t) length);
- memset((VOID *) (cursor + length), pad,
- (size_t) (count - length));
+ if (((offset + 1) % 8) == 0) {
+ *cursor++ = (unsigned char) value;
+ value = 0;
}
- cursor += count;
- break;
}
- case 'b':
- case 'B': {
- unsigned char *last;
-
- str = Tcl_GetStringFromObj(objv[arg++], &length);
- if (count == BINARY_ALL) {
- count = length;
- } else if (count == BINARY_NOCOUNT) {
- count = 1;
- }
- last = cursor + ((count + 7) / 8);
- if (count > length) {
- count = length;
- }
- value = 0;
- errorString = "binary";
- if (cmd == 'B') {
- for (offset = 0; offset < count; offset++) {
- value <<= 1;
- if (str[offset] == '1') {
- value |= 1;
- } else if (str[offset] != '0') {
- errorValue = str;
- goto badValue;
- }
- if (((offset + 1) % 8) == 0) {
- *cursor++ = (unsigned char) value;
- value = 0;
- }
- }
- } else {
- for (offset = 0; offset < count; offset++) {
- value >>= 1;
- if (str[offset] == '1') {
- value |= 128;
- } else if (str[offset] != '0') {
- errorValue = str;
- goto badValue;
- }
- if (!((offset + 1) % 8)) {
- *cursor++ = (unsigned char) value;
- value = 0;
- }
- }
+ } else {
+ for (offset = 0; offset < count; offset++) {
+ value >>= 1;
+ if (str[offset] == '1') {
+ value |= 128;
+ } else if (str[offset] != '0') {
+ errorValue = str;
+ Tcl_DecrRefCount(resultPtr);
+ goto badValue;
}
- if ((offset % 8) != 0) {
- if (cmd == 'B') {
- value <<= 8 - (offset % 8);
- } else {
- value >>= 8 - (offset % 8);
- }
+ if (!((offset + 1) % 8)) {
*cursor++ = (unsigned char) value;
+ value = 0;
}
- while (cursor < last) {
- *cursor++ = '\0';
- }
- break;
}
- case 'h':
- case 'H': {
- unsigned char *last;
- int c;
-
- str = Tcl_GetStringFromObj(objv[arg++], &length);
- if (count == BINARY_ALL) {
- count = length;
- } else if (count == BINARY_NOCOUNT) {
- count = 1;
+ }
+ if ((offset % 8) != 0) {
+ if (cmd == 'B') {
+ value <<= 8 - (offset % 8);
+ } else {
+ value >>= 8 - (offset % 8);
+ }
+ *cursor++ = (unsigned char) value;
+ }
+ while (cursor < last) {
+ *cursor++ = '\0';
+ }
+ break;
+ }
+ case 'h':
+ case 'H': {
+ unsigned char *last;
+ int c;
+
+ str = TclGetStringFromObj(objv[arg], &length);
+ arg++;
+ if (count == BINARY_ALL) {
+ count = length;
+ } else if (count == BINARY_NOCOUNT) {
+ count = 1;
+ }
+ last = cursor + ((count + 1) / 2);
+ if (count > length) {
+ count = length;
+ }
+ value = 0;
+ errorString = "hexadecimal";
+ if (cmd == 'H') {
+ for (offset = 0; offset < count; offset++) {
+ value <<= 4;
+ if (!isxdigit(UCHAR(str[offset]))) { /* INTL: digit */
+ errorValue = str;
+ Tcl_DecrRefCount(resultPtr);
+ goto badValue;
}
- last = cursor + ((count + 1) / 2);
- if (count > length) {
- count = length;
+ c = str[offset] - '0';
+ if (c > 9) {
+ c += ('0' - 'A') + 10;
}
- value = 0;
- errorString = "hexadecimal";
- if (cmd == 'H') {
- for (offset = 0; offset < count; offset++) {
- value <<= 4;
- if (!isxdigit(UCHAR(str[offset]))) { /* INTL: digit */
- errorValue = str;
- goto badValue;
- }
- c = str[offset] - '0';
- if (c > 9) {
- c += ('0' - 'A') + 10;
- }
- if (c > 16) {
- c += ('A' - 'a');
- }
- value |= (c & 0xf);
- if (offset % 2) {
- *cursor++ = (char) value;
- value = 0;
- }
- }
- } else {
- for (offset = 0; offset < count; offset++) {
- value >>= 4;
-
- if (!isxdigit(UCHAR(str[offset]))) { /* INTL: digit */
- errorValue = str;
- goto badValue;
- }
- c = str[offset] - '0';
- if (c > 9) {
- c += ('0' - 'A') + 10;
- }
- if (c > 16) {
- c += ('A' - 'a');
- }
- value |= ((c << 4) & 0xf0);
- if (offset % 2) {
- *cursor++ = (unsigned char)(value & 0xff);
- value = 0;
- }
- }
+ if (c > 16) {
+ c += ('A' - 'a');
}
+ value |= (c & 0xf);
if (offset % 2) {
- if (cmd == 'H') {
- value <<= 4;
- } else {
- value >>= 4;
- }
- *cursor++ = (unsigned char) value;
+ *cursor++ = (char) value;
+ value = 0;
}
+ }
+ } else {
+ for (offset = 0; offset < count; offset++) {
+ value >>= 4;
- while (cursor < last) {
- *cursor++ = '\0';
+ if (!isxdigit(UCHAR(str[offset]))) { /* INTL: digit */
+ errorValue = str;
+ Tcl_DecrRefCount(resultPtr);
+ goto badValue;
}
- break;
- }
- case 'c':
- case 's':
- case 'S':
- case 'i':
- case 'I':
- case 'w':
- case 'W':
- case 'd':
- case 'f': {
- int listc, i;
- Tcl_Obj **listv;
-
- if (count == BINARY_NOCOUNT) {
- /*
- * Note that we are casting away the const-ness of
- * objv, but this is safe since we aren't going to
- * modify the array.
- */
-
- listv = (Tcl_Obj**)(objv + arg);
- listc = 1;
- count = 1;
- } else {
- Tcl_ListObjGetElements(interp, objv[arg],
- &listc, &listv);
- if (count == BINARY_ALL) {
- count = listc;
- }
+ c = str[offset] - '0';
+ if (c > 9) {
+ c += ('0' - 'A') + 10;
}
- arg++;
- for (i = 0; i < count; i++) {
- if (FormatNumber(interp, cmd, listv[i], &cursor)
- != TCL_OK) {
- return TCL_ERROR;
- }
+ if (c > 16) {
+ c += ('A' - 'a');
}
- break;
- }
- case 'x': {
- if (count == BINARY_NOCOUNT) {
- count = 1;
+ value |= ((c << 4) & 0xf0);
+ if (offset % 2) {
+ *cursor++ = (unsigned char)(value & 0xff);
+ value = 0;
}
- memset(cursor, 0, (size_t) count);
- cursor += count;
- break;
}
- case 'X': {
- if (cursor > maxPos) {
- maxPos = cursor;
- }
- if (count == BINARY_NOCOUNT) {
- count = 1;
- }
- if ((count == BINARY_ALL)
- || (count > (cursor - buffer))) {
- cursor = buffer;
- } else {
- cursor -= count;
- }
- break;
+ }
+ if (offset % 2) {
+ if (cmd == 'H') {
+ value <<= 4;
+ } else {
+ value >>= 4;
}
- case '@': {
- if (cursor > maxPos) {
- maxPos = cursor;
- }
- if (count == BINARY_ALL) {
- cursor = maxPos;
- } else {
- cursor = buffer + count;
- }
- break;
+ *cursor++ = (unsigned char) value;
+ }
+
+ while (cursor < last) {
+ *cursor++ = '\0';
+ }
+ break;
+ }
+ case 'c':
+ case 't':
+ case 's':
+ case 'S':
+ case 'n':
+ case 'i':
+ case 'I':
+ case 'm':
+ case 'w':
+ case 'W':
+ case 'r':
+ case 'R':
+ case 'd':
+ case 'q':
+ case 'Q':
+ case 'f': {
+ int listc, i;
+ Tcl_Obj **listv;
+
+ if (count == BINARY_NOCOUNT) {
+ /*
+ * Note that we are casting away the const-ness of objv,
+ * but this is safe since we aren't going to modify the
+ * array.
+ */
+
+ listv = (Tcl_Obj**)(objv + arg);
+ listc = 1;
+ count = 1;
+ } else {
+ TclListObjGetElements(interp, objv[arg], &listc, &listv);
+ if (count == BINARY_ALL) {
+ count = listc;
}
}
+ arg++;
+ for (i = 0; i < count; i++) {
+ if (FormatNumber(interp, cmd, listv[i], &cursor)!=TCL_OK) {
+ Tcl_DecrRefCount(resultPtr);
+ return TCL_ERROR;
+ }
+ }
+ break;
+ }
+ case 'x':
+ if (count == BINARY_NOCOUNT) {
+ count = 1;
+ }
+ memset(cursor, 0, (size_t) count);
+ cursor += count;
+ break;
+ case 'X':
+ if (cursor > maxPos) {
+ maxPos = cursor;
+ }
+ if (count == BINARY_NOCOUNT) {
+ count = 1;
+ }
+ if ((count == BINARY_ALL) || (count > (cursor - buffer))) {
+ cursor = buffer;
+ } else {
+ cursor -= count;
+ }
+ break;
+ case '@':
+ if (cursor > maxPos) {
+ maxPos = cursor;
+ }
+ if (count == BINARY_ALL) {
+ cursor = maxPos;
+ } else {
+ cursor = buffer + count;
+ }
+ break;
}
- break;
}
- case BINARY_SCAN: {
- int i;
- Tcl_Obj *valuePtr, *elementPtr;
- Tcl_HashTable numberCacheHash;
- Tcl_HashTable *numberCachePtr;
-
- if (objc < 4) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "value formatString ?varName varName ...?");
- return TCL_ERROR;
+ Tcl_SetObjResult(interp, resultPtr);
+ break;
+ case BINARY_SCAN: {
+ int i;
+ Tcl_Obj *valuePtr, *elementPtr;
+ Tcl_HashTable numberCacheHash;
+ Tcl_HashTable *numberCachePtr;
+
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "value formatString ?varName varName ...?");
+ return TCL_ERROR;
+ }
+ numberCachePtr = &numberCacheHash;
+ Tcl_InitHashTable(numberCachePtr, TCL_ONE_WORD_KEYS);
+ buffer = Tcl_GetByteArrayFromObj(objv[2], &length);
+ format = TclGetString(objv[3]);
+ cursor = buffer;
+ arg = 4;
+ offset = 0;
+ while (*format != '\0') {
+ str = format;
+ flags = 0;
+ if (!GetFormatSpec(&format, &cmd, &count, &flags)) {
+ goto done;
}
- numberCachePtr = &numberCacheHash;
- Tcl_InitHashTable(numberCachePtr, TCL_ONE_WORD_KEYS);
- buffer = Tcl_GetByteArrayFromObj(objv[2], &length);
- format = Tcl_GetString(objv[3]);
- cursor = buffer;
- arg = 4;
- offset = 0;
- while (*format != '\0') {
- str = format;
- if (!GetFormatSpec(&format, &cmd, &count)) {
- goto done;
+ switch (cmd) {
+ case 'a':
+ case 'A': {
+ unsigned char *src;
+
+ if (arg >= objc) {
+ DeleteScanNumberCache(numberCachePtr);
+ goto badIndex;
+ }
+ if (count == BINARY_ALL) {
+ count = length - offset;
+ } else {
+ if (count == BINARY_NOCOUNT) {
+ count = 1;
+ }
+ if (count > (length - offset)) {
+ goto done;
+ }
}
- switch (cmd) {
- case 'a':
- case 'A': {
- unsigned char *src;
-
- if (arg >= objc) {
- DeleteScanNumberCache(numberCachePtr);
- goto badIndex;
- }
- if (count == BINARY_ALL) {
- count = length - offset;
- } else {
- if (count == BINARY_NOCOUNT) {
- count = 1;
- }
- if (count > (length - offset)) {
- goto done;
- }
- }
- src = buffer + offset;
- size = count;
+ src = buffer + offset;
+ size = count;
- /*
- * Trim trailing nulls and spaces, if necessary.
- */
+ /*
+ * Trim trailing nulls and spaces, if necessary.
+ */
- if (cmd == 'A') {
- while (size > 0) {
- if (src[size-1] != '\0' && src[size-1] != ' ') {
- break;
- }
- size--;
- }
- }
- valuePtr = Tcl_NewByteArrayObj(src, size);
- Tcl_IncrRefCount(valuePtr);
- resultPtr = Tcl_ObjSetVar2(interp, objv[arg],
- NULL, valuePtr, TCL_LEAVE_ERR_MSG);
- Tcl_DecrRefCount(valuePtr);
- arg++;
- if (resultPtr == NULL) {
- DeleteScanNumberCache(numberCachePtr);
- return TCL_ERROR;
+ if (cmd == 'A') {
+ while (size > 0) {
+ if (src[size-1] != '\0' && src[size-1] != ' ') {
+ break;
}
- offset += count;
- break;
+ size--;
}
- case 'b':
- case 'B': {
- unsigned char *src;
- char *dest;
-
- if (arg >= objc) {
- DeleteScanNumberCache(numberCachePtr);
- goto badIndex;
- }
- if (count == BINARY_ALL) {
- count = (length - offset) * 8;
- } else {
- if (count == BINARY_NOCOUNT) {
- count = 1;
- }
- if (count > (length - offset) * 8) {
- goto done;
- }
- }
- src = buffer + offset;
- valuePtr = Tcl_NewObj();
- Tcl_SetObjLength(valuePtr, count);
- dest = Tcl_GetString(valuePtr);
-
- if (cmd == 'b') {
- for (i = 0; i < count; i++) {
- if (i % 8) {
- value >>= 1;
- } else {
- value = *src++;
- }
- *dest++ = (char) ((value & 1) ? '1' : '0');
- }
- } else {
- for (i = 0; i < count; i++) {
- if (i % 8) {
- value <<= 1;
- } else {
- value = *src++;
- }
- *dest++ = (char) ((value & 0x80) ? '1' : '0');
- }
- }
+ }
- Tcl_IncrRefCount(valuePtr);
- resultPtr = Tcl_ObjSetVar2(interp, objv[arg],
- NULL, valuePtr, TCL_LEAVE_ERR_MSG);
- Tcl_DecrRefCount(valuePtr);
- arg++;
- if (resultPtr == NULL) {
- DeleteScanNumberCache(numberCachePtr);
- return TCL_ERROR;
- }
- offset += (count + 7 ) / 8;
- break;
+ /*
+ * Have to do this #ifdef-fery because (as part of defining
+ * Tcl_NewByteArrayObj) we removed the #def that hides this
+ * stuff normally. If this code ever gets copied to another
+ * file, it should be changed back to the simpler version.
+ */
+
+#ifdef TCL_MEM_DEBUG
+ valuePtr = Tcl_DbNewByteArrayObj(src, size, __FILE__,__LINE__);
+#else
+ valuePtr = Tcl_NewByteArrayObj(src, size);
+#endif /* TCL_MEM_DEBUG */
+
+ resultPtr = Tcl_ObjSetVar2(interp, objv[arg], NULL, valuePtr,
+ TCL_LEAVE_ERR_MSG);
+ arg++;
+ if (resultPtr == NULL) {
+ DeleteScanNumberCache(numberCachePtr);
+ return TCL_ERROR;
+ }
+ offset += count;
+ break;
+ }
+ case 'b':
+ case 'B': {
+ unsigned char *src;
+ char *dest;
+
+ if (arg >= objc) {
+ DeleteScanNumberCache(numberCachePtr);
+ goto badIndex;
+ }
+ if (count == BINARY_ALL) {
+ count = (length - offset) * 8;
+ } else {
+ if (count == BINARY_NOCOUNT) {
+ count = 1;
}
- case 'h':
- case 'H': {
- char *dest;
- unsigned char *src;
- int i;
- static char hexdigit[] = "0123456789abcdef";
-
- if (arg >= objc) {
- DeleteScanNumberCache(numberCachePtr);
- goto badIndex;
- }
- if (count == BINARY_ALL) {
- count = (length - offset)*2;
+ if (count > (length - offset) * 8) {
+ goto done;
+ }
+ }
+ src = buffer + offset;
+ valuePtr = Tcl_NewObj();
+ Tcl_SetObjLength(valuePtr, count);
+ dest = TclGetString(valuePtr);
+
+ if (cmd == 'b') {
+ for (i = 0; i < count; i++) {
+ if (i % 8) {
+ value >>= 1;
} else {
- if (count == BINARY_NOCOUNT) {
- count = 1;
- }
- if (count > (length - offset)*2) {
- goto done;
- }
+ value = *src++;
}
- src = buffer + offset;
- valuePtr = Tcl_NewObj();
- Tcl_SetObjLength(valuePtr, count);
- dest = Tcl_GetString(valuePtr);
-
- if (cmd == 'h') {
- for (i = 0; i < count; i++) {
- if (i % 2) {
- value >>= 4;
- } else {
- value = *src++;
- }
- *dest++ = hexdigit[value & 0xf];
- }
+ *dest++ = (char) ((value & 1) ? '1' : '0');
+ }
+ } else {
+ for (i = 0; i < count; i++) {
+ if (i % 8) {
+ value <<= 1;
} else {
- for (i = 0; i < count; i++) {
- if (i % 2) {
- value <<= 4;
- } else {
- value = *src++;
- }
- *dest++ = hexdigit[(value >> 4) & 0xf];
- }
+ value = *src++;
}
-
- Tcl_IncrRefCount(valuePtr);
- resultPtr = Tcl_ObjSetVar2(interp, objv[arg],
- NULL, valuePtr, TCL_LEAVE_ERR_MSG);
- Tcl_DecrRefCount(valuePtr);
- arg++;
- if (resultPtr == NULL) {
- DeleteScanNumberCache(numberCachePtr);
- return TCL_ERROR;
- }
- offset += (count + 1) / 2;
- break;
- }
- case 'c': {
- size = 1;
- goto scanNumber;
- }
- case 's':
- case 'S': {
- size = 2;
- goto scanNumber;
+ *dest++ = (char) ((value & 0x80) ? '1' : '0');
}
- case 'i':
- case 'I': {
- size = 4;
- goto scanNumber;
- }
- case 'w':
- case 'W': {
- size = 8;
- goto scanNumber;
+ }
+
+ resultPtr = Tcl_ObjSetVar2(interp, objv[arg], NULL, valuePtr,
+ TCL_LEAVE_ERR_MSG);
+ arg++;
+ if (resultPtr == NULL) {
+ DeleteScanNumberCache(numberCachePtr);
+ return TCL_ERROR;
+ }
+ offset += (count + 7) / 8;
+ break;
+ }
+ case 'h':
+ case 'H': {
+ char *dest;
+ unsigned char *src;
+ int i;
+ static const char hexdigit[] = "0123456789abcdef";
+
+ if (arg >= objc) {
+ DeleteScanNumberCache(numberCachePtr);
+ goto badIndex;
+ }
+ if (count == BINARY_ALL) {
+ count = (length - offset)*2;
+ } else {
+ if (count == BINARY_NOCOUNT) {
+ count = 1;
}
- case 'f': {
- size = sizeof(float);
- goto scanNumber;
+ if (count > (length - offset)*2) {
+ goto done;
}
- case 'd': {
- unsigned char *src;
-
- size = sizeof(double);
- /* fall through */
-
- scanNumber:
- if (arg >= objc) {
- DeleteScanNumberCache(numberCachePtr);
- goto badIndex;
- }
- if (count == BINARY_NOCOUNT) {
- if ((length - offset) < size) {
- goto done;
- }
- valuePtr = ScanNumber(buffer+offset, cmd,
- &numberCachePtr);
- offset += size;
+ }
+ src = buffer + offset;
+ valuePtr = Tcl_NewObj();
+ Tcl_SetObjLength(valuePtr, count);
+ dest = TclGetString(valuePtr);
+
+ if (cmd == 'h') {
+ for (i = 0; i < count; i++) {
+ if (i % 2) {
+ value >>= 4;
} else {
- if (count == BINARY_ALL) {
- count = (length - offset) / size;
- }
- if ((length - offset) < (count * size)) {
- goto done;
- }
- valuePtr = Tcl_NewObj();
- src = buffer+offset;
- for (i = 0; i < count; i++) {
- elementPtr = ScanNumber(src, cmd,
- &numberCachePtr);
- src += size;
- Tcl_ListObjAppendElement(NULL, valuePtr,
- elementPtr);
- }
- offset += count*size;
+ value = *src++;
}
-
- Tcl_IncrRefCount(valuePtr);
- resultPtr = Tcl_ObjSetVar2(interp, objv[arg],
- NULL, valuePtr, TCL_LEAVE_ERR_MSG);
- Tcl_DecrRefCount(valuePtr);
- arg++;
- if (resultPtr == NULL) {
- DeleteScanNumberCache(numberCachePtr);
- return TCL_ERROR;
- }
- break;
+ *dest++ = hexdigit[value & 0xf];
}
- case 'x': {
- if (count == BINARY_NOCOUNT) {
- count = 1;
- }
- if ((count == BINARY_ALL)
- || (count > (length - offset))) {
- offset = length;
+ } else {
+ for (i = 0; i < count; i++) {
+ if (i % 2) {
+ value <<= 4;
} else {
- offset += count;
+ value = *src++;
}
- break;
+ *dest++ = hexdigit[(value >> 4) & 0xf];
}
- case 'X': {
- if (count == BINARY_NOCOUNT) {
- count = 1;
- }
- if ((count == BINARY_ALL) || (count > offset)) {
- offset = 0;
- } else {
- offset -= count;
- }
- break;
+ }
+
+ resultPtr = Tcl_ObjSetVar2(interp, objv[arg], NULL, valuePtr,
+ TCL_LEAVE_ERR_MSG);
+ arg++;
+ if (resultPtr == NULL) {
+ DeleteScanNumberCache(numberCachePtr);
+ return TCL_ERROR;
+ }
+ offset += (count + 1) / 2;
+ break;
+ }
+ case 'c':
+ size = 1;
+ goto scanNumber;
+ case 't':
+ case 's':
+ case 'S':
+ size = 2;
+ goto scanNumber;
+ case 'n':
+ case 'i':
+ case 'I':
+ size = 4;
+ goto scanNumber;
+ case 'm':
+ case 'w':
+ case 'W':
+ size = 8;
+ goto scanNumber;
+ case 'r':
+ case 'R':
+ case 'f':
+ size = sizeof(float);
+ goto scanNumber;
+ case 'q':
+ case 'Q':
+ case 'd': {
+ unsigned char *src;
+
+ size = sizeof(double);
+ /* fall through */
+
+ scanNumber:
+ if (arg >= objc) {
+ DeleteScanNumberCache(numberCachePtr);
+ goto badIndex;
+ }
+ if (count == BINARY_NOCOUNT) {
+ if ((length - offset) < size) {
+ goto done;
}
- case '@': {
- if (count == BINARY_NOCOUNT) {
- DeleteScanNumberCache(numberCachePtr);
- goto badCount;
- }
- if ((count == BINARY_ALL) || (count > length)) {
- offset = length;
- } else {
- offset = count;
- }
- break;
+ valuePtr = ScanNumber(buffer+offset, cmd, flags,
+ &numberCachePtr);
+ offset += size;
+ } else {
+ if (count == BINARY_ALL) {
+ count = (length - offset) / size;
+ }
+ if ((length - offset) < (count * size)) {
+ goto done;
}
- default: {
- DeleteScanNumberCache(numberCachePtr);
- errorString = str;
- goto badField;
+ valuePtr = Tcl_NewObj();
+ src = buffer+offset;
+ for (i = 0; i < count; i++) {
+ elementPtr = ScanNumber(src, cmd, flags,
+ &numberCachePtr);
+ src += size;
+ Tcl_ListObjAppendElement(NULL, valuePtr, elementPtr);
}
+ offset += count*size;
+ }
+
+ resultPtr = Tcl_ObjSetVar2(interp, objv[arg], NULL, valuePtr,
+ TCL_LEAVE_ERR_MSG);
+ arg++;
+ if (resultPtr == NULL) {
+ DeleteScanNumberCache(numberCachePtr);
+ return TCL_ERROR;
+ }
+ break;
+ }
+ case 'x':
+ if (count == BINARY_NOCOUNT) {
+ count = 1;
+ }
+ if ((count == BINARY_ALL) || (count > (length - offset))) {
+ offset = length;
+ } else {
+ offset += count;
+ }
+ break;
+ case 'X':
+ if (count == BINARY_NOCOUNT) {
+ count = 1;
+ }
+ if ((count == BINARY_ALL) || (count > offset)) {
+ offset = 0;
+ } else {
+ offset -= count;
+ }
+ break;
+ case '@':
+ if (count == BINARY_NOCOUNT) {
+ DeleteScanNumberCache(numberCachePtr);
+ goto badCount;
}
+ if ((count == BINARY_ALL) || (count > length)) {
+ offset = length;
+ } else {
+ offset = count;
+ }
+ break;
+ default:
+ DeleteScanNumberCache(numberCachePtr);
+ errorString = str;
+ goto badField;
}
+ }
- /*
- * Set the result to the last position of the cursor.
- */
+ /*
+ * Set the result to the last position of the cursor.
+ */
- done:
- Tcl_ResetResult(interp);
- Tcl_SetLongObj(Tcl_GetObjResult(interp), arg - 4);
- DeleteScanNumberCache(numberCachePtr);
- break;
- }
+ done:
+ Tcl_SetObjResult(interp, Tcl_NewLongObj(arg - 4));
+ DeleteScanNumberCache(numberCachePtr);
+ break;
+ }
}
return TCL_OK;
- badValue:
+ badValue:
Tcl_ResetResult(interp);
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "expected ", errorString,
+ Tcl_AppendResult(interp, "expected ", errorString,
" string but got \"", errorValue, "\" instead", NULL);
return TCL_ERROR;
- badCount:
+ badCount:
errorString = "missing count for \"@\" field specifier";
goto error;
- badIndex:
+ badIndex:
errorString = "not enough arguments for all format specifiers";
goto error;
- badField:
+ badField:
{
Tcl_UniChar ch;
char buf[TCL_UTF_MAX + 1];
@@ -1365,7 +1368,7 @@ Tcl_BinaryObjCmd(dummy, interp, objc, objv)
return TCL_ERROR;
}
- error:
+ error:
Tcl_AppendResult(interp, errorString, NULL);
return TCL_ERROR;
}
@@ -1375,15 +1378,15 @@ Tcl_BinaryObjCmd(dummy, interp, objc, objv)
*
* GetFormatSpec --
*
- * This function parses the format strings used in the binary
- * format and scan commands.
+ * This function parses the format strings used in the binary format and
+ * scan commands.
*
* Results:
- * Moves the formatPtr to the start of the next command. Returns
- * the current command character and count in cmdPtr and countPtr.
- * The count is set to BINARY_ALL if the count character was '*'
- * or BINARY_NOCOUNT if no count was specified. Returns 1 on
- * success, or 0 if the string did not have a format specifier.
+ * Moves the formatPtr to the start of the next command. Returns the
+ * current command character and count in cmdPtr and countPtr. The count
+ * is set to BINARY_ALL if the count character was '*' or BINARY_NOCOUNT
+ * if no count was specified. Returns 1 on success, or 0 if the string
+ * did not have a format specifier.
*
* Side effects:
* None.
@@ -1392,10 +1395,11 @@ Tcl_BinaryObjCmd(dummy, interp, objc, objv)
*/
static int
-GetFormatSpec(formatPtr, cmdPtr, countPtr)
- char **formatPtr; /* Pointer to format string. */
- char *cmdPtr; /* Pointer to location of command char. */
- int *countPtr; /* Pointer to repeat count value. */
+GetFormatSpec(
+ char **formatPtr, /* Pointer to format string. */
+ char *cmdPtr, /* Pointer to location of command char. */
+ int *countPtr, /* Pointer to repeat count value. */
+ int *flagsPtr) /* Pointer to field flags */
{
/*
* Skip any leading blanks.
@@ -1419,6 +1423,10 @@ GetFormatSpec(formatPtr, cmdPtr, countPtr)
*cmdPtr = **formatPtr;
(*formatPtr)++;
+ if (**formatPtr == 'u') {
+ (*formatPtr)++;
+ (*flagsPtr) |= BINARY_UNSIGNED;
+ }
if (**formatPtr == '*') {
(*formatPtr)++;
(*countPtr) = BINARY_ALL;
@@ -1433,13 +1441,193 @@ GetFormatSpec(formatPtr, cmdPtr, countPtr)
/*
*----------------------------------------------------------------------
*
+ * NeedReversing --
+ *
+ * This routine determines, if bytes of a number need to be re-ordered,
+ * and returns a numeric code indicating the re-ordering to be done.
+ * This depends on the endiannes of the machine and the desired format.
+ * It is in effect a table (whose contents depend on the endianness of
+ * the system) describing whether a value needs reversing or not. Anyone
+ * porting the code to a big-endian platform should take care to make
+ * sure that they define WORDS_BIGENDIAN though this is already done by
+ * configure for the Unix build; little-endian platforms (including
+ * Windows) don't need to do anything.
+ *
+ * Results:
+ * 0 No re-ordering needed.
+ * 1 Reverse the bytes: 01234567 <-> 76543210 (little to big)
+ * 2 Apply this re-ordering: 01234567 <-> 45670123 (Nokia to little)
+ * 3 Apply this re-ordering: 01234567 <-> 32107654 (Nokia to big)
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NeedReversing(
+ int format)
+{
+ switch (format) {
+ /* native floats and doubles: never reverse */
+ case 'd':
+ case 'f':
+ /* big endian ints: never reverse */
+ case 'I':
+ case 'S':
+ case 'W':
+#ifdef WORDS_BIGENDIAN
+ /* native ints: reverse if we're little-endian */
+ case 'n':
+ case 't':
+ case 'm':
+ /* f: reverse if we're little-endian */
+ case 'Q':
+ case 'R':
+#else /* !WORDS_BIGENDIAN */
+ /* small endian floats: reverse if we're big-endian */
+ case 'r':
+#endif /* WORDS_BIGENDIAN */
+ return 0;
+
+#ifdef WORDS_BIGENDIAN
+ /* small endian floats: reverse if we're big-endian */
+ case 'q':
+ case 'r':
+#else /* !WORDS_BIGENDIAN */
+ /* native ints: reverse if we're little-endian */
+ case 'n':
+ case 't':
+ case 'm':
+ /* f: reverse if we're little-endian */
+ case 'R':
+#endif /* WORDS_BIGENDIAN */
+ /* small endian ints: always reverse */
+ case 'i':
+ case 's':
+ case 'w':
+ return 1;
+
+#ifndef WORDS_BIGENDIAN
+ /*
+ * The Q and q formats need special handling to account for the unusual
+ * byte ordering of 8-byte floats on Nokia 770 systems, which claim to be
+ * little-endian, but also reverse word order.
+ */
+
+ case 'Q':
+ if (TclNokia770Doubles()) {
+ return 3;
+ }
+ return 1;
+ case 'q':
+ if (TclNokia770Doubles()) {
+ return 2;
+ }
+ return 0;
+#endif
+ }
+
+ Tcl_Panic("unexpected fallthrough");
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CopyNumber --
+ *
+ * This routine is called by FormatNumber and ScanNumber to copy a
+ * floating-point number. If required, bytes are reversed while copying.
+ * The behaviour is only fully defined when used with IEEE float and
+ * double values (guaranteed to be 4 and 8 bytes long, respectively.)
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * Copies length bytes
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+CopyNumber(
+ const void *from, /* source */
+ void *to, /* destination */
+ unsigned int length, /* Number of bytes to copy */
+ int type) /* What type of thing are we copying? */
+{
+ switch (NeedReversing(type)) {
+ case 0:
+ memcpy(to, from, length);
+ break;
+ case 1: {
+ const unsigned char *fromPtr = from;
+ unsigned char *toPtr = to;
+
+ switch (length) {
+ case 4:
+ toPtr[0] = fromPtr[3];
+ toPtr[1] = fromPtr[2];
+ toPtr[2] = fromPtr[1];
+ toPtr[3] = fromPtr[0];
+ break;
+ case 8:
+ toPtr[0] = fromPtr[7];
+ toPtr[1] = fromPtr[6];
+ toPtr[2] = fromPtr[5];
+ toPtr[3] = fromPtr[4];
+ toPtr[4] = fromPtr[3];
+ toPtr[5] = fromPtr[2];
+ toPtr[6] = fromPtr[1];
+ toPtr[7] = fromPtr[0];
+ break;
+ }
+ break;
+ }
+ case 2: {
+ const unsigned char *fromPtr = from;
+ unsigned char *toPtr = to;
+
+ toPtr[0] = fromPtr[4];
+ toPtr[1] = fromPtr[5];
+ toPtr[2] = fromPtr[6];
+ toPtr[3] = fromPtr[7];
+ toPtr[4] = fromPtr[0];
+ toPtr[5] = fromPtr[1];
+ toPtr[6] = fromPtr[2];
+ toPtr[7] = fromPtr[3];
+ break;
+ }
+ case 3: {
+ const unsigned char *fromPtr = from;
+ unsigned char *toPtr = to;
+
+ toPtr[0] = fromPtr[3];
+ toPtr[1] = fromPtr[2];
+ toPtr[2] = fromPtr[1];
+ toPtr[3] = fromPtr[0];
+ toPtr[4] = fromPtr[7];
+ toPtr[5] = fromPtr[6];
+ toPtr[6] = fromPtr[5];
+ toPtr[7] = fromPtr[4];
+ break;
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* FormatNumber --
*
- * This routine is called by Tcl_BinaryObjCmd to format a number
- * into a location pointed at by cursor.
+ * This routine is called by Tcl_BinaryObjCmd to format a number into a
+ * location pointed at by cursor.
*
* Results:
- * A standard Tcl result.
+ * A standard Tcl result.
*
* Side effects:
* Moves the cursor to the next location to be written into.
@@ -1448,64 +1636,79 @@ GetFormatSpec(formatPtr, cmdPtr, countPtr)
*/
static int
-FormatNumber(interp, type, src, cursorPtr)
- Tcl_Interp *interp; /* Current interpreter, used to report
+FormatNumber(
+ Tcl_Interp *interp, /* Current interpreter, used to report
* errors. */
- int type; /* Type of number to format. */
- Tcl_Obj *src; /* Number to format. */
- unsigned char **cursorPtr; /* Pointer to index into destination buffer. */
+ int type, /* Type of number to format. */
+ Tcl_Obj *src, /* Number to format. */
+ unsigned char **cursorPtr) /* Pointer to index into destination buffer. */
{
long value;
double dvalue;
Tcl_WideInt wvalue;
+ float fvalue;
switch (type) {
case 'd':
- case 'f':
+ case 'q':
+ case 'Q':
/*
- * For floating point types, we need to copy the data using
- * memcpy to avoid alignment issues.
+ * Double-precision floating point values. Tcl_GetDoubleFromObj
+ * returns TCL_ERROR for NaN, but we can check by comparing the
+ * object's type pointer.
*/
if (Tcl_GetDoubleFromObj(interp, src, &dvalue) != TCL_OK) {
- return TCL_ERROR;
+ if (src->typePtr != &tclDoubleType) {
+ return TCL_ERROR;
+ }
+ dvalue = src->internalRep.doubleValue;
}
- if (type == 'd') {
- /*
- * Can't just memcpy() here. [Bug 1116542]
- */
-
- CopyNumber(&dvalue, *cursorPtr, sizeof(double));
- *cursorPtr += sizeof(double);
- } else {
- float fvalue;
+ CopyNumber(&dvalue, *cursorPtr, sizeof(double), type);
+ *cursorPtr += sizeof(double);
+ return TCL_OK;
- /*
- * Because some compilers will generate floating point exceptions
- * on an overflow cast (e.g. Borland), we restrict the values
- * to the valid range for float.
- */
+ case 'f':
+ case 'r':
+ case 'R':
+ /*
+ * Single-precision floating point values. Tcl_GetDoubleFromObj
+ * returns TCL_ERROR for NaN, but we can check by comparing the
+ * object's type pointer.
+ */
- if (fabs(dvalue) > (double)FLT_MAX) {
- fvalue = (dvalue >= 0.0) ? FLT_MAX : -FLT_MAX;
- } else {
- fvalue = (float) dvalue;
+ if (Tcl_GetDoubleFromObj(interp, src, &dvalue) != TCL_OK) {
+ if (src->typePtr != &tclDoubleType) {
+ return TCL_ERROR;
}
- memcpy((VOID *) *cursorPtr, (VOID *) &fvalue, sizeof(float));
- *cursorPtr += sizeof(float);
+ dvalue = src->internalRep.doubleValue;
+ }
+
+ /*
+ * Because some compilers will generate floating point exceptions on
+ * an overflow cast (e.g. Borland), we restrict the values to the
+ * valid range for float.
+ */
+
+ if (fabs(dvalue) > (double)FLT_MAX) {
+ fvalue = (dvalue >= 0.0) ? FLT_MAX : -FLT_MAX;
+ } else {
+ fvalue = (float) dvalue;
}
+ CopyNumber(&fvalue, *cursorPtr, sizeof(float), type);
+ *cursorPtr += sizeof(float);
return TCL_OK;
/*
- * Next cases separate from other integer cases because we
- * need a different API to get a wide.
+ * 64-bit integer values.
*/
case 'w':
case 'W':
+ case 'm':
if (Tcl_GetWideIntFromObj(interp, src, &wvalue) != TCL_OK) {
return TCL_ERROR;
}
- if (type == 'w') {
+ if (NeedReversing(type)) {
*(*cursorPtr)++ = (unsigned char) wvalue;
*(*cursorPtr)++ = (unsigned char) (wvalue >> 8);
*(*cursorPtr)++ = (unsigned char) (wvalue >> 16);
@@ -1525,170 +1728,221 @@ FormatNumber(interp, type, src, cursorPtr)
*(*cursorPtr)++ = (unsigned char) wvalue;
}
return TCL_OK;
- default:
- if (Tcl_GetLongFromObj(interp, src, &value) != TCL_OK) {
+
+ /*
+ * 32-bit integer values.
+ */
+ case 'i':
+ case 'I':
+ case 'n':
+ if (TclGetLongFromObj(interp, src, &value) != TCL_OK) {
return TCL_ERROR;
}
- if (type == 'c') {
- *(*cursorPtr)++ = (unsigned char) value;
- } else if (type == 's') {
- *(*cursorPtr)++ = (unsigned char) value;
- *(*cursorPtr)++ = (unsigned char) (value >> 8);
- } else if (type == 'S') {
- *(*cursorPtr)++ = (unsigned char) (value >> 8);
- *(*cursorPtr)++ = (unsigned char) value;
- } else if (type == 'i') {
+ if (NeedReversing(type)) {
*(*cursorPtr)++ = (unsigned char) value;
*(*cursorPtr)++ = (unsigned char) (value >> 8);
*(*cursorPtr)++ = (unsigned char) (value >> 16);
*(*cursorPtr)++ = (unsigned char) (value >> 24);
- } else if (type == 'I') {
+ } else {
*(*cursorPtr)++ = (unsigned char) (value >> 24);
*(*cursorPtr)++ = (unsigned char) (value >> 16);
*(*cursorPtr)++ = (unsigned char) (value >> 8);
*(*cursorPtr)++ = (unsigned char) value;
}
return TCL_OK;
+
+ /*
+ * 16-bit integer values.
+ */
+ case 's':
+ case 'S':
+ case 't':
+ if (TclGetLongFromObj(interp, src, &value) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (NeedReversing(type)) {
+ *(*cursorPtr)++ = (unsigned char) value;
+ *(*cursorPtr)++ = (unsigned char) (value >> 8);
+ } else {
+ *(*cursorPtr)++ = (unsigned char) (value >> 8);
+ *(*cursorPtr)++ = (unsigned char) value;
+ }
+ return TCL_OK;
+
+ /*
+ * 8-bit integer values.
+ */
+ case 'c':
+ if (TclGetLongFromObj(interp, src, &value) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ *(*cursorPtr)++ = (unsigned char) value;
+ return TCL_OK;
+
+ default:
+ Tcl_Panic("unexpected fallthrough");
+ return TCL_ERROR;
}
}
-/* Ugly workaround for old and broken compiler! */
-static void
-CopyNumber(from, to, length)
- CONST VOID *from;
- VOID *to;
- unsigned int length;
-{
- memcpy(to, from, length);
-}
-
/*
*----------------------------------------------------------------------
*
* ScanNumber --
*
- * This routine is called by Tcl_BinaryObjCmd to scan a number
- * out of a buffer.
+ * This routine is called by Tcl_BinaryObjCmd to scan a number out of a
+ * buffer.
*
* Results:
- * Returns a newly created object containing the scanned number.
- * This object has a ref count of zero.
+ * Returns a newly created object containing the scanned number. This
+ * object has a ref count of zero.
*
* Side effects:
- * Might reuse an object in the number cache, place a new object
- * in the cache, or delete the cache and set the reference to
- * it (itself passed in by reference) to NULL.
+ * Might reuse an object in the number cache, place a new object in the
+ * cache, or delete the cache and set the reference to it (itself passed
+ * in by reference) to NULL.
*
*----------------------------------------------------------------------
*/
static Tcl_Obj *
-ScanNumber(buffer, type, numberCachePtrPtr)
- unsigned char *buffer; /* Buffer to scan number from. */
- int type; /* Format character from "binary scan" */
- Tcl_HashTable **numberCachePtrPtr;
+ScanNumber(
+ unsigned char *buffer, /* Buffer to scan number from. */
+ int type, /* Format character from "binary scan" */
+ int flags, /* Format field flags */
+ Tcl_HashTable **numberCachePtrPtr)
/* Place to look for cache of scanned
* value objects, or NULL if too many
* different numbers have been scanned. */
{
long value;
+ float fvalue;
+ double dvalue;
Tcl_WideUInt uwvalue;
/*
* We cannot rely on the compiler to properly sign extend integer values
* when we cast from smaller values to larger values because we don't know
- * the exact size of the integer types. So, we have to handle sign
+ * the exact size of the integer types. So, we have to handle sign
* extension explicitly by checking the high bit and padding with 1's as
- * needed.
+ * needed. This practice is disabled if the BINARY_UNSIGNED flag is set.
*/
switch (type) {
- case 'c':
- /*
- * Characters need special handling. We want to produce a
- * signed result, but on some platforms (such as AIX) chars
- * are unsigned. To deal with this, check for a value that
- * should be negative but isn't.
- */
+ case 'c':
+ /*
+ * Characters need special handling. We want to produce a signed
+ * result, but on some platforms (such as AIX) chars are unsigned. To
+ * deal with this, check for a value that should be negative but
+ * isn't.
+ */
- value = buffer[0];
+ value = buffer[0];
+ if (!(flags & BINARY_UNSIGNED)) {
if (value & 0x80) {
value |= -0x100;
}
- goto returnNumericObject;
+ }
+ goto returnNumericObject;
+
+ /*
+ * 16-bit numeric values. We need the sign extension trick (see above)
+ * here as well.
+ */
- case 's':
+ case 's':
+ case 'S':
+ case 't':
+ if (NeedReversing(type)) {
value = (long) (buffer[0] + (buffer[1] << 8));
- goto shortValue;
- case 'S':
+ } else {
value = (long) (buffer[1] + (buffer[0] << 8));
- shortValue:
+ }
+ if (!(flags & BINARY_UNSIGNED)) {
if (value & 0x8000) {
value |= -0x10000;
}
- goto returnNumericObject;
+ }
+ goto returnNumericObject;
- case 'i':
- value = (long) (buffer[0]
+ /*
+ * 32-bit numeric values.
+ */
+
+ case 'i':
+ case 'I':
+ case 'n':
+ if (NeedReversing(type)) {
+ value = (long) (buffer[0]
+ (buffer[1] << 8)
+ (buffer[2] << 16)
- + (buffer[3] << 24));
- goto intValue;
- case 'I':
+ + (((long)buffer[3]) << 24));
+ } else {
value = (long) (buffer[3]
+ (buffer[2] << 8)
+ (buffer[1] << 16)
- + (buffer[0] << 24));
- intValue:
- /*
- * Check to see if the value was sign extended properly on
- * systems where an int is more than 32-bits.
- */
+ + (((long)buffer[0]) << 24));
+ }
+
+ /*
+ * Check to see if the value was sign extended properly on systems
+ * where an int is more than 32-bits.
+ * We avoid caching unsigned integers as we cannot distinguish between
+ * 32bit signed and unsigned in the hash (short and char are ok).
+ */
+
+ if (flags & BINARY_UNSIGNED) {
+ return Tcl_NewWideIntObj((Tcl_WideInt)(unsigned long)value);
+ }
+ if ((value & (((unsigned int)1)<<31)) && (value > 0)) {
+ value -= (((unsigned int)1)<<31);
+ value -= (((unsigned int)1)<<31);
+ }
+
+ returnNumericObject:
+ if (*numberCachePtrPtr == NULL) {
+ return Tcl_NewLongObj(value);
+ } else {
+ register Tcl_HashTable *tablePtr = *numberCachePtrPtr;
+ register Tcl_HashEntry *hPtr;
+ int isNew;
- if ((value & (((unsigned int)1)<<31)) && (value > 0)) {
- value -= (((unsigned int)1)<<31);
- value -= (((unsigned int)1)<<31);
+ hPtr = Tcl_CreateHashEntry(tablePtr, INT2PTR(value), &isNew);
+ if (!isNew) {
+ return (Tcl_Obj *) Tcl_GetHashValue(hPtr);
}
- returnNumericObject:
- if (*numberCachePtrPtr == NULL) {
- return Tcl_NewLongObj(value);
- } else {
- register Tcl_HashTable *tablePtr = *numberCachePtrPtr;
- register Tcl_HashEntry *hPtr;
- int isNew;
-
- hPtr = Tcl_CreateHashEntry(tablePtr, (char *)value, &isNew);
- if (!isNew) {
- return (Tcl_Obj *) Tcl_GetHashValue(hPtr);
- }
- if (tablePtr->numEntries > BINARY_SCAN_MAX_CACHE) {
- /*
- * We've overflowed the cache! Someone's parsing
- * a LOT of varied binary data in a single call!
- * Bail out by switching back to the old behaviour
- * for the rest of the scan.
- *
- * Note that anyone just using the 'c' conversion
- * (for bytes) cannot trigger this.
- */
- DeleteScanNumberCache(tablePtr);
- *numberCachePtrPtr = NULL;
- return Tcl_NewLongObj(value);
- } else {
- register Tcl_Obj *objPtr = Tcl_NewLongObj(value);
+ if (tablePtr->numEntries <= BINARY_SCAN_MAX_CACHE) {
+ register Tcl_Obj *objPtr = Tcl_NewLongObj(value);
- Tcl_IncrRefCount(objPtr);
- Tcl_SetHashValue(hPtr, (ClientData) objPtr);
- return objPtr;
- }
+ Tcl_IncrRefCount(objPtr);
+ Tcl_SetHashValue(hPtr, (ClientData) objPtr);
+ return objPtr;
}
/*
- * Do not cache wide values; they are already too large to
- * use as keys.
+ * We've overflowed the cache! Someone's parsing a LOT of varied
+ * binary data in a single call! Bail out by switching back to the
+ * old behaviour for the rest of the scan.
+ *
+ * Note that anyone just using the 'c' conversion (for bytes)
+ * cannot trigger this.
*/
- case 'w':
- uwvalue = ((Tcl_WideUInt) buffer[0])
+
+ DeleteScanNumberCache(tablePtr);
+ *numberCachePtrPtr = NULL;
+ return Tcl_NewLongObj(value);
+ }
+
+ /*
+ * Do not cache wide (64-bit) values; they are already too large to
+ * use as keys.
+ */
+
+ case 'w':
+ case 'W':
+ case 'm':
+ if (NeedReversing(type)) {
+ uwvalue = ((Tcl_WideUInt) buffer[0])
| (((Tcl_WideUInt) buffer[1]) << 8)
| (((Tcl_WideUInt) buffer[2]) << 16)
| (((Tcl_WideUInt) buffer[3]) << 24)
@@ -1696,9 +1950,8 @@ ScanNumber(buffer, type, numberCachePtrPtr)
| (((Tcl_WideUInt) buffer[5]) << 40)
| (((Tcl_WideUInt) buffer[6]) << 48)
| (((Tcl_WideUInt) buffer[7]) << 56);
- return Tcl_NewWideIntObj((Tcl_WideInt) uwvalue);
- case 'W':
- uwvalue = ((Tcl_WideUInt) buffer[7])
+ } else {
+ uwvalue = ((Tcl_WideUInt) buffer[7])
| (((Tcl_WideUInt) buffer[6]) << 8)
| (((Tcl_WideUInt) buffer[5]) << 16)
| (((Tcl_WideUInt) buffer[4]) << 24)
@@ -1706,23 +1959,42 @@ ScanNumber(buffer, type, numberCachePtrPtr)
| (((Tcl_WideUInt) buffer[2]) << 40)
| (((Tcl_WideUInt) buffer[1]) << 48)
| (((Tcl_WideUInt) buffer[0]) << 56);
- return Tcl_NewWideIntObj((Tcl_WideInt) uwvalue);
-
- /*
- * Do not cache double values; they are already too large
- * to use as keys and the values stored are utterly
- * incompatible too.
- */
- case 'f': {
- float fvalue;
- memcpy((VOID *) &fvalue, (VOID *) buffer, sizeof(float));
- return Tcl_NewDoubleObj(fvalue);
}
- case 'd': {
- double dvalue;
- memcpy((VOID *) &dvalue, (VOID *) buffer, sizeof(double));
- return Tcl_NewDoubleObj(dvalue);
+ if (flags & BINARY_UNSIGNED) {
+ Tcl_Obj *bigObj = NULL;
+ mp_int big;
+
+ TclBNInitBignumFromWideUInt(&big, uwvalue);
+ bigObj = Tcl_NewBignumObj(&big);
+ return bigObj;
}
+ return Tcl_NewWideIntObj((Tcl_WideInt) uwvalue);
+
+ /*
+ * Do not cache double values; they are already too large to use as
+ * keys and the values stored are utterly incompatible with the
+ * integer part of the cache.
+ */
+
+ /*
+ * 32-bit IEEE single-precision floating point.
+ */
+
+ case 'f':
+ case 'R':
+ case 'r':
+ CopyNumber(buffer, &fvalue, sizeof(float), type);
+ return Tcl_NewDoubleObj(fvalue);
+
+ /*
+ * 64-bit IEEE double-precision floating point.
+ */
+
+ case 'd':
+ case 'Q':
+ case 'q':
+ CopyNumber(buffer, &dvalue, sizeof(double), type);
+ return Tcl_NewDoubleObj(dvalue);
}
return NULL;
}
@@ -1731,7 +2003,7 @@ ScanNumber(buffer, type, numberCachePtrPtr)
*----------------------------------------------------------------------
*
* DeleteScanNumberCache --
- *
+ *
* Deletes the hash table acting as a scan number cache.
*
* Results:
@@ -1744,10 +2016,11 @@ ScanNumber(buffer, type, numberCachePtrPtr)
*/
static void
-DeleteScanNumberCache(numberCachePtr)
- Tcl_HashTable *numberCachePtr; /* Pointer to the hash table, or
- * NULL (when the cache has already
- * been deleted due to overflow.) */
+DeleteScanNumberCache(
+ Tcl_HashTable *numberCachePtr)
+ /* Pointer to the hash table, or NULL (when
+ * the cache has already been deleted due to
+ * overflow.) */
{
Tcl_HashEntry *hEntry;
Tcl_HashSearch search;
@@ -1758,7 +2031,7 @@ DeleteScanNumberCache(numberCachePtr)
hEntry = Tcl_FirstHashEntry(numberCachePtr, &search);
while (hEntry != NULL) {
- register Tcl_Obj *value = (Tcl_Obj *) Tcl_GetHashValue(hEntry);
+ register Tcl_Obj *value = Tcl_GetHashValue(hEntry);
if (value != NULL) {
Tcl_DecrRefCount(value);
@@ -1767,3 +2040,11 @@ DeleteScanNumberCache(numberCachePtr)
}
Tcl_DeleteHashTable(numberCachePtr);
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclCkalloc.c b/generic/tclCkalloc.c
index e81eaea..c374ce5 100644
--- a/generic/tclCkalloc.c
+++ b/generic/tclCkalloc.c
@@ -1,21 +1,21 @@
/*
* tclCkalloc.c --
*
- * Interface to malloc and free that provides support for debugging problems
- * involving overwritten, double freeing memory and loss of memory.
+ * Interface to malloc and free that provides support for debugging
+ * problems involving overwritten, double freeing memory and loss of
+ * memory.
*
* Copyright (c) 1991-1994 The Regents of the University of California.
* Copyright (c) 1994-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.
*
* This code contributed by Karl Lehenbauer and Mark Diekhans
*/
#include "tclInt.h"
-#include "tclPort.h"
#define FALSE 0
#define TRUE 1
@@ -28,29 +28,29 @@
*/
typedef struct MemTag {
- int refCount; /* Number of mem_headers referencing
- * this tag. */
- char string[4]; /* Actual size of string will be as
- * large as needed for actual tag. This
- * must be the last field in the structure. */
+ int refCount; /* Number of mem_headers referencing this
+ * tag. */
+ char string[4]; /* Actual size of string will be as large as
+ * needed for actual tag. This must be the
+ * last field in the structure. */
} MemTag;
#define TAG_SIZE(bytesInString) ((unsigned) sizeof(MemTag) + bytesInString - 3)
-static MemTag *curTagPtr = NULL;/* Tag to use in all future mem_headers
- * (set by "memory tag" command). */
+static MemTag *curTagPtr = NULL;/* Tag to use in all future mem_headers (set
+ * by "memory tag" command). */
/*
- * One of the following structures is allocated just before each
- * dynamically allocated chunk of memory, both to record information
- * about the chunk and to help detect chunk under-runs.
+ * One of the following structures is allocated just before each dynamically
+ * allocated chunk of memory, both to record information about the chunk and
+ * to help detect chunk under-runs.
*/
#define LOW_GUARD_SIZE (8 + (32 - (sizeof(long) + sizeof(int)))%8)
struct mem_header {
struct mem_header *flink;
struct mem_header *blink;
- MemTag *tagPtr; /* Tag from "memory tag" command; may be
+ MemTag *tagPtr; /* Tag from "memory tag" command; may be
* NULL. */
CONST char *file;
long length;
@@ -59,9 +59,8 @@ struct mem_header {
/* Aligns body on 8-byte boundary, plus
* provides at least 8 additional guard bytes
* to detect underruns. */
- char body[1]; /* First byte of client's space. Actual
- * size of this field will be larger than
- * one. */
+ char body[1]; /* First byte of client's space. Actual size
+ * of this field will be larger than one. */
};
static struct mem_header *allocHead = NULL; /* List of allocated structures */
@@ -69,16 +68,16 @@ static struct mem_header *allocHead = NULL; /* List of allocated structures */
#define GUARD_VALUE 0141
/*
- * The following macro determines the amount of guard space *above* each
- * chunk of memory.
+ * The following macro determines the amount of guard space *above* each chunk
+ * of memory.
*/
#define HIGH_GUARD_SIZE 8
/*
* The following macro computes the offset of the "body" field within
- * mem_header. It is used to get back to the header pointer from the
- * body pointer that's used by clients.
+ * mem_header. It is used to get back to the header pointer from the body
+ * pointer that's used by clients.
*/
#define BODY_OFFSET \
@@ -86,25 +85,25 @@ static struct mem_header *allocHead = NULL; /* List of allocated structures */
static int total_mallocs = 0;
static int total_frees = 0;
-static int current_bytes_malloced = 0;
-static int maximum_bytes_malloced = 0;
+static size_t current_bytes_malloced = 0;
+static size_t maximum_bytes_malloced = 0;
static int current_malloc_packets = 0;
static int maximum_malloc_packets = 0;
static int break_on_malloc = 0;
static int trace_on_at_malloc = 0;
-static int alloc_tracing = FALSE;
-static int init_malloced_bodies = TRUE;
+static int alloc_tracing = FALSE;
+static int init_malloced_bodies = TRUE;
#ifdef MEM_VALIDATE
- static int validate_memory = TRUE;
+static int validate_memory = TRUE;
#else
- static int validate_memory = FALSE;
+static int validate_memory = FALSE;
#endif
/*
- * The following variable indicates to TclFinalizeMemorySubsystem()
- * that it should dump out the state of memory before exiting. If the
- * value is non-NULL, it gives the name of the file in which to
- * dump memory usage information.
+ * The following variable indicates to TclFinalizeMemorySubsystem() that it
+ * should dump out the state of memory before exiting. If the value is
+ * non-NULL, it gives the name of the file in which to dump memory usage
+ * information.
*/
char *tclMemDumpFileName = NULL;
@@ -114,10 +113,11 @@ static char dumpFile[100]; /* Records where to dump memory allocation
* information. */
/*
- * Mutex to serialize allocations. This is a low-level mutex that must
- * be explicitly initialized. This is necessary because the self
- * initializing mutexes use ckalloc...
+ * Mutex to serialize allocations. This is a low-level mutex that must be
+ * explicitly initialized. This is necessary because the self initializing
+ * mutexes use ckalloc...
*/
+
static Tcl_Mutex *ckallocMutexPtr;
static int ckallocInit = 0;
@@ -125,26 +125,27 @@ static int ckallocInit = 0;
* Prototypes for procedures defined in this file:
*/
-static int CheckmemCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int argc, CONST char *argv[]));
-static int MemoryCmd _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int argc, CONST char **argv));
-static void ValidateMemory _ANSI_ARGS_((
- struct mem_header *memHeaderP, CONST char *file,
- int line, int nukeGuards));
+static int CheckmemCmd(ClientData clientData, Tcl_Interp *interp,
+ int argc, CONST char *argv[]);
+static int MemoryCmd(ClientData clientData, Tcl_Interp *interp,
+ int argc, CONST char *argv[]);
+static void ValidateMemory(struct mem_header *memHeaderP,
+ CONST char *file, int line, int nukeGuards);
/*
*----------------------------------------------------------------------
*
* TclInitDbCkalloc --
- * Initialize the locks used by the allocator.
- * This is only appropriate to call in a single threaded environment,
- * such as during TclInitSubsystems.
+ *
+ * Initialize the locks used by the allocator. This is only appropriate
+ * to call in a single threaded environment, such as during
+ * TclInitSubsystems.
*
*----------------------------------------------------------------------
*/
+
void
-TclInitDbCkalloc()
+TclInitDbCkalloc(void)
{
if (!ckallocInit) {
ckallocInit = 1;
@@ -156,29 +157,40 @@ TclInitDbCkalloc()
*----------------------------------------------------------------------
*
* TclDumpMemoryInfo --
- * Display the global memory management statistics.
+ *
+ * Display the global memory management statistics.
*
*----------------------------------------------------------------------
*/
-void
-TclDumpMemoryInfo(outFile)
- FILE *outFile;
+
+int
+TclDumpMemoryInfo(ClientData clientData, int flags)
{
- fprintf(outFile,"total mallocs %10d\n",
- total_mallocs);
- fprintf(outFile,"total frees %10d\n",
- total_frees);
- fprintf(outFile,"current packets allocated %10d\n",
- current_malloc_packets);
- fprintf(outFile,"current bytes allocated %10d\n",
- current_bytes_malloced);
- fprintf(outFile,"maximum packets allocated %10d\n",
- maximum_malloc_packets);
- fprintf(outFile,"maximum bytes allocated %10d\n",
- maximum_bytes_malloced);
+ char buf[1024];
+
+ if (clientData == NULL) { return 0; }
+ sprintf(buf,
+ "total mallocs %10d\n"
+ "total frees %10d\n"
+ "current packets allocated %10d\n"
+ "current bytes allocated %10lu\n"
+ "maximum packets allocated %10d\n"
+ "maximum bytes allocated %10lu\n",
+ total_mallocs,
+ total_frees,
+ current_malloc_packets,
+ (unsigned long)current_bytes_malloced,
+ maximum_malloc_packets,
+ (unsigned long)maximum_bytes_malloced);
+ if (flags == 0) {
+ fprintf((FILE *)clientData, buf);
+ } else {
+ /* Assume objPtr to append to */
+ Tcl_AppendToObj((Tcl_Obj *) clientData, buf, -1);
+ }
+ return 1;
}
-
/*
*----------------------------------------------------------------------
*
@@ -197,67 +209,68 @@ TclDumpMemoryInfo(outFile)
*/
static void
-ValidateMemory(memHeaderP, file, line, nukeGuards)
- struct mem_header *memHeaderP; /* Memory chunk to validate */
- CONST char *file; /* File containing the call to
- * Tcl_ValidateAllMemory */
- int line; /* Line number of call to
- * Tcl_ValidateAllMemory */
- int nukeGuards; /* If non-zero, indicates that the
- * memory guards are to be reset to 0
- * after they have been printed */
+ValidateMemory(
+ struct mem_header *memHeaderP,
+ /* Memory chunk to validate */
+ CONST char *file, /* File containing the call to
+ * Tcl_ValidateAllMemory */
+ int line, /* Line number of call to
+ * Tcl_ValidateAllMemory */
+ int nukeGuards) /* If non-zero, indicates that the memory
+ * guards are to be reset to 0 after they have
+ * been printed */
{
unsigned char *hiPtr;
- int idx;
- int guard_failed = FALSE;
+ size_t idx;
+ int guard_failed = FALSE;
int byte;
for (idx = 0; idx < LOW_GUARD_SIZE; idx++) {
- byte = *(memHeaderP->low_guard + idx);
- if (byte != GUARD_VALUE) {
- guard_failed = TRUE;
- fflush(stdout);
+ byte = *(memHeaderP->low_guard + idx);
+ if (byte != GUARD_VALUE) {
+ guard_failed = TRUE;
+ fflush(stdout);
byte &= 0xff;
- fprintf(stderr, "low guard byte %d is 0x%x \t%c\n", idx, byte,
+ fprintf(stderr, "low guard byte %d is 0x%x \t%c\n", (int)idx, byte,
(isprint(UCHAR(byte)) ? byte : ' ')); /* INTL: bytes */
- }
+ }
}
if (guard_failed) {
- TclDumpMemoryInfo (stderr);
- fprintf(stderr, "low guard failed at %lx, %s %d\n",
- (long unsigned int) memHeaderP->body, file, line);
- fflush(stderr); /* In case name pointer is bad. */
- fprintf(stderr, "%ld bytes allocated at (%s %d)\n", memHeaderP->length,
+ TclDumpMemoryInfo((ClientData) stderr, 0);
+ fprintf(stderr, "low guard failed at %lx, %s %d\n",
+ (long unsigned int) memHeaderP->body, file, line);
+ fflush(stderr); /* In case name pointer is bad. */
+ fprintf(stderr, "%ld bytes allocated at (%s %d)\n", memHeaderP->length,
memHeaderP->file, memHeaderP->line);
- panic ("Memory validation failure");
+ Tcl_Panic("Memory validation failure");
}
hiPtr = (unsigned char *)memHeaderP->body + memHeaderP->length;
for (idx = 0; idx < HIGH_GUARD_SIZE; idx++) {
- byte = *(hiPtr + idx);
- if (byte != GUARD_VALUE) {
- guard_failed = TRUE;
- fflush (stdout);
+ byte = *(hiPtr + idx);
+ if (byte != GUARD_VALUE) {
+ guard_failed = TRUE;
+ fflush(stdout);
byte &= 0xff;
- fprintf(stderr, "hi guard byte %d is 0x%x \t%c\n", idx, byte,
+ fprintf(stderr, "hi guard byte %d is 0x%x \t%c\n", (int)idx, byte,
(isprint(UCHAR(byte)) ? byte : ' ')); /* INTL: bytes */
- }
+ }
}
if (guard_failed) {
- TclDumpMemoryInfo (stderr);
- fprintf(stderr, "high guard failed at %lx, %s %d\n",
- (long unsigned int) memHeaderP->body, file, line);
- fflush(stderr); /* In case name pointer is bad. */
- fprintf(stderr, "%ld bytes allocated at (%s %d)\n",
+ TclDumpMemoryInfo((ClientData) stderr, 0);
+ fprintf(stderr, "high guard failed at %lx, %s %d\n",
+ (long unsigned int) memHeaderP->body, file, line);
+ fflush(stderr); /* In case name pointer is bad. */
+ fprintf(stderr, "%ld bytes allocated at (%s %d)\n",
memHeaderP->length, memHeaderP->file,
memHeaderP->line);
- panic("Memory validation failure");
+ Tcl_Panic("Memory validation failure");
}
if (nukeGuards) {
- memset ((char *) memHeaderP->low_guard, 0, LOW_GUARD_SIZE);
- memset ((char *) hiPtr, 0, HIGH_GUARD_SIZE);
+ memset(memHeaderP->low_guard, 0, LOW_GUARD_SIZE);
+ memset(hiPtr, 0, HIGH_GUARD_SIZE);
}
}
@@ -277,10 +290,13 @@ ValidateMemory(memHeaderP, file, line, nukeGuards)
*
*----------------------------------------------------------------------
*/
+
void
-Tcl_ValidateAllMemory (file, line)
- CONST char *file; /* File from which Tcl_ValidateAllMemory was called */
- int line; /* Line number of call to Tcl_ValidateAllMemory */
+Tcl_ValidateAllMemory(
+ CONST char *file, /* File from which Tcl_ValidateAllMemory was
+ * called. */
+ int line) /* Line number of call to
+ * Tcl_ValidateAllMemory */
{
struct mem_header *memScanP;
@@ -289,7 +305,7 @@ Tcl_ValidateAllMemory (file, line)
}
Tcl_MutexLock(ckallocMutexPtr);
for (memScanP = allocHead; memScanP != NULL; memScanP = memScanP->flink) {
- ValidateMemory(memScanP, file, line, FALSE);
+ ValidateMemory(memScanP, file, line, FALSE);
}
Tcl_MutexUnlock(ckallocMutexPtr);
}
@@ -303,17 +319,19 @@ Tcl_ValidateAllMemory (file, line)
* information will be written to stderr.
*
* Results:
- * Return TCL_ERROR if an error accessing the file occurs, `errno'
- * will have the file error number left in it.
+ * Return TCL_ERROR if an error accessing the file occurs, `errno' will
+ * have the file error number left in it.
+ *
*----------------------------------------------------------------------
*/
+
int
-Tcl_DumpActiveMemory (fileName)
- CONST char *fileName; /* Name of the file to write info to */
+Tcl_DumpActiveMemory(
+ CONST char *fileName) /* Name of the file to write info to */
{
- FILE *fileP;
+ FILE *fileP;
struct mem_header *memScanP;
- char *address;
+ char *address;
if (fileName == NULL) {
fileP = stderr;
@@ -326,18 +344,18 @@ Tcl_DumpActiveMemory (fileName)
Tcl_MutexLock(ckallocMutexPtr);
for (memScanP = allocHead; memScanP != NULL; memScanP = memScanP->flink) {
- address = &memScanP->body [0];
- fprintf(fileP, "%8lx - %8lx %7ld @ %s %d %s",
+ address = &memScanP->body [0];
+ fprintf(fileP, "%8lx - %8lx %7ld @ %s %d %s",
(long unsigned int) address,
- (long unsigned int) address + memScanP->length - 1,
- memScanP->length, memScanP->file, memScanP->line,
- (memScanP->tagPtr == NULL) ? "" : memScanP->tagPtr->string);
+ (long unsigned int) address + memScanP->length - 1,
+ memScanP->length, memScanP->file, memScanP->line,
+ (memScanP->tagPtr == NULL) ? "" : memScanP->tagPtr->string);
(void) fputc('\n', fileP);
}
Tcl_MutexUnlock(ckallocMutexPtr);
if (fileP != stderr) {
- fclose (fileP);
+ fclose(fileP);
}
return TCL_OK;
}
@@ -347,53 +365,54 @@ Tcl_DumpActiveMemory (fileName)
*
* Tcl_DbCkalloc - debugging ckalloc
*
- * Allocate the requested amount of space plus some extra for
- * guard bands at both ends of the request, plus a size, panicing
- * if there isn't enough space, then write in the guard bands
- * and return the address of the space in the middle that the
- * user asked for.
+ * Allocate the requested amount of space plus some extra for guard bands
+ * at both ends of the request, plus a size, panicing if there isn't
+ * enough space, then write in the guard bands and return the address of
+ * the space in the middle that the user asked for.
*
- * The second and third arguments are file and line, these contain
- * the filename and line number corresponding to the caller.
- * These are sent by the ckalloc macro; it uses the preprocessor
- * autodefines __FILE__ and __LINE__.
+ * The second and third arguments are file and line, these contain the
+ * filename and line number corresponding to the caller. These are sent
+ * by the ckalloc macro; it uses the preprocessor autodefines __FILE__
+ * and __LINE__.
*
*----------------------------------------------------------------------
*/
+
char *
-Tcl_DbCkalloc(size, file, line)
- unsigned int size;
- CONST char *file;
- int line;
+Tcl_DbCkalloc(
+ unsigned int size,
+ CONST char *file,
+ int line)
{
struct mem_header *result = NULL;
- if (validate_memory)
- Tcl_ValidateAllMemory (file, line);
-
+ if (validate_memory) {
+ Tcl_ValidateAllMemory(file, line);
+ }
/* Don't let size argument to TclpAlloc overflow */
- if (size <= UINT_MAX - HIGH_GUARD_SIZE - sizeof(struct mem_header)) {
+ if (size <= UINT_MAX - HIGH_GUARD_SIZE -sizeof(struct mem_header)) {
result = (struct mem_header *) TclpAlloc((unsigned)size +
sizeof(struct mem_header) + HIGH_GUARD_SIZE);
}
if (result == NULL) {
- fflush(stdout);
- TclDumpMemoryInfo(stderr);
- panic("unable to alloc %u bytes, %s line %d", size, file, line);
+ fflush(stdout);
+ TclDumpMemoryInfo((ClientData) stderr, 0);
+ Tcl_Panic("unable to alloc %u bytes, %s line %d", size, file, line);
}
/*
- * Fill in guard zones and size. Also initialize the contents of
- * the block with bogus bytes to detect uses of initialized data.
- * Link into allocated list.
+ * Fill in guard zones and size. Also initialize the contents of the block
+ * with bogus bytes to detect uses of initialized data. Link into
+ * allocated list.
*/
+
if (init_malloced_bodies) {
- memset ((VOID *) result, GUARD_VALUE,
+ memset(result, GUARD_VALUE,
size + sizeof(struct mem_header) + HIGH_GUARD_SIZE);
} else {
- memset ((char *) result->low_guard, GUARD_VALUE, LOW_GUARD_SIZE);
- memset (result->body + size, GUARD_VALUE, HIGH_GUARD_SIZE);
+ memset(result->low_guard, GUARD_VALUE, LOW_GUARD_SIZE);
+ memset(result->body + size, GUARD_VALUE, HIGH_GUARD_SIZE);
}
if (!ckallocInit) {
TclInitDbCkalloc();
@@ -409,56 +428,61 @@ Tcl_DbCkalloc(size, file, line)
result->flink = allocHead;
result->blink = NULL;
- if (allocHead != NULL)
- allocHead->blink = result;
+ if (allocHead != NULL) {
+ allocHead->blink = result;
+ }
allocHead = result;
total_mallocs++;
if (trace_on_at_malloc && (total_mallocs >= trace_on_at_malloc)) {
- (void) fflush(stdout);
- fprintf(stderr, "reached malloc trace enable point (%d)\n",
- total_mallocs);
- fflush(stderr);
- alloc_tracing = TRUE;
- trace_on_at_malloc = 0;
+ (void) fflush(stdout);
+ fprintf(stderr, "reached malloc trace enable point (%d)\n",
+ total_mallocs);
+ fflush(stderr);
+ alloc_tracing = TRUE;
+ trace_on_at_malloc = 0;
}
- if (alloc_tracing)
- fprintf(stderr,"ckalloc %lx %u %s %d\n",
+ if (alloc_tracing) {
+ fprintf(stderr,"ckalloc %lx %u %s %d\n",
(long unsigned int) result->body, size, file, line);
+ }
if (break_on_malloc && (total_mallocs >= break_on_malloc)) {
- break_on_malloc = 0;
- (void) fflush(stdout);
- fprintf(stderr,"reached malloc break limit (%d)\n",
- total_mallocs);
- fprintf(stderr, "program will now enter C debugger\n");
- (void) fflush(stderr);
+ break_on_malloc = 0;
+ (void) fflush(stdout);
+ fprintf(stderr,"reached malloc break limit (%d)\n",
+ total_mallocs);
+ fprintf(stderr, "program will now enter C debugger\n");
+ (void) fflush(stderr);
abort();
}
current_malloc_packets++;
- if (current_malloc_packets > maximum_malloc_packets)
- maximum_malloc_packets = current_malloc_packets;
+ if (current_malloc_packets > maximum_malloc_packets) {
+ maximum_malloc_packets = current_malloc_packets;
+ }
current_bytes_malloced += size;
- if (current_bytes_malloced > maximum_bytes_malloced)
- maximum_bytes_malloced = current_bytes_malloced;
+ if (current_bytes_malloced > maximum_bytes_malloced) {
+ maximum_bytes_malloced = current_bytes_malloced;
+ }
Tcl_MutexUnlock(ckallocMutexPtr);
return result->body;
}
-
+
char *
-Tcl_AttemptDbCkalloc(size, file, line)
- unsigned int size;
- CONST char *file;
- int line;
+Tcl_AttemptDbCkalloc(
+ unsigned int size,
+ CONST char *file,
+ int line)
{
struct mem_header *result = NULL;
- if (validate_memory)
- Tcl_ValidateAllMemory (file, line);
+ if (validate_memory) {
+ Tcl_ValidateAllMemory(file, line);
+ }
/* Don't let size argument to TclpAlloc overflow */
if (size <= UINT_MAX - HIGH_GUARD_SIZE - sizeof(struct mem_header)) {
@@ -466,22 +490,22 @@ Tcl_AttemptDbCkalloc(size, file, line)
sizeof(struct mem_header) + HIGH_GUARD_SIZE);
}
if (result == NULL) {
- fflush(stdout);
- TclDumpMemoryInfo(stderr);
+ fflush(stdout);
+ TclDumpMemoryInfo((ClientData) stderr, 0);
return NULL;
}
/*
- * Fill in guard zones and size. Also initialize the contents of
- * the block with bogus bytes to detect uses of initialized data.
- * Link into allocated list.
+ * Fill in guard zones and size. Also initialize the contents of the block
+ * with bogus bytes to detect uses of initialized data. Link into
+ * allocated list.
*/
if (init_malloced_bodies) {
- memset ((VOID *) result, GUARD_VALUE,
+ memset(result, GUARD_VALUE,
size + sizeof(struct mem_header) + HIGH_GUARD_SIZE);
} else {
- memset ((char *) result->low_guard, GUARD_VALUE, LOW_GUARD_SIZE);
- memset (result->body + size, GUARD_VALUE, HIGH_GUARD_SIZE);
+ memset(result->low_guard, GUARD_VALUE, LOW_GUARD_SIZE);
+ memset(result->body + size, GUARD_VALUE, HIGH_GUARD_SIZE);
}
if (!ckallocInit) {
TclInitDbCkalloc();
@@ -497,71 +521,73 @@ Tcl_AttemptDbCkalloc(size, file, line)
result->flink = allocHead;
result->blink = NULL;
- if (allocHead != NULL)
- allocHead->blink = result;
+ if (allocHead != NULL) {
+ allocHead->blink = result;
+ }
allocHead = result;
total_mallocs++;
if (trace_on_at_malloc && (total_mallocs >= trace_on_at_malloc)) {
- (void) fflush(stdout);
- fprintf(stderr, "reached malloc trace enable point (%d)\n",
- total_mallocs);
- fflush(stderr);
- alloc_tracing = TRUE;
- trace_on_at_malloc = 0;
+ (void) fflush(stdout);
+ fprintf(stderr, "reached malloc trace enable point (%d)\n",
+ total_mallocs);
+ fflush(stderr);
+ alloc_tracing = TRUE;
+ trace_on_at_malloc = 0;
}
- if (alloc_tracing)
- fprintf(stderr,"ckalloc %lx %u %s %d\n",
+ if (alloc_tracing) {
+ fprintf(stderr,"ckalloc %lx %u %s %d\n",
(long unsigned int) result->body, size, file, line);
+ }
if (break_on_malloc && (total_mallocs >= break_on_malloc)) {
- break_on_malloc = 0;
- (void) fflush(stdout);
- fprintf(stderr,"reached malloc break limit (%d)\n",
- total_mallocs);
- fprintf(stderr, "program will now enter C debugger\n");
- (void) fflush(stderr);
+ break_on_malloc = 0;
+ (void) fflush(stdout);
+ fprintf(stderr,"reached malloc break limit (%d)\n",
+ total_mallocs);
+ fprintf(stderr, "program will now enter C debugger\n");
+ (void) fflush(stderr);
abort();
}
current_malloc_packets++;
- if (current_malloc_packets > maximum_malloc_packets)
- maximum_malloc_packets = current_malloc_packets;
+ if (current_malloc_packets > maximum_malloc_packets) {
+ maximum_malloc_packets = current_malloc_packets;
+ }
current_bytes_malloced += size;
- if (current_bytes_malloced > maximum_bytes_malloced)
- maximum_bytes_malloced = current_bytes_malloced;
+ if (current_bytes_malloced > maximum_bytes_malloced) {
+ maximum_bytes_malloced = current_bytes_malloced;
+ }
Tcl_MutexUnlock(ckallocMutexPtr);
return result->body;
}
-
/*
*----------------------------------------------------------------------
*
* Tcl_DbCkfree - debugging ckfree
*
- * Verify that the low and high guards are intact, and if so
- * then free the buffer else panic.
+ * Verify that the low and high guards are intact, and if so then free
+ * the buffer else Tcl_Panic.
*
- * The guards are erased after being checked to catch duplicate
- * frees.
+ * The guards are erased after being checked to catch duplicate frees.
*
- * The second and third arguments are file and line, these contain
- * the filename and line number corresponding to the caller.
- * These are sent by the ckfree macro; it uses the preprocessor
- * autodefines __FILE__ and __LINE__.
+ * The second and third arguments are file and line, these contain the
+ * filename and line number corresponding to the caller. These are sent
+ * by the ckfree macro; it uses the preprocessor autodefines __FILE__ and
+ * __LINE__.
*
*----------------------------------------------------------------------
*/
int
-Tcl_DbCkfree(ptr, file, line)
- char *ptr;
- CONST char *file;
- int line;
+Tcl_DbCkfree(
+ char *ptr,
+ CONST char *file,
+ int line)
{
struct mem_header *memp;
@@ -570,28 +596,28 @@ Tcl_DbCkfree(ptr, file, line)
}
/*
- * The following cast is *very* tricky. Must convert the pointer
- * to an integer before doing arithmetic on it, because otherwise
- * the arithmetic will be done differently (and incorrectly) on
- * word-addressed machines such as Crays (will subtract only bytes,
- * even though BODY_OFFSET is in words on these machines).
+ * The following cast is *very* tricky. Must convert the pointer to an
+ * integer before doing arithmetic on it, because otherwise the arithmetic
+ * will be done differently (and incorrectly) on word-addressed machines
+ * such as Crays (will subtract only bytes, even though BODY_OFFSET is in
+ * words on these machines).
*/
memp = (struct mem_header *) (((size_t) ptr) - BODY_OFFSET);
if (alloc_tracing) {
- fprintf(stderr, "ckfree %lx %ld %s %d\n",
+ fprintf(stderr, "ckfree %lx %ld %s %d\n",
(long unsigned int) memp->body, memp->length, file, line);
}
if (validate_memory) {
- Tcl_ValidateAllMemory(file, line);
+ Tcl_ValidateAllMemory(file, line);
}
Tcl_MutexLock(ckallocMutexPtr);
ValidateMemory(memp, file, line, TRUE);
if (init_malloced_bodies) {
- memset((VOID *) ptr, GUARD_VALUE, (size_t) memp->length);
+ memset(ptr, GUARD_VALUE, (size_t) memp->length);
}
total_frees++;
@@ -608,12 +634,16 @@ Tcl_DbCkfree(ptr, file, line)
/*
* Delink from allocated list
*/
- if (memp->flink != NULL)
- memp->flink->blink = memp->blink;
- if (memp->blink != NULL)
- memp->blink->flink = memp->flink;
- if (allocHead == memp)
- allocHead = memp->flink;
+
+ if (memp->flink != NULL) {
+ memp->flink->blink = memp->blink;
+ }
+ if (memp->blink != NULL) {
+ memp->blink->flink = memp->flink;
+ }
+ if (allocHead == memp) {
+ allocHead = memp->flink;
+ }
TclpFree((char *) memp);
Tcl_MutexUnlock(ckallocMutexPtr);
@@ -625,21 +655,22 @@ Tcl_DbCkfree(ptr, file, line)
*
* Tcl_DbCkrealloc - debugging ckrealloc
*
- * Reallocate a chunk of memory by allocating a new one of the
- * right size, copying the old data to the new location, and then
- * freeing the old memory space, using all the memory checking
- * features of this package.
+ * Reallocate a chunk of memory by allocating a new one of the right
+ * size, copying the old data to the new location, and then freeing the
+ * old memory space, using all the memory checking features of this
+ * package.
*
*--------------------------------------------------------------------
*/
+
char *
-Tcl_DbCkrealloc(ptr, size, file, line)
- char *ptr;
- unsigned int size;
- CONST char *file;
- int line;
+Tcl_DbCkrealloc(
+ char *ptr,
+ unsigned int size,
+ CONST char *file,
+ int line)
{
- char *new;
+ char *newPtr;
unsigned int copySize;
struct mem_header *memp;
@@ -648,8 +679,7 @@ Tcl_DbCkrealloc(ptr, size, file, line)
}
/*
- * See comment from Tcl_DbCkfree before you change the following
- * line.
+ * See comment from Tcl_DbCkfree before you change the following line.
*/
memp = (struct mem_header *) (((size_t) ptr) - BODY_OFFSET);
@@ -658,20 +688,20 @@ Tcl_DbCkrealloc(ptr, size, file, line)
if (copySize > (unsigned int) memp->length) {
copySize = memp->length;
}
- new = Tcl_DbCkalloc(size, file, line);
- memcpy((VOID *) new, (VOID *) ptr, (size_t) copySize);
+ newPtr = Tcl_DbCkalloc(size, file, line);
+ memcpy(newPtr, ptr, (size_t) copySize);
Tcl_DbCkfree(ptr, file, line);
- return new;
+ return newPtr;
}
-
+
char *
-Tcl_AttemptDbCkrealloc(ptr, size, file, line)
- char *ptr;
- unsigned int size;
- CONST char *file;
- int line;
+Tcl_AttemptDbCkrealloc(
+ char *ptr,
+ unsigned int size,
+ CONST char *file,
+ int line)
{
- char *new;
+ char *newPtr;
unsigned int copySize;
struct mem_header *memp;
@@ -680,8 +710,7 @@ Tcl_AttemptDbCkrealloc(ptr, size, file, line)
}
/*
- * See comment from Tcl_DbCkfree before you change the following
- * line.
+ * See comment from Tcl_DbCkfree before you change the following line.
*/
memp = (struct mem_header *) (((size_t) ptr) - BODY_OFFSET);
@@ -690,13 +719,13 @@ Tcl_AttemptDbCkrealloc(ptr, size, file, line)
if (copySize > (unsigned int) memp->length) {
copySize = memp->length;
}
- new = Tcl_AttemptDbCkalloc(size, file, line);
- if (new == NULL) {
+ newPtr = Tcl_AttemptDbCkalloc(size, file, line);
+ if (newPtr == NULL) {
return NULL;
}
- memcpy((VOID *) new, (VOID *) ptr, (size_t) copySize);
+ memcpy(newPtr, ptr, (size_t) copySize);
Tcl_DbCkfree(ptr, file, line);
- return new;
+ return newPtr;
}
@@ -705,8 +734,8 @@ Tcl_AttemptDbCkrealloc(ptr, size, file, line)
*
* Tcl_Alloc, et al. --
*
- * These functions are defined in terms of the debugging versions
- * when TCL_MEM_DEBUG is set.
+ * These functions are defined in terms of the debugging versions when
+ * TCL_MEM_DEBUG is set.
*
* Results:
* Same as the debug versions.
@@ -724,37 +753,37 @@ Tcl_AttemptDbCkrealloc(ptr, size, file, line)
#undef Tcl_AttemptRealloc
char *
-Tcl_Alloc(size)
- unsigned int size;
+Tcl_Alloc(
+ unsigned int size)
{
return Tcl_DbCkalloc(size, "unknown", 0);
}
char *
-Tcl_AttemptAlloc(size)
- unsigned int size;
+Tcl_AttemptAlloc(
+ unsigned int size)
{
return Tcl_AttemptDbCkalloc(size, "unknown", 0);
}
void
-Tcl_Free(ptr)
- char *ptr;
+Tcl_Free(
+ char *ptr)
{
Tcl_DbCkfree(ptr, "unknown", 0);
}
char *
-Tcl_Realloc(ptr, size)
- char *ptr;
- unsigned int size;
+Tcl_Realloc(
+ char *ptr,
+ unsigned int size)
{
return Tcl_DbCkrealloc(ptr, size, "unknown", 0);
}
char *
-Tcl_AttemptRealloc(ptr, size)
- char *ptr;
- unsigned int size;
+Tcl_AttemptRealloc(
+ char *ptr,
+ unsigned int size)
{
return Tcl_AttemptDbCkrealloc(ptr, size, "unknown", 0);
}
@@ -763,8 +792,9 @@ Tcl_AttemptRealloc(ptr, size)
*----------------------------------------------------------------------
*
* MemoryCmd --
- * Implements the Tcl "memory" command, which provides Tcl-level
- * control of Tcl memory debugging information.
+ *
+ * Implements the Tcl "memory" command, which provides Tcl-level control
+ * of Tcl memory debugging information.
* memory active $file
* memory break_on_malloc $count
* memory info
@@ -776,33 +806,34 @@ Tcl_AttemptRealloc(ptr, size)
* memory validate on|off
*
* Results:
- * Standard TCL results.
+ * Standard TCL results.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
static int
-MemoryCmd (clientData, interp, argc, argv)
- ClientData clientData;
- Tcl_Interp *interp;
- int argc;
- CONST char **argv;
+MemoryCmd(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int argc,
+ CONST char *argv[])
{
CONST char *fileName;
+ FILE *fileP;
Tcl_DString buffer;
int result;
size_t len;
if (argc < 2) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " option [args..]\"", (char *) NULL);
+ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+ " option [args..]\"", NULL);
return TCL_ERROR;
}
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\"", (char *) NULL);
+ if (argc != 3) {
+ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+ " ", argv[1], " file\"", NULL);
return TCL_ERROR;
}
fileName = Tcl_TranslateFileName(interp, argv[2], &buffer);
@@ -812,43 +843,61 @@ MemoryCmd (clientData, interp, argc, argv)
result = Tcl_DumpActiveMemory (fileName);
Tcl_DStringFree(&buffer);
if (result != TCL_OK) {
- Tcl_AppendResult(interp, "error accessing ", argv[2],
- (char *) NULL);
+ Tcl_AppendResult(interp, "error accessing ", argv[2], NULL);
return TCL_ERROR;
}
return TCL_OK;
}
if (strcmp(argv[1],"break_on_malloc") == 0) {
- if (argc != 3) {
- goto argError;
+ if (argc != 3) {
+ goto argError;
}
- if (Tcl_GetInt(interp, argv[2], &break_on_malloc) != TCL_OK) {
+ if (Tcl_GetInt(interp, argv[2], &break_on_malloc) != TCL_OK) {
return TCL_ERROR;
}
- return TCL_OK;
+ return TCL_OK;
}
if (strcmp(argv[1],"info") == 0) {
- char buf[400];
- sprintf(buf, "%-25s %10d\n%-25s %10d\n%-25s %10d\n%-25s %10d\n%-25s %10d\n%-25s %10d\n",
- "total mallocs", total_mallocs, "total frees", total_frees,
- "current packets allocated", current_malloc_packets,
- "current bytes allocated", current_bytes_malloced,
- "maximum packets allocated", maximum_malloc_packets,
- "maximum bytes allocated", maximum_bytes_malloced);
- Tcl_SetResult(interp, buf, TCL_VOLATILE);
- return TCL_OK;
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "%-25s %10d\n%-25s %10d\n%-25s %10d\n%-25s %10lu\n%-25s %10d\n%-25s %10lu\n",
+ "total mallocs", total_mallocs, "total frees", total_frees,
+ "current packets allocated", current_malloc_packets,
+ "current bytes allocated", current_bytes_malloced,
+ "maximum packets allocated", maximum_malloc_packets,
+ "maximum bytes allocated", maximum_bytes_malloced));
+ return TCL_OK;
}
if (strcmp(argv[1],"init") == 0) {
- if (argc != 3) {
- goto bad_suboption;
+ if (argc != 3) {
+ goto bad_suboption;
+ }
+ init_malloced_bodies = (strcmp(argv[2],"on") == 0);
+ return TCL_OK;
+ }
+ if (strcmp(argv[1],"objs") == 0) {
+ if (argc != 3) {
+ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+ " objs file\"", NULL);
+ return TCL_ERROR;
+ }
+ fileName = Tcl_TranslateFileName(interp, argv[2], &buffer);
+ if (fileName == NULL) {
+ return TCL_ERROR;
+ }
+ fileP = fopen(fileName, "w");
+ if (fileP == NULL) {
+ Tcl_AppendResult(interp, "cannot open output file", NULL);
+ return TCL_ERROR;
}
- init_malloced_bodies = (strcmp(argv[2],"on") == 0);
- return TCL_OK;
+ TclDbDumpActiveObjects(fileP);
+ fclose(fileP);
+ Tcl_DStringFree(&buffer);
+ return TCL_OK;
}
if (strcmp(argv[1],"onexit") == 0) {
- if (argc != 3) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- argv[0], " onexit file\"", (char *) NULL);
+ if (argc != 3) {
+ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+ " onexit file\"", NULL);
return TCL_ERROR;
}
fileName = Tcl_TranslateFileName(interp, argv[2], &buffer);
@@ -863,7 +912,7 @@ MemoryCmd (clientData, interp, argc, argv)
if (strcmp(argv[1],"tag") == 0) {
if (argc != 3) {
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " tag string\"", (char *) NULL);
+ " tag string\"", NULL);
return TCL_ERROR;
}
if ((curTagPtr != NULL) && (curTagPtr->refCount == 0)) {
@@ -876,43 +925,43 @@ MemoryCmd (clientData, interp, argc, argv)
return TCL_OK;
}
if (strcmp(argv[1],"trace") == 0) {
- if (argc != 3) {
- goto bad_suboption;
+ if (argc != 3) {
+ goto bad_suboption;
}
- alloc_tracing = (strcmp(argv[2],"on") == 0);
- return TCL_OK;
+ alloc_tracing = (strcmp(argv[2],"on") == 0);
+ return TCL_OK;
}
if (strcmp(argv[1],"trace_on_at_malloc") == 0) {
- if (argc != 3) {
- goto argError;
+ if (argc != 3) {
+ goto argError;
}
- if (Tcl_GetInt(interp, argv[2], &trace_on_at_malloc) != TCL_OK) {
+ if (Tcl_GetInt(interp, argv[2], &trace_on_at_malloc) != TCL_OK) {
return TCL_ERROR;
}
return TCL_OK;
}
if (strcmp(argv[1],"validate") == 0) {
- if (argc != 3) {
+ if (argc != 3) {
goto bad_suboption;
}
- validate_memory = (strcmp(argv[2],"on") == 0);
- return TCL_OK;
+ validate_memory = (strcmp(argv[2],"on") == 0);
+ return TCL_OK;
}
Tcl_AppendResult(interp, "bad option \"", argv[1],
- "\": should be active, break_on_malloc, info, init, onexit, ",
- "tag, trace, trace_on_at_malloc, or validate", (char *) NULL);
+ "\": should be active, break_on_malloc, info, init, onexit, "
+ "tag, trace, trace_on_at_malloc, or validate", NULL);
return TCL_ERROR;
-argError:
+ argError:
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " ", argv[1], " count\"", (char *) NULL);
+ " ", argv[1], " count\"", NULL);
return TCL_ERROR;
-bad_suboption:
+ bad_suboption:
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " ", argv[1], " on|off\"", (char *) NULL);
+ " ", argv[1], " on|off\"", NULL);
return TCL_ERROR;
}
@@ -921,10 +970,9 @@ bad_suboption:
*
* CheckmemCmd --
*
- * This is the command procedure for the "checkmem" command, which
- * causes the application to exit after printing information about
- * memory usage to the file passed to this command as its first
- * argument.
+ * This is the command procedure for the "checkmem" command, which causes
+ * the application to exit after printing information about memory usage
+ * to the file passed to this command as its first argument.
*
* Results:
* Returns a standard Tcl completion code.
@@ -936,15 +984,15 @@ bad_suboption:
*/
static int
-CheckmemCmd(clientData, interp, argc, argv)
- ClientData clientData; /* Not used. */
- Tcl_Interp *interp; /* Interpreter for evaluation. */
- int argc; /* Number of arguments. */
- CONST char *argv[]; /* String values of arguments. */
+CheckmemCmd(
+ ClientData clientData, /* Not used. */
+ Tcl_Interp *interp, /* Interpreter for evaluation. */
+ int argc, /* Number of arguments. */
+ CONST char *argv[]) /* String values of arguments. */
{
if (argc != 2) {
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
- " fileName\"", (char *) NULL);
+ " fileName\"", NULL);
return TCL_ERROR;
}
tclMemDumpFileName = dumpFile;
@@ -957,8 +1005,7 @@ CheckmemCmd(clientData, interp, argc, argv)
*
* Tcl_InitMemory --
*
- * Create the "memory" and "checkmem" commands in the given
- * interpreter.
+ * Create the "memory" and "checkmem" commands in the given interpreter.
*
* Results:
* None.
@@ -970,14 +1017,13 @@ CheckmemCmd(clientData, interp, argc, argv)
*/
void
-Tcl_InitMemory(interp)
- Tcl_Interp *interp; /* Interpreter in which commands should be added */
+Tcl_InitMemory(
+ Tcl_Interp *interp) /* Interpreter in which commands should be
+ * added */
{
TclInitDbCkalloc();
- Tcl_CreateCommand (interp, "memory", MemoryCmd, (ClientData) NULL,
- (Tcl_CmdDeleteProc *) NULL);
- Tcl_CreateCommand(interp, "checkmem", CheckmemCmd, (ClientData) 0,
- (Tcl_CmdDeleteProc *) NULL);
+ Tcl_CreateCommand(interp, "memory", MemoryCmd, (ClientData) NULL, NULL);
+ Tcl_CreateCommand(interp, "checkmem", CheckmemCmd, (ClientData) 0, NULL);
}
@@ -994,47 +1040,50 @@ Tcl_InitMemory(interp)
*----------------------------------------------------------------------
*
* Tcl_Alloc --
- * Interface to TclpAlloc when TCL_MEM_DEBUG is disabled. It does check
- * that memory was actually allocated.
+ *
+ * Interface to TclpAlloc when TCL_MEM_DEBUG is disabled. It does check
+ * that memory was actually allocated.
*
*----------------------------------------------------------------------
*/
char *
-Tcl_Alloc (size)
- unsigned int size;
+Tcl_Alloc(
+ unsigned int size)
{
char *result;
result = TclpAlloc(size);
+
/*
- * Most systems will not alloc(0), instead bumping it to one so
- * that NULL isn't returned. Some systems (AIX, Tru64) will alloc(0)
- * by returning NULL, so we have to check that the NULL we get is
- * not in response to alloc(0).
+ * Most systems will not alloc(0), instead bumping it to one so that NULL
+ * isn't returned. Some systems (AIX, Tru64) will alloc(0) by returning
+ * NULL, so we have to check that the NULL we get is not in response to
+ * alloc(0).
*
- * The ANSI spec actually says that systems either return NULL *or*
- * a special pointer on failure, but we only check for NULL
+ * The ANSI spec actually says that systems either return NULL *or* a
+ * special pointer on failure, but we only check for NULL
*/
+
if ((result == NULL) && size) {
- panic("unable to alloc %u bytes", size);
+ Tcl_Panic("unable to alloc %u bytes", size);
}
return result;
}
char *
-Tcl_DbCkalloc(size, file, line)
- unsigned int size;
- CONST char *file;
- int line;
+Tcl_DbCkalloc(
+ unsigned int size,
+ CONST char *file,
+ int line)
{
char *result;
result = (char *) TclpAlloc(size);
if ((result == NULL) && size) {
- fflush(stdout);
- panic("unable to alloc %u bytes, %s line %d", size, file, line);
+ fflush(stdout);
+ Tcl_Panic("unable to alloc %u bytes, %s line %d", size, file, line);
}
return result;
}
@@ -1043,15 +1092,16 @@ Tcl_DbCkalloc(size, file, line)
*----------------------------------------------------------------------
*
* Tcl_AttemptAlloc --
- * Interface to TclpAlloc when TCL_MEM_DEBUG is disabled. It does not
- * check that memory was actually allocated.
+ *
+ * Interface to TclpAlloc when TCL_MEM_DEBUG is disabled. It does not
+ * check that memory was actually allocated.
*
*----------------------------------------------------------------------
*/
char *
-Tcl_AttemptAlloc (size)
- unsigned int size;
+Tcl_AttemptAlloc(
+ unsigned int size)
{
char *result;
@@ -1060,57 +1110,57 @@ Tcl_AttemptAlloc (size)
}
char *
-Tcl_AttemptDbCkalloc(size, file, line)
- unsigned int size;
- CONST char *file;
- int line;
+Tcl_AttemptDbCkalloc(
+ unsigned int size,
+ CONST char *file,
+ int line)
{
char *result;
result = (char *) TclpAlloc(size);
return result;
}
-
/*
*----------------------------------------------------------------------
*
* Tcl_Realloc --
- * Interface to TclpRealloc when TCL_MEM_DEBUG is disabled. It does
- * check that memory was actually allocated.
+ *
+ * Interface to TclpRealloc when TCL_MEM_DEBUG is disabled. It does check
+ * that memory was actually allocated.
*
*----------------------------------------------------------------------
*/
char *
-Tcl_Realloc(ptr, size)
- char *ptr;
- unsigned int size;
+Tcl_Realloc(
+ char *ptr,
+ unsigned int size)
{
char *result;
result = TclpRealloc(ptr, size);
if ((result == NULL) && size) {
- panic("unable to realloc %u bytes", size);
+ Tcl_Panic("unable to realloc %u bytes", size);
}
return result;
}
char *
-Tcl_DbCkrealloc(ptr, size, file, line)
- char *ptr;
- unsigned int size;
- CONST char *file;
- int line;
+Tcl_DbCkrealloc(
+ char *ptr,
+ unsigned int size,
+ CONST char *file,
+ int line)
{
char *result;
result = (char *) TclpRealloc(ptr, size);
if ((result == NULL) && size) {
- fflush(stdout);
- panic("unable to realloc %u bytes, %s line %d", size, file, line);
+ fflush(stdout);
+ Tcl_Panic("unable to realloc %u bytes, %s line %d", size, file, line);
}
return result;
}
@@ -1119,16 +1169,17 @@ Tcl_DbCkrealloc(ptr, size, file, line)
*----------------------------------------------------------------------
*
* Tcl_AttemptRealloc --
- * Interface to TclpRealloc when TCL_MEM_DEBUG is disabled. It does
- * not check that memory was actually allocated.
+ *
+ * Interface to TclpRealloc when TCL_MEM_DEBUG is disabled. It does not
+ * check that memory was actually allocated.
*
*----------------------------------------------------------------------
*/
char *
-Tcl_AttemptRealloc(ptr, size)
- char *ptr;
- unsigned int size;
+Tcl_AttemptRealloc(
+ char *ptr,
+ unsigned int size)
{
char *result;
@@ -1137,11 +1188,11 @@ Tcl_AttemptRealloc(ptr, size)
}
char *
-Tcl_AttemptDbCkrealloc(ptr, size, file, line)
- char *ptr;
- unsigned int size;
- CONST char *file;
- int line;
+Tcl_AttemptDbCkrealloc(
+ char *ptr,
+ unsigned int size,
+ CONST char *file,
+ int line)
{
char *result;
@@ -1153,25 +1204,26 @@ Tcl_AttemptDbCkrealloc(ptr, size, file, line)
*----------------------------------------------------------------------
*
* Tcl_Free --
- * Interface to TclpFree when TCL_MEM_DEBUG is disabled. Done here
- * rather in the macro to keep some modules from being compiled with
- * TCL_MEM_DEBUG enabled and some with it disabled.
+ *
+ * Interface to TclpFree when TCL_MEM_DEBUG is disabled. Done here rather
+ * in the macro to keep some modules from being compiled with
+ * TCL_MEM_DEBUG enabled and some with it disabled.
*
*----------------------------------------------------------------------
*/
void
-Tcl_Free (ptr)
- char *ptr;
+Tcl_Free(
+ char *ptr)
{
TclpFree(ptr);
}
int
-Tcl_DbCkfree(ptr, file, line)
- char *ptr;
- CONST char *file;
- int line;
+Tcl_DbCkfree(
+ char *ptr,
+ CONST char *file,
+ int line)
{
TclpFree(ptr);
return 0;
@@ -1181,36 +1233,37 @@ Tcl_DbCkfree(ptr, file, line)
*----------------------------------------------------------------------
*
* Tcl_InitMemory --
- * Dummy initialization for memory command, which is only available
- * if TCL_MEM_DEBUG is on.
+ *
+ * Dummy initialization for memory command, which is only available if
+ * TCL_MEM_DEBUG is on.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
void
-Tcl_InitMemory(interp)
- Tcl_Interp *interp;
+Tcl_InitMemory(
+ Tcl_Interp *interp)
{
}
int
-Tcl_DumpActiveMemory(fileName)
- CONST char *fileName;
+Tcl_DumpActiveMemory(
+ CONST char *fileName)
{
return TCL_OK;
}
void
-Tcl_ValidateAllMemory(file, line)
- CONST char *file;
- int line;
+Tcl_ValidateAllMemory(
+ CONST char *file,
+ int line)
{
}
-void
-TclDumpMemoryInfo(outFile)
- FILE *outFile;
+int
+TclDumpMemoryInfo(ClientData clientData, int flags)
{
+ return 1;
}
#endif /* TCL_MEM_DEBUG */
@@ -1220,23 +1273,22 @@ TclDumpMemoryInfo(outFile)
*
* TclFinalizeMemorySubsystem --
*
- * This procedure is called to finalize all the structures that
- * are used by the memory allocator on a per-process basis.
+ * This procedure is called to finalize all the structures that are used
+ * by the memory allocator on a per-process basis.
*
* Results:
* None.
*
* Side effects:
- * This subsystem is self-initializing, since memory can be
- * allocated before Tcl is formally initialized. After this call,
- * this subsystem has been reset to its initial state and is
- * usable again.
+ * This subsystem is self-initializing, since memory can be allocated
+ * before Tcl is formally initialized. After this call, this subsystem
+ * has been reset to its initial state and is usable again.
*
*---------------------------------------------------------------------------
*/
void
-TclFinalizeMemorySubsystem()
+TclFinalizeMemorySubsystem(void)
{
#ifdef TCL_MEM_DEBUG
if (tclMemDumpFileName != NULL) {
@@ -1244,12 +1296,15 @@ TclFinalizeMemorySubsystem()
} else if (onExitMemDumpFileName != NULL) {
Tcl_DumpActiveMemory(onExitMemDumpFileName);
}
+
Tcl_MutexLock(ckallocMutexPtr);
+
if (curTagPtr != NULL) {
TclpFree((char *) curTagPtr);
curTagPtr = NULL;
}
allocHead = NULL;
+
Tcl_MutexUnlock(ckallocMutexPtr);
#endif
@@ -1257,3 +1312,11 @@ TclFinalizeMemorySubsystem()
TclFinalizeAllocSubsystem();
#endif
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclClock.c b/generic/tclClock.c
index 2c00a07..5b95ae6 100644
--- a/generic/tclClock.c
+++ b/generic/tclClock.c
@@ -1,23 +1,136 @@
-/*
+/*
* tclClock.c --
*
- * Contains the time and date related commands. This code
- * is derived from the time and date facilities of TclX,
- * by Mark Diekhans and Karl Lehenbauer.
+ * Contains the time and date related commands. This code is derived from
+ * the time and date facilities of TclX, by Mark Diekhans and Karl
+ * Lehenbauer.
*
* Copyright 1991-1995 Karl Lehenbauer and Mark Diekhans.
* Copyright (c) 1995 Sun Microsystems, Inc.
+ * Copyright (c) 2004 by Kevin B. Kenny. All rights reserved.
*
- * 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.
*/
-#include "tcl.h"
#include "tclInt.h"
-#include "tclPort.h"
/*
- * The date parsing stuff uses lexx and has tons o statics.
+ * Windows has mktime. The configurators do not check.
+ */
+
+#ifdef __WIN32__
+#define HAVE_MKTIME 1
+#endif
+
+/*
+ * Constants
+ */
+
+#define JULIAN_DAY_POSIX_EPOCH 2440588
+#define SECONDS_PER_DAY 86400
+#define JULIAN_SEC_POSIX_EPOCH (((Tcl_WideInt) JULIAN_DAY_POSIX_EPOCH) \
+ * SECONDS_PER_DAY)
+#define FOUR_CENTURIES 146097 /* days */
+#define JDAY_1_JAN_1_CE_JULIAN 1721424
+#define JDAY_1_JAN_1_CE_GREGORIAN 1721426
+#define ONE_CENTURY_GREGORIAN 36524 /* days */
+#define FOUR_YEARS 1461 /* days */
+#define ONE_YEAR 365 /* days */
+
+/*
+ * Table of the days in each month, leap and common years
+ */
+
+static const int hath[2][12] = {
+ {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+ {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
+};
+static const int daysInPriorMonths[2][13] = {
+ {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
+ {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}
+};
+
+/*
+ * Enumeration of the string literals used in [clock]
+ */
+
+typedef enum ClockLiteral {
+ LIT__NIL,
+ LIT__DEFAULT_FORMAT,
+ LIT_BCE, LIT_C,
+ LIT_CANNOT_USE_GMT_AND_TIMEZONE,
+ LIT_CE,
+ LIT_DAYOFMONTH, LIT_DAYOFWEEK, LIT_DAYOFYEAR,
+ LIT_ERA, LIT_GMT, LIT_GREGORIAN,
+ LIT_INTEGER_VALUE_TOO_LARGE,
+ LIT_ISO8601WEEK, LIT_ISO8601YEAR,
+ LIT_JULIANDAY, LIT_LOCALSECONDS,
+ LIT_MONTH,
+ LIT_SECONDS, LIT_TZNAME, LIT_TZOFFSET,
+ LIT_YEAR,
+ LIT__END
+} ClockLiteral;
+static const char *const literals[] = {
+ "",
+ "%a %b %d %H:%M:%S %Z %Y",
+ "BCE", "C",
+ "cannot use -gmt and -timezone in same call",
+ "CE",
+ "dayOfMonth", "dayOfWeek", "dayOfYear",
+ "era", ":GMT", "gregorian",
+ "integer value too large to represent",
+ "iso8601Week", "iso8601Year",
+ "julianDay", "localSeconds",
+ "month",
+ "seconds", "tzName", "tzOffset",
+ "year"
+};
+
+/*
+ * Structure containing the client data for [clock]
+ */
+
+typedef struct ClockClientData {
+ int refCount; /* Number of live references */
+ Tcl_Obj** literals; /* Pool of object literals */
+} ClockClientData;
+
+/*
+ * Structure containing the fields used in [clock format] and [clock scan]
+ */
+
+typedef struct TclDateFields {
+ Tcl_WideInt seconds; /* Time expressed in seconds from the Posix
+ * epoch */
+ Tcl_WideInt localSeconds; /* Local time expressed in nominal seconds
+ * from the Posix epoch */
+ int tzOffset; /* Time zone offset in seconds east of
+ * Greenwich */
+ Tcl_Obj* tzName; /* Time zone name */
+ int julianDay; /* Julian Day Number in local time zone */
+ enum {BCE=1, CE=0} era; /* Era */
+ int gregorian; /* Flag == 1 if the date is Gregorian */
+ int year; /* Year of the era */
+ int dayOfYear; /* Day of the year (1 January == 1) */
+ int month; /* Month number */
+ int dayOfMonth; /* Day of the month */
+ int iso8601Year; /* ISO8601 week-based year */
+ int iso8601Week; /* ISO8601 week number */
+ int dayOfWeek; /* Day of the week */
+} TclDateFields;
+static const char* eras[] = { "CE", "BCE", NULL };
+
+/*
+ * Thread specific data block holding a 'struct tm' for the 'gmtime' and
+ * 'localtime' library calls.
+ */
+
+static Tcl_ThreadDataKey tmKey;
+
+/*
+ * Mutex protecting 'gmtime', 'localtime' and 'mktime' calls and the statics
+ * in the date parsing code.
*/
TCL_DECLARE_MUTEX(clockMutex)
@@ -26,366 +139,1914 @@ TCL_DECLARE_MUTEX(clockMutex)
* Function prototypes for local procedures in this file:
*/
-static int FormatClock _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_WideInt clockVal, int useGMT,
- char *format));
+static int ConvertUTCToLocal(Tcl_Interp*,
+ TclDateFields*, Tcl_Obj*, int);
+static int ConvertUTCToLocalUsingTable(Tcl_Interp*,
+ TclDateFields*, int, Tcl_Obj *const[]);
+static int ConvertUTCToLocalUsingC(Tcl_Interp*,
+ TclDateFields*, int);
+static int ConvertLocalToUTC(Tcl_Interp*,
+ TclDateFields*, Tcl_Obj*, int);
+static int ConvertLocalToUTCUsingTable(Tcl_Interp*,
+ TclDateFields*, int, Tcl_Obj *const[]);
+static int ConvertLocalToUTCUsingC(Tcl_Interp*,
+ TclDateFields*, int);
+static Tcl_Obj* LookupLastTransition(Tcl_Interp*, Tcl_WideInt,
+ int, Tcl_Obj *const *);
+static void GetYearWeekDay(TclDateFields*, int);
+static void GetGregorianEraYearDay(TclDateFields*, int);
+static void GetMonthDay(TclDateFields*);
+static void GetJulianDayFromEraYearWeekDay(TclDateFields*, int);
+static void GetJulianDayFromEraYearMonthDay(TclDateFields*, int);
+static int IsGregorianLeapYear(TclDateFields*);
+static int WeekdayOnOrBefore(int, int);
+static int ClockClicksObjCmd(
+ ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int ClockConvertlocaltoutcObjCmd(
+ ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int ClockGetdatefieldsObjCmd(
+ ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int ClockGetjuliandayfromerayearmonthdayObjCmd(
+ ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int ClockGetjuliandayfromerayearweekdayObjCmd(
+ ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int ClockGetenvObjCmd(
+ ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int ClockMicrosecondsObjCmd(
+ ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int ClockMillisecondsObjCmd(
+ ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int ClockParseformatargsObjCmd(
+ ClientData clientData, Tcl_Interp* interp,
+ int objc, Tcl_Obj *const objv[]);
+static int ClockSecondsObjCmd(
+ ClientData clientData, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static struct tm * ThreadSafeLocalTime(const time_t *);
+static void TzsetIfNecessary(void);
+static void ClockDeleteCmdProc(ClientData);
+
+/*
+ * Structure containing description of "native" clock commands to create.
+ */
+
+struct ClockCommand {
+ const char *name; /* The tail of the command name. The full name
+ * is "::tcl::clock::<name>". When NULL marks
+ * the end of the table. */
+ Tcl_ObjCmdProc *objCmdProc; /* Function that implements the command. This
+ * will always have the ClockClientData sent
+ * to it, but may well ignore this data. */
+};
+
+static const struct ClockCommand clockCommands[] = {
+ { "clicks", ClockClicksObjCmd },
+ { "getenv", ClockGetenvObjCmd },
+ { "microseconds", ClockMicrosecondsObjCmd },
+ { "milliseconds", ClockMillisecondsObjCmd },
+ { "seconds", ClockSecondsObjCmd },
+ { "Oldscan", TclClockOldscanObjCmd },
+ { "ConvertLocalToUTC", ClockConvertlocaltoutcObjCmd },
+ { "GetDateFields", ClockGetdatefieldsObjCmd },
+ { "GetJulianDayFromEraYearMonthDay",
+ ClockGetjuliandayfromerayearmonthdayObjCmd },
+ { "GetJulianDayFromEraYearWeekDay",
+ ClockGetjuliandayfromerayearweekdayObjCmd },
+ { "ParseFormatArgs", ClockParseformatargsObjCmd },
+ { NULL, NULL }
+};
/*
- *-------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*
- * Tcl_ClockObjCmd --
+ * TclClockInit --
*
- * This procedure is invoked to process the "clock" Tcl command.
- * See the user documentation for details on what it does.
+ * Registers the 'clock' subcommands with the Tcl interpreter and
+ * initializes its client data (which consists mostly of constant
+ * Tcl_Obj's that it is too much trouble to keep recreating).
*
* Results:
- * A standard Tcl result.
+ * None.
*
* Side effects:
- * See the user documentation.
+ * Installs the commands and creates the client data
*
- *-------------------------------------------------------------------------
+ *----------------------------------------------------------------------
+ */
+
+void
+TclClockInit(
+ Tcl_Interp *interp) /* Tcl interpreter */
+{
+ const struct ClockCommand *clockCmdPtr;
+ char cmdName[50]; /* Buffer large enough to hold the string
+ *::tcl::clock::GetJulianDayFromEraYearMonthDay
+ * plus a terminating NULL. */
+ ClockClientData *data;
+ int i;
+
+ /*
+ * Safe interps get [::clock] as alias to a master, so do not need their
+ * own copies of the support routines.
+ */
+
+ if (Tcl_IsSafe(interp)) {
+ return;
+ }
+
+ /*
+ * Create the client data, which is a refcounted literal pool.
+ */
+
+ data = (ClockClientData *) ckalloc(sizeof(ClockClientData));
+ data->refCount = 0;
+ data->literals = (Tcl_Obj**) ckalloc(LIT__END * sizeof(Tcl_Obj*));
+ for (i = 0; i < LIT__END; ++i) {
+ data->literals[i] = Tcl_NewStringObj(literals[i], -1);
+ Tcl_IncrRefCount(data->literals[i]);
+ }
+
+ /*
+ * Install the commands.
+ */
+
+ strcpy(cmdName, "::tcl::clock::");
+#define TCL_CLOCK_PREFIX_LEN 14 /* == strlen("::tcl::clock::") */
+ for (clockCmdPtr=clockCommands ; clockCmdPtr->name!=NULL ; clockCmdPtr++) {
+ strcpy(cmdName + TCL_CLOCK_PREFIX_LEN, clockCmdPtr->name);
+ data->refCount++;
+ Tcl_CreateObjCommand(interp, cmdName, clockCmdPtr->objCmdProc, data,
+ ClockDeleteCmdProc);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ClockConvertlocaltoutcObjCmd --
+ *
+ * Tcl command that converts a UTC time to a local time by whatever means
+ * is available.
+ *
+ * Usage:
+ * ::tcl::clock::ConvertUTCToLocal dictionary tzdata changeover
+ *
+ * Parameters:
+ * dict - Dictionary containing a 'localSeconds' entry.
+ * tzdata - Time zone data
+ * changeover - Julian Day of the adoption of the Gregorian calendar.
+ *
+ * Results:
+ * Returns a standard Tcl result.
+ *
+ * Side effects:
+ * On success, sets the interpreter result to the given dictionary
+ * augmented with a 'seconds' field giving the UTC time. On failure,
+ * leaves an error message in the interpreter result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ClockConvertlocaltoutcObjCmd(
+ ClientData clientData, /* Client data */
+ Tcl_Interp* interp, /* Tcl interpreter */
+ int objc, /* Parameter count */
+ Tcl_Obj *const *objv) /* Parameter vector */
+{
+ ClockClientData* data = (ClockClientData*) clientData;
+ Tcl_Obj* const * literals = data->literals;
+ Tcl_Obj* secondsObj;
+ Tcl_Obj* dict;
+ int changeover;
+ TclDateFields fields;
+ int created = 0;
+ int status;
+
+ /*
+ * Check params and convert time.
+ */
+
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 1, objv, "dict tzdata changeover");
+ return TCL_ERROR;
+ }
+ dict = objv[1];
+ if (Tcl_DictObjGet(interp, dict, literals[LIT_LOCALSECONDS],
+ &secondsObj)!= TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (secondsObj == NULL) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("key \"localseconds\" not "
+ "found in dictionary", -1));
+ return TCL_ERROR;
+ }
+ if ((Tcl_GetWideIntFromObj(interp, secondsObj,
+ &(fields.localSeconds)) != TCL_OK)
+ || (TclGetIntFromObj(interp, objv[3], &changeover) != TCL_OK)
+ || ConvertLocalToUTC(interp, &fields, objv[2], changeover)) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Copy-on-write; set the 'seconds' field in the dictionary and place the
+ * modified dictionary in the interpreter result.
+ */
+
+ if (Tcl_IsShared(dict)) {
+ dict = Tcl_DuplicateObj(dict);
+ created = 1;
+ Tcl_IncrRefCount(dict);
+ }
+ status = Tcl_DictObjPut(interp, dict, literals[LIT_SECONDS],
+ Tcl_NewWideIntObj(fields.seconds));
+ if (status == TCL_OK) {
+ Tcl_SetObjResult(interp, dict);
+ }
+ if (created) {
+ Tcl_DecrRefCount(dict);
+ }
+ return status;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ClockGetdatefieldsObjCmd --
+ *
+ * Tcl command that determines the values that [clock format] will use in
+ * formatting a date, and populates a dictionary with them.
+ *
+ * Usage:
+ * ::tcl::clock::GetDateFields seconds tzdata changeover
+ *
+ * Parameters:
+ * seconds - Time expressed in seconds from the Posix epoch.
+ * tzdata - Time zone data of the time zone in which time is to
+ * be expressed.
+ * changeover - Julian Day Number at which the current locale adopted
+ * the Gregorian calendar
+ *
+ * Results:
+ * Returns a dictonary populated with the fields:
+ * seconds - Seconds from the Posix epoch
+ * localSeconds - Nominal seconds from the Posix epoch in
+ * the local time zone.
+ * tzOffset - Time zone offset in seconds east of Greenwich
+ * tzName - Time zone name
+ * julianDay - Julian Day Number in the local time zone
+ *
+ *----------------------------------------------------------------------
*/
int
-Tcl_ClockObjCmd (client, interp, objc, objv)
- ClientData client; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
+ClockGetdatefieldsObjCmd(
+ ClientData clientData, /* Opaque pointer to literal pool, etc. */
+ Tcl_Interp* interp, /* Tcl interpreter */
+ int objc, /* Parameter count */
+ Tcl_Obj *const *objv) /* Parameter vector */
{
- Tcl_Obj *resultPtr;
- int index;
- Tcl_Obj *CONST *objPtr;
- int useGMT = 0;
- char *format = "%a %b %d %X %Z %Y";
- int dummy;
- Tcl_WideInt baseClock, clockVal;
- long zone;
- Tcl_Obj *baseObjPtr = NULL;
- char *scanStr;
- int n;
-
- static CONST char *switches[] =
- {"clicks", "format", "scan", "seconds", (char *) NULL};
- enum command { COMMAND_CLICKS, COMMAND_FORMAT, COMMAND_SCAN,
- COMMAND_SECONDS
- };
- static CONST char *formatSwitches[] = {"-format", "-gmt", (char *) NULL};
- static CONST char *scanSwitches[] = {"-base", "-gmt", (char *) NULL};
+ TclDateFields fields;
+ Tcl_Obj* dict;
+ ClockClientData* data = (ClockClientData*) clientData;
+ Tcl_Obj* const * literals = data->literals;
+ int changeover;
+
+ /*
+ * Check params.
+ */
- resultPtr = Tcl_GetObjResult(interp);
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 1, objv, "seconds tzdata changeover");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetWideIntFromObj(interp, objv[1], &(fields.seconds)) != TCL_OK
+ || TclGetIntFromObj(interp, objv[3], &changeover) != TCL_OK) {
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[1], switches, "option", 0, &index)
- != TCL_OK) {
+ /*
+ * fields.seconds could be an unsigned number that overflowed. Make
+ * sure that it isn't.
+ */
+
+ if (objv[1]->typePtr == &tclBignumType) {
+ Tcl_SetObjResult(interp, literals[LIT_INTEGER_VALUE_TOO_LARGE]);
return TCL_ERROR;
}
- switch ((enum command) index) {
- case COMMAND_CLICKS: { /* clicks */
- int forceMilli = 0;
-
- if (objc == 3) {
- format = Tcl_GetStringFromObj(objv[2], &n);
- if ( ( n >= 2 )
- && ( strncmp( format, "-milliseconds",
- (unsigned int) n) == 0 ) ) {
- forceMilli = 1;
- } else {
- Tcl_AppendStringsToObj(resultPtr,
- "bad switch \"", format,
- "\": must be -milliseconds", (char *) NULL);
- return TCL_ERROR;
- }
- } else if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-milliseconds?");
- return TCL_ERROR;
+
+ /*
+ * Convert UTC time to local.
+ */
+
+ if (ConvertUTCToLocal(interp, &fields, objv[2], changeover) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Extract Julian day.
+ */
+
+ fields.julianDay = (int) ((fields.localSeconds + JULIAN_SEC_POSIX_EPOCH)
+ / SECONDS_PER_DAY);
+
+ /*
+ * Convert to Julian or Gregorian calendar.
+ */
+
+ GetGregorianEraYearDay(&fields, changeover);
+ GetMonthDay(&fields);
+ GetYearWeekDay(&fields, changeover);
+
+ dict = Tcl_NewDictObj();
+ Tcl_DictObjPut(NULL, dict, literals[LIT_LOCALSECONDS],
+ Tcl_NewWideIntObj(fields.localSeconds));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_SECONDS],
+ Tcl_NewWideIntObj(fields.seconds));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_TZNAME], fields.tzName);
+ Tcl_DecrRefCount(fields.tzName);
+ Tcl_DictObjPut(NULL, dict, literals[LIT_TZOFFSET],
+ Tcl_NewIntObj(fields.tzOffset));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_JULIANDAY],
+ Tcl_NewIntObj(fields.julianDay));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_GREGORIAN],
+ Tcl_NewIntObj(fields.gregorian));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_ERA],
+ literals[fields.era ? LIT_BCE : LIT_CE]);
+ Tcl_DictObjPut(NULL, dict, literals[LIT_YEAR],
+ Tcl_NewIntObj(fields.year));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_DAYOFYEAR],
+ Tcl_NewIntObj(fields.dayOfYear));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_MONTH],
+ Tcl_NewIntObj(fields.month));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_DAYOFMONTH],
+ Tcl_NewIntObj(fields.dayOfMonth));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_ISO8601YEAR],
+ Tcl_NewIntObj(fields.iso8601Year));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_ISO8601WEEK],
+ Tcl_NewIntObj(fields.iso8601Week));
+ Tcl_DictObjPut(NULL, dict, literals[LIT_DAYOFWEEK],
+ Tcl_NewIntObj(fields.dayOfWeek));
+ Tcl_SetObjResult(interp, dict);
+
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ClockGetjuliandayfromerayearmonthdayObjCmd --
+ *
+ * Tcl command that converts a time from era-year-month-day to a Julian
+ * Day Number.
+ *
+ * Parameters:
+ * dict - Dictionary that contains 'era', 'year', 'month' and
+ * 'dayOfMonth' keys.
+ * changeover - Julian Day of changeover to the Gregorian calendar
+ *
+ * Results:
+ * Result is either TCL_OK, with the interpreter result being the
+ * dictionary augmented with a 'julianDay' key, or TCL_ERROR,
+ * with the result being an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ClockGetjuliandayfromerayearmonthdayObjCmd (
+ ClientData clientData, /* Opaque pointer to literal pool, etc. */
+ Tcl_Interp* interp, /* Tcl interpreter */
+ int objc, /* Parameter count */
+ Tcl_Obj *const *objv) /* Parameter vector */
+{
+ TclDateFields fields;
+ Tcl_Obj* dict;
+ ClockClientData* data = (ClockClientData*) clientData;
+ Tcl_Obj* const * literals = data->literals;
+ Tcl_Obj* fieldPtr;
+ int changeover;
+ int copied = 0;
+ int status;
+ int era = 0;
+
+ /*
+ * Check params.
+ */
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "dict changeover");
+ return TCL_ERROR;
+ }
+ dict = objv[1];
+ if (Tcl_DictObjGet(interp, dict, literals[LIT_ERA], &fieldPtr) != TCL_OK
+ || Tcl_GetIndexFromObj(interp, fieldPtr, eras, "era", TCL_EXACT,
+ &era) != TCL_OK
+ || Tcl_DictObjGet(interp, dict, literals[LIT_YEAR],
+ &fieldPtr) != TCL_OK
+ || TclGetIntFromObj(interp, fieldPtr, &(fields.year)) != TCL_OK
+ || Tcl_DictObjGet(interp, dict, literals[LIT_MONTH],
+ &fieldPtr) != TCL_OK
+ || TclGetIntFromObj(interp, fieldPtr, &(fields.month)) != TCL_OK
+ || Tcl_DictObjGet(interp, dict, literals[LIT_DAYOFMONTH],
+ &fieldPtr) != TCL_OK
+ || TclGetIntFromObj(interp, fieldPtr,
+ &(fields.dayOfMonth)) != TCL_OK
+ || TclGetIntFromObj(interp, objv[2], &changeover) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ fields.era = era;
+
+ /*
+ * Get Julian day.
+ */
+
+ GetJulianDayFromEraYearMonthDay(&fields, changeover);
+
+ /*
+ * Store Julian day in the dictionary - copy on write.
+ */
+
+ if (Tcl_IsShared(dict)) {
+ dict = Tcl_DuplicateObj(dict);
+ Tcl_IncrRefCount(dict);
+ copied = 1;
+ }
+ status = Tcl_DictObjPut(interp, dict, literals[LIT_JULIANDAY],
+ Tcl_NewIntObj(fields.julianDay));
+ if (status == TCL_OK) {
+ Tcl_SetObjResult(interp, dict);
+ }
+ if (copied) {
+ Tcl_DecrRefCount(dict);
+ }
+ return status;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ClockGetjuliandayfromerayearweekdayObjCmd --
+ *
+ * Tcl command that converts a time from the ISO calendar to a Julian Day
+ * Number.
+ *
+ * Parameters:
+ * dict - Dictionary that contains 'era', 'iso8601Year', 'iso8601Week'
+ * and 'dayOfWeek' keys.
+ * changeover - Julian Day of changeover to the Gregorian calendar
+ *
+ * Results:
+ * Result is either TCL_OK, with the interpreter result being the
+ * dictionary augmented with a 'julianDay' key, or TCL_ERROR, with the
+ * result being an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ClockGetjuliandayfromerayearweekdayObjCmd (
+ ClientData clientData, /* Opaque pointer to literal pool, etc. */
+ Tcl_Interp* interp, /* Tcl interpreter */
+ int objc, /* Parameter count */
+ Tcl_Obj *const *objv) /* Parameter vector */
+{
+ TclDateFields fields;
+ Tcl_Obj* dict;
+ ClockClientData* data = (ClockClientData*) clientData;
+ Tcl_Obj* const * literals = data->literals;
+ Tcl_Obj* fieldPtr;
+ int changeover;
+ int copied = 0;
+ int status;
+ int era = 0;
+
+ /*
+ * Check params.
+ */
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "dict changeover");
+ return TCL_ERROR;
+ }
+ dict = objv[1];
+ if (Tcl_DictObjGet(interp, dict, literals[LIT_ERA], &fieldPtr) != TCL_OK
+ || 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
+ || TclGetIntFromObj(interp, objv[2], &changeover) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ fields.era = era;
+
+ /*
+ * Get Julian day.
+ */
+
+ GetJulianDayFromEraYearWeekDay(&fields, changeover);
+
+ /*
+ * Store Julian day in the dictionary - copy on write.
+ */
+
+ if (Tcl_IsShared(dict)) {
+ dict = Tcl_DuplicateObj(dict);
+ Tcl_IncrRefCount(dict);
+ copied = 1;
+ }
+ status = Tcl_DictObjPut(interp, dict, literals[LIT_JULIANDAY],
+ Tcl_NewIntObj(fields.julianDay));
+ if (status == TCL_OK) {
+ Tcl_SetObjResult(interp, dict);
+ }
+ if (copied) {
+ Tcl_DecrRefCount(dict);
+ }
+ return status;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ConvertLocalToUTC --
+ *
+ * Converts a time (in a TclDateFields structure) from the local wall
+ * clock to UTC.
+ *
+ * Results:
+ * Returns a standard Tcl result.
+ *
+ * Side effects:
+ * Populates the 'seconds' field if successful; stores an error message
+ * in the interpreter result on failure.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ConvertLocalToUTC(
+ Tcl_Interp* interp, /* Tcl interpreter */
+ TclDateFields* fields, /* Fields of the time */
+ Tcl_Obj* tzdata, /* Time zone data */
+ int changeover) /* Julian Day of the Gregorian transition */
+{
+ int rowc; /* Number of rows in tzdata */
+ Tcl_Obj** rowv; /* Pointers to the rows */
+
+ /*
+ * Unpack the tz data.
+ */
+
+ if (TclListObjGetElements(interp, tzdata, &rowc, &rowv) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Special case: If the time zone is :localtime, the tzdata will be empty.
+ * Use 'mktime' to convert the time to local
+ */
+
+ if (rowc == 0) {
+ return ConvertLocalToUTCUsingC(interp, fields, changeover);
+ } else {
+ return ConvertLocalToUTCUsingTable(interp, fields, rowc, rowv);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ConvertLocalToUTCUsingTable --
+ *
+ * Converts a time (in a TclDateFields structure) from local time in a
+ * given time zone to UTC.
+ *
+ * Results:
+ * Returns a standard Tcl result.
+ *
+ * Side effects:
+ * Stores an error message in the interpreter if an error occurs; if
+ * successful, stores the 'seconds' field in 'fields.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ConvertLocalToUTCUsingTable(
+ Tcl_Interp* interp, /* Tcl interpreter */
+ TclDateFields* fields, /* Time to convert, with 'seconds' filled in */
+ int rowc, /* Number of points at which time changes */
+ Tcl_Obj *const rowv[]) /* Points at which time changes */
+{
+ Tcl_Obj* row;
+ int cellc;
+ Tcl_Obj** cellv;
+ int have[8];
+ int nHave = 0;
+ int i;
+ int found;
+
+ /*
+ * Perform an initial lookup assuming that local == UTC, and locate the
+ * last time conversion prior to that time. Get the offset from that row,
+ * and look up again. Continue until we find an offset that we found
+ * before. This definition, rather than "the same offset" ensures that we
+ * don't enter an endless loop, as would otherwise happen when trying to
+ * convert a non-existent time such as 02:30 during the US Spring Daylight
+ * Saving Time transition.
+ */
+
+ found = 0;
+ fields->tzOffset = 0;
+ fields->seconds = fields->localSeconds;
+ while (!found) {
+ row = LookupLastTransition(interp, fields->seconds, rowc, rowv);
+ if ((row == NULL)
+ || TclListObjGetElements(interp, row, &cellc,
+ &cellv) != TCL_OK
+ || TclGetIntFromObj(interp, cellv[1],
+ &(fields->tzOffset)) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ found = 0;
+ for (i = 0; !found && i < nHave; ++i) {
+ if (have[i] == fields->tzOffset) {
+ found = 1;
+ break;
}
- if (forceMilli) {
- /*
- * We can enforce at least millisecond granularity
- */
- Tcl_Time time;
- Tcl_GetTime(&time);
- Tcl_SetLongObj(resultPtr,
- (long) (time.sec*1000 + time.usec/1000));
- } else {
- Tcl_SetLongObj(resultPtr, (long) TclpGetClicks());
+ }
+ if (!found) {
+ if (nHave == 8) {
+ Tcl_Panic("loop in ConvertLocalToUTCUsingTable");
}
- return TCL_OK;
+ have[nHave] = fields->tzOffset;
+ ++nHave;
}
+ fields->seconds = fields->localSeconds - fields->tzOffset;
+ }
+ fields->tzOffset = have[i];
+ fields->seconds = fields->localSeconds - fields->tzOffset;
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ConvertLocalToUTCUsingC --
+ *
+ * Converts a time from local wall clock to UTC when the local time zone
+ * cannot be determined. Uses 'mktime' to do the job.
+ *
+ * Results:
+ * Returns a standard Tcl result.
+ *
+ * Side effects:
+ * Stores an error message in the interpreter if an error occurs; if
+ * successful, stores the 'seconds' field in 'fields.
+ *
+ *----------------------------------------------------------------------
+ */
- case COMMAND_FORMAT: /* format */
- if ((objc < 3) || (objc > 7)) {
- wrongFmtArgs:
- Tcl_WrongNumArgs(interp, 2, objv,
- "clockval ?-format string? ?-gmt boolean?");
- return TCL_ERROR;
- }
+static int
+ConvertLocalToUTCUsingC(
+ Tcl_Interp* interp, /* Tcl interpreter */
+ TclDateFields* fields, /* Time to convert, with 'seconds' filled in */
+ int changeover) /* Julian Day of the Gregorian transition */
+{
+ struct tm timeVal;
+ int localErrno;
+ int secondOfDay;
+ Tcl_WideInt jsec;
- if (Tcl_GetWideIntFromObj(interp, objv[2], &clockVal)
- != TCL_OK) {
- return TCL_ERROR;
- }
-
- objPtr = objv+3;
- objc -= 3;
- while (objc > 1) {
- if (Tcl_GetIndexFromObj(interp, objPtr[0], formatSwitches,
- "switch", 0, &index) != TCL_OK) {
- return TCL_ERROR;
- }
- switch (index) {
- case 0: /* -format */
- format = Tcl_GetStringFromObj(objPtr[1], &dummy);
- break;
- case 1: /* -gmt */
- if (Tcl_GetBooleanFromObj(interp, objPtr[1],
- &useGMT) != TCL_OK) {
- return TCL_ERROR;
- }
- break;
- }
- objPtr += 2;
- objc -= 2;
- }
- if (objc != 0) {
- goto wrongFmtArgs;
- }
- return FormatClock(interp, clockVal, useGMT,
- format);
-
- case COMMAND_SCAN: /* scan */
- if ((objc < 3) || (objc > 7)) {
- wrongScanArgs:
- Tcl_WrongNumArgs(interp, 2, objv,
- "dateString ?-base clockValue? ?-gmt boolean?");
- return TCL_ERROR;
- }
+ /*
+ * Convert the given time to a date.
+ */
- objPtr = objv+3;
- objc -= 3;
- while (objc > 1) {
- if (Tcl_GetIndexFromObj(interp, objPtr[0], scanSwitches,
- "switch", 0, &index) != TCL_OK) {
- return TCL_ERROR;
- }
- switch (index) {
- case 0: /* -base */
- baseObjPtr = objPtr[1];
- break;
- case 1: /* -gmt */
- if (Tcl_GetBooleanFromObj(interp, objPtr[1],
- &useGMT) != TCL_OK) {
- return TCL_ERROR;
- }
- break;
- }
- objPtr += 2;
- objc -= 2;
- }
- if (objc != 0) {
- goto wrongScanArgs;
- }
+ jsec = fields->localSeconds + JULIAN_SEC_POSIX_EPOCH;
+ fields->julianDay = (int) (jsec / SECONDS_PER_DAY);
+ secondOfDay = (int)(jsec % SECONDS_PER_DAY);
+ if (secondOfDay < 0) {
+ secondOfDay += SECONDS_PER_DAY;
+ --fields->julianDay;
+ }
+ GetGregorianEraYearDay(fields, changeover);
+ GetMonthDay(fields);
- if (baseObjPtr != NULL) {
- if (Tcl_GetWideIntFromObj(interp, baseObjPtr,
- &baseClock) != TCL_OK) {
- return TCL_ERROR;
- }
- } else {
- baseClock = TclpGetSeconds();
- }
+ /*
+ * Convert the date/time to a 'struct tm'.
+ */
- if (useGMT) {
- zone = -50000; /* Force GMT */
- } else {
- zone = TclpGetTimeZone(baseClock);
- }
+ timeVal.tm_year = fields->year - 1900;
+ timeVal.tm_mon = fields->month - 1;
+ timeVal.tm_mday = fields->dayOfMonth;
+ timeVal.tm_hour = (secondOfDay / 3600) % 24;
+ timeVal.tm_min = (secondOfDay / 60) % 60;
+ timeVal.tm_sec = secondOfDay % 60;
+ timeVal.tm_isdst = -1;
+ timeVal.tm_wday = -1;
+ timeVal.tm_yday = -1;
- scanStr = Tcl_GetStringFromObj(objv[2], &dummy);
- Tcl_MutexLock(&clockMutex);
- if (TclGetDate(scanStr, baseClock, zone,
- &clockVal) < 0) {
- Tcl_MutexUnlock(&clockMutex);
- Tcl_AppendStringsToObj(resultPtr,
- "unable to convert date-time string \"",
- scanStr, "\"", (char *) NULL);
- return TCL_ERROR;
- }
- Tcl_MutexUnlock(&clockMutex);
+ /*
+ * Get local time. It is rumored that mktime is not thread safe on some
+ * platforms, so seize a mutex before attempting this.
+ */
- Tcl_SetWideIntObj(resultPtr, clockVal);
- return TCL_OK;
+ TzsetIfNecessary();
+ Tcl_MutexLock(&clockMutex);
+ errno = 0;
+ fields->seconds = (Tcl_WideInt) mktime(&timeVal);
+ localErrno = errno;
+ Tcl_MutexUnlock(&clockMutex);
- case COMMAND_SECONDS: /* seconds */
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return TCL_ERROR;
- }
- Tcl_SetLongObj(resultPtr, (long) TclpGetSeconds());
- return TCL_OK;
- default:
- return TCL_ERROR; /* Should never be reached. */
+ /*
+ * If conversion fails, report an error.
+ */
+
+ if (localErrno != 0
+ || (fields->seconds == -1 && timeVal.tm_yday == -1)) {
+ Tcl_SetResult(interp, "time value too large/small to represent",
+ TCL_STATIC);
+ return TCL_ERROR;
}
+ return TCL_OK;
}
/*
- *-----------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*
- * FormatClock --
+ * ConvertUTCToLocal --
*
- * Formats a time value based on seconds into a human readable
- * string.
+ * Converts a time (in a TclDateFields structure) from UTC to local time.
*
* Results:
- * Standard Tcl result.
+ * Returns a standard Tcl result.
*
* Side effects:
- * None.
+ * Populates the 'tzName' and 'tzOffset' fields.
*
- *-----------------------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
static int
-FormatClock(interp, clockVal, useGMT, format)
- Tcl_Interp *interp; /* Current interpreter. */
- Tcl_WideInt clockVal; /* Time in seconds. */
- int useGMT; /* Boolean */
- char *format; /* Format string */
+ConvertUTCToLocal(
+ Tcl_Interp* interp, /* Tcl interpreter */
+ TclDateFields* fields, /* Fields of the time */
+ Tcl_Obj* tzdata, /* Time zone data */
+ int changeover) /* Julian Day of the Gregorian transition */
{
- struct tm *timeDataPtr;
- Tcl_DString buffer, uniBuffer;
- int bufSize;
- char *p;
- int result;
- time_t tclockVal;
-#if !defined(HAVE_TM_ZONE) && !defined(WIN32)
- TIMEZONE_t savedTimeZone = 0; /* lint. */
- char *savedTZEnv = NULL; /* lint. */
-#endif
+ int rowc; /* Number of rows in tzdata */
+ Tcl_Obj** rowv; /* Pointers to the rows */
-#ifdef HAVE_TZSET
/*
- * Some systems forgot to call tzset in localtime, make sure its done.
+ * Unpack the tz data.
*/
- static int calledTzset = 0;
- Tcl_MutexLock(&clockMutex);
- if (!calledTzset) {
- tzset();
- calledTzset = 1;
+ if (TclListObjGetElements(interp, tzdata, &rowc, &rowv) != TCL_OK) {
+ return TCL_ERROR;
}
- Tcl_MutexUnlock(&clockMutex);
-#endif
/*
- * If the user gave us -format "", just return now
+ * Special case: If the time zone is :localtime, the tzdata will be empty.
+ * Use 'localtime' to convert the time to local
+ */
+
+ if (rowc == 0) {
+ return ConvertUTCToLocalUsingC(interp, fields, changeover);
+ } else {
+ return ConvertUTCToLocalUsingTable(interp, fields, rowc, rowv);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ConvertUTCToLocalUsingTable --
+ *
+ * Converts UTC to local time, given a table of transition points
+ *
+ * Results:
+ * Returns a standard Tcl result
+ *
+ * Side effects:
+ * On success, fills fields->tzName, fields->tzOffset and
+ * fields->localSeconds. On failure, places an error message in the
+ * interpreter result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ConvertUTCToLocalUsingTable(
+ Tcl_Interp* interp, /* Tcl interpreter */
+ TclDateFields* fields, /* Fields of the date */
+ int rowc, /* Number of rows in the conversion table
+ * (>= 1) */
+ Tcl_Obj *const rowv[]) /* Rows of the conversion table */
+{
+ Tcl_Obj* row; /* Row containing the current information */
+ int cellc; /* Count of cells in the row (must be 4) */
+ Tcl_Obj** cellv; /* Pointers to the cells */
+
+ /*
+ * Look up the nearest transition time.
+ */
+
+ row = LookupLastTransition(interp, fields->seconds, rowc, rowv);
+ if (row == NULL ||
+ TclListObjGetElements(interp, row, &cellc, &cellv) != TCL_OK ||
+ TclGetIntFromObj(interp,cellv[1],&(fields->tzOffset)) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Convert the time.
+ */
+
+ fields->tzName = cellv[3];
+ Tcl_IncrRefCount(fields->tzName);
+ fields->localSeconds = fields->seconds + fields->tzOffset;
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ConvertUTCToLocalUsingC --
+ *
+ * Converts UTC to localtime in cases where the local time zone is not
+ * determinable, using the C 'localtime' function to do it.
+ *
+ * Results:
+ * Returns a standard Tcl result.
+ *
+ * Side effects:
+ * On success, fills fields->tzName, fields->tzOffset and
+ * fields->localSeconds. On failure, places an error message in the
+ * interpreter result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ConvertUTCToLocalUsingC(
+ Tcl_Interp* interp, /* Tcl interpreter */
+ TclDateFields* fields, /* Time to convert, with 'seconds' filled in */
+ int changeover) /* Julian Day of the Gregorian transition */
+{
+ time_t tock;
+ struct tm* timeVal; /* Time after conversion */
+ int diff; /* Time zone diff local-Greenwich */
+ char buffer[8]; /* Buffer for time zone name */
+
+ /*
+ * Use 'localtime' to determine local year, month, day, time of day.
+ */
+
+ 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_SetErrorCode(interp, "CLOCK", "argTooLarge", NULL);
+ return TCL_ERROR;
+ }
+ TzsetIfNecessary();
+ timeVal = ThreadSafeLocalTime(&tock);
+ if (timeVal == NULL) {
+ Tcl_AppendResult(interp,
+ "localtime failed (clock value may be too "
+ "large/small to represent)", NULL);
+ Tcl_SetErrorCode(interp, "CLOCK", "localtimeFailed", NULL);
+ return TCL_ERROR;
+ }
+
+ /*
+ * Fill in the date in 'fields' and use it to derive Julian Day.
+ */
+
+ fields->era = CE;
+ fields->year = timeVal->tm_year + 1900;
+ fields->month = timeVal->tm_mon + 1;
+ fields->dayOfMonth = timeVal->tm_mday;
+ GetJulianDayFromEraYearMonthDay(fields, changeover);
+
+ /*
+ * Convert that value to seconds.
+ */
+
+ fields->localSeconds = (((fields->julianDay * (Tcl_WideInt) 24
+ + timeVal->tm_hour) * 60 + timeVal->tm_min) * 60
+ + timeVal->tm_sec) - JULIAN_SEC_POSIX_EPOCH;
+
+ /*
+ * Determine a time zone offset and name; just use +hhmm for the name.
+ */
+
+ diff = (int) (fields->localSeconds - fields->seconds);
+ fields->tzOffset = diff;
+ if (diff < 0) {
+ *buffer = '-';
+ diff = -diff;
+ } else {
+ *buffer = '+';
+ }
+ sprintf(buffer+1, "%02d", diff / 3600);
+ diff %= 3600;
+ sprintf(buffer+3, "%02d", diff / 60);
+ diff %= 60;
+ if (diff > 0) {
+ sprintf(buffer+5, "%02d", diff);
+ }
+ fields->tzName = Tcl_NewStringObj(buffer, -1);
+ Tcl_IncrRefCount(fields->tzName);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * LookupLastTransition --
+ *
+ * Given a UTC time and a tzdata array, looks up the last transition on
+ * or before the given time.
+ *
+ * Results:
+ * Returns a pointer to the row, or NULL if an error occurs.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj*
+LookupLastTransition(
+ Tcl_Interp* interp, /* Interpreter for error messages */
+ Tcl_WideInt tick, /* Time from the epoch */
+ int rowc, /* Number of rows of tzdata */
+ Tcl_Obj *const *rowv) /* Rows in tzdata */
+{
+ int l;
+ int u;
+ Tcl_Obj* compObj;
+ Tcl_WideInt compVal;
+
+ /*
+ * Examine the first row to make sure we're in bounds.
*/
- if (*format == '\0') {
- return TCL_OK;
+
+ if (Tcl_ListObjIndex(interp, rowv[0], 0, &compObj) != TCL_OK
+ || Tcl_GetWideIntFromObj(interp, compObj, &compVal) != TCL_OK) {
+ return NULL;
+ }
+
+ /*
+ * Bizarre case - first row doesn't begin at MIN_WIDE_INT. Return it
+ * anyway.
+ */
+
+ if (tick < compVal) {
+ return rowv[0];
}
-#if !defined(HAVE_TM_ZONE) && !defined(WIN32)
/*
- * This is a kludge for systems not having the timezone string in
- * struct tm. No matter what was specified, they use the local
- * timezone string. Since this kludge requires fiddling with the
- * TZ environment variable, it will mess up if done on multiple
- * threads at once. Protect it with a the clock mutex.
+ * Binary-search to find the transition.
*/
- Tcl_MutexLock( &clockMutex );
- if (useGMT) {
- CONST char *varValue;
+ l = 0;
+ u = rowc-1;
+ while (l < u) {
+ int m = (l + u + 1) / 2;
- varValue = Tcl_GetVar2(interp, "env", "TZ", TCL_GLOBAL_ONLY);
- if (varValue != NULL) {
- savedTZEnv = strcpy(ckalloc(strlen(varValue) + 1), varValue);
- } else {
- savedTZEnv = NULL;
+ if (Tcl_ListObjIndex(interp, rowv[m], 0, &compObj) != TCL_OK ||
+ Tcl_GetWideIntFromObj(interp, compObj, &compVal) != TCL_OK) {
+ return NULL;
+ }
+ if (tick >= compVal) {
+ l = m;
+ } else {
+ u = m-1;
}
- Tcl_SetVar2(interp, "env", "TZ", "GMT0", TCL_GLOBAL_ONLY);
- savedTimeZone = timezone;
- timezone = 0;
- tzset();
}
-#endif
+ return rowv[l];
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetYearWeekDay --
+ *
+ * Given a date with Julian Calendar Day, compute the year, week, and day
+ * in the ISO8601 calendar.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Stores 'iso8601Year', 'iso8601Week' and 'dayOfWeek' in the date
+ * fields.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GetYearWeekDay(
+ TclDateFields* fields, /* Date to convert, must have 'julianDay' */
+ int changeover) /* Julian Day Number of the Gregorian
+ * transition */
+{
+ TclDateFields temp;
+ int dayOfFiscalYear;
- tclockVal = (time_t) clockVal;
- timeDataPtr = TclpGetDate((TclpTime_t) &tclockVal, useGMT);
-
/*
- * Make a guess at the upper limit on the substituted string size
- * based on the number of percents in the string.
+ * Find the given date, minus three days, plus one year. That date's
+ * iso8601 year is an upper bound on the ISO8601 year of the given date.
*/
- for (bufSize = 1, p = format; *p != '\0'; p++) {
- if (*p == '%') {
- bufSize += 40;
- if (p[1] == 'c') {
- bufSize += 226;
- }
+ temp.julianDay = fields->julianDay - 3;
+ GetGregorianEraYearDay(&temp, changeover);
+ if (temp.era == BCE) {
+ temp.iso8601Year = temp.year - 1;
+ } else {
+ temp.iso8601Year = temp.year + 1;
+ }
+ temp.iso8601Week = 1;
+ temp.dayOfWeek = 1;
+ GetJulianDayFromEraYearWeekDay(&temp, changeover);
+
+ /*
+ * temp.julianDay is now the start of an ISO8601 year, either the one
+ * corresponding to the given date, or the one after. If we guessed high,
+ * move one year earlier
+ */
+
+ if (fields->julianDay < temp.julianDay) {
+ if (temp.era == BCE) {
+ temp.iso8601Year += 1;
} else {
- bufSize++;
+ temp.iso8601Year -= 1;
}
+ GetJulianDayFromEraYearWeekDay(&temp, changeover);
}
- Tcl_DStringInit(&uniBuffer);
- Tcl_UtfToExternalDString(NULL, format, -1, &uniBuffer);
- Tcl_DStringInit(&buffer);
- Tcl_DStringSetLength(&buffer, bufSize);
- /* If we haven't locked the clock mutex up above, lock it now. */
+ fields->iso8601Year = temp.iso8601Year;
+ dayOfFiscalYear = fields->julianDay - temp.julianDay;
+ fields->iso8601Week = (dayOfFiscalYear / 7) + 1;
+ fields->dayOfWeek = (dayOfFiscalYear + 1) % 7;
+ if (fields->dayOfWeek < 1) {
+ fields->dayOfWeek += 7;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetGregorianEraYearDay --
+ *
+ * Given a Julian Day Number, extracts the year and day of the year and
+ * puts them into TclDateFields, along with the era (BCE or CE) and a
+ * flag indicating whether the date is Gregorian or Julian.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Stores 'era', 'gregorian', 'year', and 'dayOfYear'.
+ *
+ *----------------------------------------------------------------------
+ */
-#if defined(HAVE_TM_ZONE) || defined(WIN32)
- Tcl_MutexLock(&clockMutex);
-#endif
- result = TclpStrftime(buffer.string, (unsigned int) bufSize,
- Tcl_DStringValue(&uniBuffer), timeDataPtr, useGMT);
-#if defined(HAVE_TM_ZONE) || defined(WIN32)
- Tcl_MutexUnlock(&clockMutex);
-#endif
- Tcl_DStringFree(&uniBuffer);
-
-#if !defined(HAVE_TM_ZONE) && !defined(WIN32)
- if (useGMT) {
- if (savedTZEnv != NULL) {
- Tcl_SetVar2(interp, "env", "TZ", savedTZEnv, TCL_GLOBAL_ONLY);
- ckfree(savedTZEnv);
- } else {
- Tcl_UnsetVar2(interp, "env", "TZ", TCL_GLOBAL_ONLY);
- }
- timezone = savedTimeZone;
- tzset();
- }
- Tcl_MutexUnlock( &clockMutex );
-#endif
+static void
+GetGregorianEraYearDay(
+ TclDateFields* fields, /* Date fields containing 'julianDay' */
+ int changeover) /* Gregorian transition date */
+{
+ int jday = fields->julianDay;
+ int day;
+ int year;
+ int n;
- if (result == 0) {
+ if (jday >= changeover) {
/*
- * A zero return is the error case (can also mean the strftime
- * didn't get enough space to write into). We know it doesn't
- * mean that we wrote zero chars because the check for an empty
- * format string is above.
+ * Gregorian calendar.
*/
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "bad format string \"", format, "\"", (char *) NULL);
+
+ fields->gregorian = 1;
+ year = 1;
+
+ /*
+ * n = Number of 400-year cycles since 1 January, 1 CE in the
+ * proleptic Gregorian calendar. day = remaining days.
+ */
+
+ day = jday - JDAY_1_JAN_1_CE_GREGORIAN;
+ n = day / FOUR_CENTURIES;
+ day %= FOUR_CENTURIES;
+ if (day < 0) {
+ day += FOUR_CENTURIES;
+ --n;
+ }
+ year += 400 * n;
+
+ /*
+ * n = number of centuries since the start of (year);
+ * day = remaining days
+ */
+
+ n = day / ONE_CENTURY_GREGORIAN;
+ day %= ONE_CENTURY_GREGORIAN;
+ if (n > 3) {
+ /*
+ * 31 December in the last year of a 400-year cycle.
+ */
+
+ n = 3;
+ day += ONE_CENTURY_GREGORIAN;
+ }
+ year += 100 * n;
+
+ } else {
+ /*
+ * Julian calendar.
+ */
+
+ fields->gregorian = 0;
+ year = 1;
+ day = jday - JDAY_1_JAN_1_CE_JULIAN;
+
+ }
+
+ /*
+ * n = number of 4-year cycles; days = remaining days.
+ */
+
+ n = day / FOUR_YEARS;
+ day %= FOUR_YEARS;
+ if (day < 0) {
+ day += FOUR_YEARS;
+ --n;
+ }
+ year += 4 * n;
+
+ /*
+ * n = number of years; days = remaining days.
+ */
+
+ n = day / ONE_YEAR;
+ day %= ONE_YEAR;
+ if (n > 3) {
+ /*
+ * 31 December of a leap year.
+ */
+
+ n = 3;
+ day += 365;
+ }
+ year += n;
+
+ /*
+ * store era/year/day back into fields.
+ */
+
+ if (year <= 0) {
+ fields->era = BCE;
+ fields->year = 1 - year;
+ } else {
+ fields->era = CE;
+ fields->year = year;
+ }
+ fields->dayOfYear = day + 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetMonthDay --
+ *
+ * Given a date as year and day-of-year, find month and day.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Stores 'month' and 'dayOfMonth' in the 'fields' structure.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GetMonthDay(
+ TclDateFields* fields) /* Date to convert */
+{
+ int day = fields->dayOfYear;
+ int month;
+ const int* h = hath[IsGregorianLeapYear(fields)];
+
+ for (month = 0; month < 12 && day > h[month]; ++month) {
+ day -= h[month];
+ }
+ fields->month = month+1;
+ fields->dayOfMonth = day;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetJulianDayFromEraYearWeekDay --
+ *
+ * Given a TclDateFields structure containing era, ISO8601 year, ISO8601
+ * week, and day of week, computes the Julian Day Number.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Stores 'julianDay' in the fields.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GetJulianDayFromEraYearWeekDay(
+ TclDateFields* fields, /* Date to convert */
+ int changeover) /* Julian Day Number of the Gregorian
+ * transition */
+{
+ int firstMonday; /* Julian day number of week 1, day 1 in the
+ * given year */
+
+ /*
+ * Find January 4 in the ISO8601 year, which will always be in week 1.
+ */
+
+ TclDateFields firstWeek;
+ firstWeek.era = fields->era;
+ firstWeek.year = fields->iso8601Year;
+ firstWeek.month = 1;
+ firstWeek.dayOfMonth = 4;
+ GetJulianDayFromEraYearMonthDay(&firstWeek, changeover);
+
+ /*
+ * Find Monday of week 1.
+ */
+
+ firstMonday = WeekdayOnOrBefore(1, firstWeek.julianDay);
+
+ /*
+ * Advance to the given week and day.
+ */
+
+ fields->julianDay = firstMonday + 7 * (fields->iso8601Week - 1)
+ + fields->dayOfWeek - 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetJulianDayFromEraYearMonthDay --
+ *
+ * Given era, year, month, and dayOfMonth (in TclDateFields), and the
+ * Gregorian transition date, computes the Julian Day Number.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Stores day number in 'julianDay'
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GetJulianDayFromEraYearMonthDay(
+ TclDateFields* fields, /* Date to convert */
+ int changeover) /* Gregorian transition date as a Julian Day */
+{
+ int year; int ym1;
+ int month; int mm1;
+ int q; int r;
+ int ym1o4; int ym1o100; int ym1o400;
+
+ if (fields->era == BCE) {
+ year = 1 - fields->year;
+ } else {
+ year = fields->year;
+ }
+
+ /*
+ * Reduce month modulo 12.
+ */
+
+ month = fields->month;
+ mm1 = month - 1;
+ q = mm1 / 12;
+ r = (mm1 % 12);
+ if (r < 0) {
+ r += 12;
+ q -= 1;
+ }
+ year += q;
+ month = r + 1;
+ ym1 = year - 1;
+
+ /*
+ * Adjust the year after reducing the month.
+ */
+
+ fields->gregorian = 1;
+ if (year < 1) {
+ fields->era = BCE;
+ fields->year = 1-year;
+ } else {
+ fields->era = CE;
+ fields->year = year;
+ }
+
+ /*
+ * Try an initial conversion in the Gregorian calendar.
+ */
+
+ ym1o4 = ym1 / 4;
+ if (ym1 % 4 < 0) {
+ --ym1o4;
+ }
+ ym1o100 = ym1 / 100;
+ if (ym1 % 100 < 0) {
+ --ym1o100;
+ }
+ ym1o400 = ym1 / 400;
+ if (ym1 % 400 < 0) {
+ --ym1o400;
+ }
+ fields->julianDay = JDAY_1_JAN_1_CE_GREGORIAN - 1
+ + fields->dayOfMonth
+ + daysInPriorMonths[IsGregorianLeapYear(fields)][month - 1]
+ + (ONE_YEAR * ym1)
+ + ym1o4
+ - ym1o100
+ + ym1o400;
+
+ /*
+ * If the resulting date is before the Gregorian changeover, convert in
+ * the Julian calendar instead.
+ */
+
+ if (fields->julianDay < changeover) {
+ fields->gregorian = 0;
+ fields->julianDay = JDAY_1_JAN_1_CE_JULIAN - 1
+ + fields->dayOfMonth
+ + daysInPriorMonths[year%4 == 0][month - 1]
+ + (ONE_YEAR * ym1)
+ + ym1o4;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * IsGregorianLeapYear --
+ *
+ * Tests whether a given year is a leap year, in either Julian or
+ * Gregorian calendar.
+ *
+ * Results:
+ * Returns 1 for a leap year, 0 otherwise.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+IsGregorianLeapYear(
+ TclDateFields* fields) /* Date to test */
+{
+ int year;
+
+ if (fields->era == BCE) {
+ year = 1 - fields->year;
+ } else {
+ year = fields->year;
+ }
+ if (year%4 != 0) {
+ return 0;
+ } else if (!(fields->gregorian)) {
+ return 1;
+ } else if (year%400 == 0) {
+ return 1;
+ } else if (year%100 == 0) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WeekdayOnOrBefore --
+ *
+ * Finds the Julian Day Number of a given day of the week that falls on
+ * or before a given date, expressed as Julian Day Number.
+ *
+ * Results:
+ * Returns the Julian Day Number
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WeekdayOnOrBefore(
+ int dayOfWeek, /* Day of week; Sunday == 0 or 7 */
+ int julianDay) /* Reference date */
+{
+ int k = (dayOfWeek + 6) % 7;
+ if (k < 0) {
+ k += 7;
+ }
+ return julianDay - ((julianDay - k) % 7);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ClockGetenvObjCmd --
+ *
+ * Tcl command that reads an environment variable from the system
+ *
+ * Usage:
+ * ::tcl::clock::getEnv NAME
+ *
+ * Parameters:
+ * NAME - Name of the environment variable desired
+ *
+ * Results:
+ * Returns a standard Tcl result. Returns an error if the variable does
+ * not exist, with a message left in the interpreter. Returns TCL_OK and
+ * the value of the variable if the variable does exist,
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+ClockGetenvObjCmd(
+ ClientData clientData,
+ Tcl_Interp* interp,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ const char* varName;
+ const char* varValue;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "name");
return TCL_ERROR;
}
+ varName = TclGetString(objv[1]);
+ varValue = getenv(varName);
+ if (varValue == NULL) {
+ varValue = "";
+ }
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(varValue, -1));
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadSafeLocalTime --
+ *
+ * Wrapper around the 'localtime' library function to make it thread
+ * safe.
+ *
+ * Results:
+ * Returns a pointer to a 'struct tm' in thread-specific data.
+ *
+ * Side effects:
+ * Invokes localtime or localtime_r as appropriate.
+ *
+ *----------------------------------------------------------------------
+ */
+static struct tm *
+ThreadSafeLocalTime(
+ const time_t *timePtr) /* Pointer to the number of seconds since the
+ * local system's epoch */
+{
/*
- * Convert the time to UTF from external encoding [Bug: 3345]
+ * Get a thread-local buffer to hold the returned time.
*/
- Tcl_DStringInit(&uniBuffer);
- Tcl_ExternalToUtfDString(NULL, buffer.string, -1, &uniBuffer);
- Tcl_SetStringObj(Tcl_GetObjResult(interp), uniBuffer.string, -1);
+ struct tm *tmPtr = (struct tm *)
+ Tcl_GetThreadData(&tmKey, (int) sizeof(struct tm));
+#ifdef HAVE_LOCALTIME_R
+ localtime_r(timePtr, tmPtr);
+#else
+ struct tm *sysTmPtr;
- Tcl_DStringFree(&uniBuffer);
- Tcl_DStringFree(&buffer);
+ Tcl_MutexLock(&clockMutex);
+ sysTmPtr = localtime(timePtr);
+ if (sysTmPtr == NULL) {
+ Tcl_MutexUnlock(&clockMutex);
+ return NULL;
+ } else {
+ memcpy((void *) tmPtr, (void *) localtime(timePtr), sizeof(struct tm));
+ Tcl_MutexUnlock(&clockMutex);
+ }
+#endif
+ return tmPtr;
+}
+
+/*----------------------------------------------------------------------
+ *
+ * ClockClicksObjCmd --
+ *
+ * Returns a high-resolution counter.
+ *
+ * Results:
+ * Returns a standard Tcl result.
+ *
+ * Side effects:
+ * None.
+ *
+ * This function implements the 'clock clicks' Tcl command. Refer to the user
+ * documentation for details on what it does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+ClockClicksObjCmd(
+ ClientData clientData, /* Client data is unused */
+ Tcl_Interp* interp, /* Tcl interpreter */
+ int objc, /* Parameter count */
+ Tcl_Obj* const* objv) /* Parameter values */
+{
+ static const char *clicksSwitches[] = {
+ "-milliseconds", "-microseconds", NULL
+ };
+ enum ClicksSwitch {
+ CLICKS_MILLIS, CLICKS_MICROS, CLICKS_NATIVE
+ };
+ int index = CLICKS_NATIVE;
+ Tcl_Time now;
+
+ switch (objc) {
+ case 1:
+ break;
+ case 2:
+ if (Tcl_GetIndexFromObj(interp, objv[1], clicksSwitches, "option", 0,
+ &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ break;
+ default:
+ Tcl_WrongNumArgs(interp, 1, objv, "?option?");
+ return TCL_ERROR;
+ }
+
+ switch (index) {
+ case CLICKS_MILLIS:
+ Tcl_GetTime(&now);
+ Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt)
+ now.sec * 1000 + now.usec / 1000));
+ break;
+ case CLICKS_NATIVE: {
+#ifndef TCL_WIDE_CLICKS
+ unsigned long clicks = TclpGetClicks();
+#else
+ Tcl_WideInt clicks = TclpGetWideClicks();
+#endif
+ Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt) clicks));
+ break;
+ }
+ case CLICKS_MICROS:
+ Tcl_GetTime(&now);
+ Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
+ ((Tcl_WideInt) now.sec * 1000000) + now.usec));
+ break;
+ }
+
+ return TCL_OK;
+}
+
+/*----------------------------------------------------------------------
+ *
+ * ClockMillisecondsObjCmd -
+ *
+ * Returns a count of milliseconds since the epoch.
+ *
+ * Results:
+ * Returns a standard Tcl result.
+ *
+ * Side effects:
+ * None.
+ *
+ * This function implements the 'clock milliseconds' Tcl command. Refer to the
+ * user documentation for details on what it does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+ClockMillisecondsObjCmd(
+ ClientData clientData, /* Client data is unused */
+ Tcl_Interp* interp, /* Tcl interpreter */
+ int objc, /* Parameter count */
+ Tcl_Obj* const* objv) /* Parameter values */
+{
+ Tcl_Time now;
+
+ if (objc != 1) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return TCL_ERROR;
+ }
+ Tcl_GetTime(&now);
+ Tcl_SetObjResult(interp, Tcl_NewWideIntObj( (Tcl_WideInt)
+ now.sec * 1000 + now.usec / 1000));
return TCL_OK;
}
+
+/*----------------------------------------------------------------------
+ *
+ * ClockMicrosecondsObjCmd -
+ *
+ * Returns a count of microseconds since the epoch.
+ *
+ * Results:
+ * Returns a standard Tcl result.
+ *
+ * Side effects:
+ * None.
+ *
+ * This function implements the 'clock microseconds' Tcl command. Refer to the
+ * user documentation for details on what it does.
+ *
+ *----------------------------------------------------------------------
+ */
+int
+ClockMicrosecondsObjCmd(
+ ClientData clientData, /* Client data is unused */
+ Tcl_Interp* interp, /* Tcl interpreter */
+ int objc, /* Parameter count */
+ Tcl_Obj* const* objv) /* Parameter values */
+{
+ Tcl_Time now;
+
+ if (objc != 1) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return TCL_ERROR;
+ }
+ Tcl_GetTime(&now);
+ Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
+ ((Tcl_WideInt) now.sec * 1000000) + now.usec));
+ return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ClockParseformatargsObjCmd --
+ *
+ * Parses the arguments for [clock format].
+ *
+ * Results:
+ * Returns a standard Tcl result, whose value is a four-element
+ * list comprising the time format, the locale, and the timezone.
+ *
+ * This function exists because the loop that parses the [clock format]
+ * options is a known performance "hot spot", and is implemented in an
+ * effort to speed that particular code up.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+ClockParseformatargsObjCmd(
+ ClientData clientData, /* Client data containing literal pool */
+ Tcl_Interp* interp, /* Tcl interpreter */
+ int objc, /* Parameter count */
+ Tcl_Obj *const objv[] /* Parameter vector */
+) {
+
+ ClockClientData* dataPtr = (ClockClientData*) clientData;
+ Tcl_Obj** litPtr = dataPtr->literals;
+
+ /* Format, locale and timezone */
+
+ Tcl_Obj* results[3];
+#define formatObj results[0]
+#define localeObj results[1]
+#define timezoneObj results[2]
+ int gmtFlag = 0;
+
+ /* Command line options expected */
+
+ static const char* options[] = {
+ "-format", "-gmt", "-locale",
+ "-timezone", NULL };
+ enum optionInd {
+ CLOCK_FORMAT_FORMAT, CLOCK_FORMAT_GMT, CLOCK_FORMAT_LOCALE,
+ CLOCK_FORMAT_TIMEZONE
+ };
+ int optionIndex; /* Index of an option */
+ int saw = 0; /* Flag == 1 if option was seen already */
+ Tcl_WideInt clockVal; /* Clock value - just used to parse */
+ int i;
+
+ /* Args consist of a time followed by keyword-value pairs */
+
+ if (objc < 2 || (objc % 2) != 0) {
+ Tcl_WrongNumArgs(interp, 0, objv,
+ "clock format clockval ?-format string? "
+ "?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?");
+ Tcl_SetErrorCode(interp, "CLOCK", "wrongNumArgs", NULL);
+ return TCL_ERROR;
+ }
+
+ /* Extract values for the keywords */
+
+ formatObj = litPtr[LIT__DEFAULT_FORMAT];
+ localeObj = litPtr[LIT_C];
+ timezoneObj = litPtr[LIT__NIL];
+ for (i = 2; i < objc; i+=2) {
+ if (Tcl_GetIndexFromObj(interp, objv[i], options, "switch", 0,
+ &optionIndex) != TCL_OK) {
+ Tcl_SetErrorCode(interp, "CLOCK", "badSwitch",
+ Tcl_GetString(objv[i]), NULL);
+ return TCL_ERROR;
+ }
+ switch (optionIndex) {
+ case CLOCK_FORMAT_FORMAT:
+ formatObj = objv[i+1];
+ break;
+ case CLOCK_FORMAT_GMT:
+ if (Tcl_GetBooleanFromObj(interp, objv[i+1], &gmtFlag) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ break;
+ case CLOCK_FORMAT_LOCALE:
+ localeObj = objv[i+1];
+ break;
+ case CLOCK_FORMAT_TIMEZONE:
+ timezoneObj = objv[i+1];
+ break;
+ }
+ saw |= (1 << optionIndex);
+ }
+
+ /* Check options */
+
+ if (Tcl_GetWideIntFromObj(interp, objv[1], &clockVal) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if ((saw & (1 << CLOCK_FORMAT_GMT))
+ && (saw & (1 << CLOCK_FORMAT_TIMEZONE))) {
+ Tcl_SetObjResult(interp, litPtr[LIT_CANNOT_USE_GMT_AND_TIMEZONE]);
+ Tcl_SetErrorCode(interp, "CLOCK", "gmtWithTimezone", NULL);
+ return TCL_ERROR;
+ }
+ if (gmtFlag) {
+ timezoneObj = litPtr[LIT_GMT];
+ }
+
+ /* Return options as a list */
+
+ Tcl_SetObjResult(interp, Tcl_NewListObj(3, results));
+ return TCL_OK;
+
+#undef timezoneObj
+#undef localeObj
+#undef formatObj
+
+}
+
+/*----------------------------------------------------------------------
+ *
+ * ClockSecondsObjCmd -
+ *
+ * Returns a count of microseconds since the epoch.
+ *
+ * Results:
+ * Returns a standard Tcl result.
+ *
+ * Side effects:
+ * None.
+ *
+ * This function implements the 'clock seconds' Tcl command. Refer to the user
+ * documentation for details on what it does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+ClockSecondsObjCmd(
+ ClientData clientData, /* Client data is unused */
+ Tcl_Interp* interp, /* Tcl interpreter */
+ int objc, /* Parameter count */
+ Tcl_Obj* const* objv) /* Parameter values */
+{
+ Tcl_Time now;
+
+ if (objc != 1) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return TCL_ERROR;
+ }
+ Tcl_GetTime(&now);
+ Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt) now.sec));
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TzsetIfNecessary --
+ *
+ * Calls the tzset() library function if the contents of the TZ
+ * environment variable has changed.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Calls tzset.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+TzsetIfNecessary(void)
+{
+ static char* tzWas = NULL; /* Previous value of TZ, protected by
+ * clockMutex. */
+ const char* tzIsNow; /* Current value of TZ */
+
+ Tcl_MutexLock(&clockMutex);
+ tzIsNow = getenv("TZ");
+ if (tzIsNow != NULL && (tzWas == NULL || strcmp(tzIsNow, tzWas) != 0)) {
+ tzset();
+ if (tzWas != NULL) {
+ ckfree(tzWas);
+ }
+ tzWas = ckalloc(strlen(tzIsNow) + 1);
+ strcpy(tzWas, tzIsNow);
+ } else if (tzIsNow == NULL && tzWas != NULL) {
+ tzset();
+ ckfree(tzWas);
+ tzWas = NULL;
+ }
+ Tcl_MutexUnlock(&clockMutex);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ClockDeleteCmdProc --
+ *
+ * Remove a reference to the clock client data, and clean up memory
+ * when it's all gone.
+ *
+ * Results:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ClockDeleteCmdProc(
+ ClientData clientData) /* Opaque pointer to the client data */
+{
+ ClockClientData *data = (ClockClientData*) clientData;
+ int i;
+
+ --(data->refCount);
+ if (data->refCount == 0) {
+ for (i = 0; i < LIT__END; ++i) {
+ Tcl_DecrRefCount(data->literals[i]);
+ }
+ ckfree((char*) (data->literals));
+ ckfree((char*) data);
+ }
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclCmdAH.c b/generic/tclCmdAH.c
index 63d9111..75ba465 100644
--- a/generic/tclCmdAH.c
+++ b/generic/tclCmdAH.c
@@ -1,51 +1,45 @@
-/*
+/*
* tclCmdAH.c --
*
- * This file contains the top-level command routines for most of
- * the Tcl built-in commands whose names begin with the letters
- * A to H.
+ * This file contains the top-level command routines for most of the Tcl
+ * built-in commands whose names begin with the letters A to H.
*
* Copyright (c) 1987-1993 The Regents of the University of California.
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
*
- * 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.
*/
-#ifndef _WIN64
-/* See [Bug 2935503]: file mtime sets wrong time */
-# define _USE_32BIT_TIME_T
-#endif
-
-#include <sys/stat.h>
#include "tclInt.h"
-#include "tclPort.h"
#include <locale.h>
/*
* Prototypes for local procedures defined in this file:
*/
-static int CheckAccess _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_Obj *objPtr, int mode));
-static int GetStatBuf _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_Obj *objPtr, Tcl_FSStatProc *statProc,
- Tcl_StatBuf *statPtr));
-static char * GetTypeFromMode _ANSI_ARGS_((int mode));
-static int StoreStatData _ANSI_ARGS_((Tcl_Interp *interp,
- char *varName, Tcl_StatBuf *statPtr));
+static int CheckAccess(Tcl_Interp *interp, Tcl_Obj *pathPtr,
+ int mode);
+static int EncodingDirsObjCmd(ClientData dummy,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[]);
+static int GetStatBuf(Tcl_Interp *interp, Tcl_Obj *pathPtr,
+ Tcl_FSStatProc *statProc, Tcl_StatBuf *statPtr);
+static char * GetTypeFromMode(int mode);
+static int StoreStatData(Tcl_Interp *interp, Tcl_Obj *varName,
+ Tcl_StatBuf *statPtr);
/*
*----------------------------------------------------------------------
*
* Tcl_BreakObjCmd --
*
- * This procedure is invoked to process the "break" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "break" Tcl command. See the
+ * user documentation for details on what it does.
*
- * With the bytecode compiler, this procedure is only called when
- * a command name is computed at runtime, and is "break" or the name
- * to which "break" was renamed: e.g., "set z break; $z"
+ * With the bytecode compiler, this procedure is only called when a
+ * command name is computed at runtime, and is "break" or the name to
+ * which "break" was renamed: e.g., "set z break; $z"
*
* Results:
* A standard Tcl result.
@@ -58,11 +52,11 @@ static int StoreStatData _ANSI_ARGS_((Tcl_Interp *interp,
/* ARGSUSED */
int
-Tcl_BreakObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_BreakObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
if (objc != 1) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
@@ -76,8 +70,9 @@ Tcl_BreakObjCmd(dummy, interp, objc, objv)
*
* Tcl_CaseObjCmd --
*
- * This procedure is invoked to process the "case" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "case" Tcl command. See the
+ * user documentation for details on what it does. THIS COMMAND IS
+ * OBSOLETE AND DEPRECATED. SLATED FOR REMOVAL IN TCL 9.0.
*
* Results:
* A standard Tcl object result.
@@ -90,15 +85,15 @@ Tcl_BreakObjCmd(dummy, interp, objc, objv)
/* ARGSUSED */
int
-Tcl_CaseObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_CaseObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
register int i;
int body, result, caseObjc;
- char *string, *arg;
+ char *stringPtr, *arg;
Tcl_Obj *CONST *caseObjv;
Tcl_Obj *armPtr;
@@ -108,10 +103,10 @@ Tcl_CaseObjCmd(dummy, interp, objc, objv)
return TCL_ERROR;
}
- string = Tcl_GetString(objv[1]);
+ stringPtr = TclGetString(objv[1]);
body = -1;
- arg = Tcl_GetString(objv[2]);
+ arg = TclGetString(objv[2]);
if (strcmp(arg, "in") == 0) {
i = 3;
} else {
@@ -121,14 +116,14 @@ Tcl_CaseObjCmd(dummy, interp, objc, objv)
caseObjv = objv + i;
/*
- * If all of the pattern/command pairs are lumped into a single
- * argument, split them out again.
+ * If all of the pattern/command pairs are lumped into a single argument,
+ * split them out again.
*/
if (caseObjc == 1) {
Tcl_Obj **newObjv;
-
- Tcl_ListObjGetElements(interp, caseObjv[0], &caseObjc, &newObjv);
+
+ TclListObjGetElements(interp, caseObjv[0], &caseObjc, &newObjv);
caseObjv = newObjv;
}
@@ -140,17 +135,16 @@ Tcl_CaseObjCmd(dummy, interp, objc, objv)
if (i == (caseObjc - 1)) {
Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "extra case pattern with no body", -1);
+ Tcl_AppendResult(interp, "extra case pattern with no body", NULL);
return TCL_ERROR;
}
/*
- * Check for special case of single pattern (no list) with
- * no backslash sequences.
+ * Check for special case of single pattern (no list) with no
+ * backslash sequences.
*/
- pat = Tcl_GetString(caseObjv[i]);
+ pat = TclGetString(caseObjv[i]);
for (p = (unsigned char *) pat; *p != '\0'; p++) {
if (isspace(*p) || (*p == '\\')) { /* INTL: ISO space, UCHAR */
break;
@@ -160,17 +154,16 @@ Tcl_CaseObjCmd(dummy, interp, objc, objv)
if ((*pat == 'd') && (strcmp(pat, "default") == 0)) {
body = i + 1;
}
- if (Tcl_StringMatch(string, pat)) {
+ if (Tcl_StringMatch(stringPtr, pat)) {
body = i + 1;
goto match;
}
continue;
}
-
/*
- * Break up pattern lists, then check each of the patterns
- * in the list.
+ * Break up pattern lists, then check each of the patterns in the
+ * list.
*/
result = Tcl_SplitList(interp, pat, &patObjc, &patObjv);
@@ -178,7 +171,7 @@ Tcl_CaseObjCmd(dummy, interp, objc, objv)
return result;
}
for (j = 0; j < patObjc; j++) {
- if (Tcl_StringMatch(string, patObjv[j])) {
+ if (Tcl_StringMatch(stringPtr, patObjv[j])) {
body = i + 1;
break;
}
@@ -189,18 +182,14 @@ Tcl_CaseObjCmd(dummy, interp, objc, objv)
}
}
- match:
+ match:
if (body != -1) {
armPtr = caseObjv[body - 1];
result = Tcl_EvalObjEx(interp, caseObjv[body], 0);
if (result == TCL_ERROR) {
- char msg[100 + TCL_INTEGER_SPACE];
-
- arg = Tcl_GetString(armPtr);
- sprintf(msg,
- "\n (\"%.50s\" arm line %d)", arg,
- interp->errorLine);
- Tcl_AddObjErrorInfo(interp, msg, -1);
+ Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+ "\n (\"%.50s\" arm line %d)",
+ TclGetString(armPtr), interp->errorLine));
}
return result;
}
@@ -217,7 +206,7 @@ Tcl_CaseObjCmd(dummy, interp, objc, objv)
*
* Tcl_CatchObjCmd --
*
- * This object-based procedure is invoked to process the "catch" Tcl
+ * This object-based procedure is invoked to process the "catch" Tcl
* command. See the user documentation for details on what it does.
*
* Results:
@@ -231,53 +220,69 @@ Tcl_CaseObjCmd(dummy, interp, objc, objv)
/* ARGSUSED */
int
-Tcl_CatchObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_CatchObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Tcl_Obj *varNamePtr = NULL;
+ Tcl_Obj *optionVarNamePtr = NULL;
int result;
-#ifdef TCL_TIP280
- Interp* iPtr = (Interp*) interp;
-#endif
+ Interp *iPtr = (Interp *) interp;
- if ((objc != 2) && (objc != 3)) {
- Tcl_WrongNumArgs(interp, 1, objv, "command ?varName?");
+ if ((objc < 2) || (objc > 4)) {
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "script ?resultVarName? ?optionVarName?");
return TCL_ERROR;
}
- if (objc == 3) {
+ if (objc >= 3) {
varNamePtr = objv[2];
}
+ if (objc == 4) {
+ optionVarNamePtr = objv[3];
+ }
-#ifndef TCL_TIP280
- result = Tcl_EvalObjEx(interp, objv[1], 0);
-#else
- /* TIP #280. Make invoking context available to caught script */
- result = TclEvalObjEx(interp, objv[1], 0, iPtr->cmdFramePtr,1);
-#endif
-
- if (objc == 3) {
- if (Tcl_ObjSetVar2(interp, varNamePtr, NULL,
- Tcl_GetObjResult(interp), 0) == NULL) {
+ /*
+ * TIP #280. Make invoking context available to caught script.
+ */
+
+ result = TclEvalObjEx(interp, objv[1], 0, iPtr->cmdFramePtr, 1);
+
+ /*
+ * We disable catch in interpreters where the limit has been exceeded.
+ */
+
+ if (Tcl_LimitExceeded(interp)) {
+ Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+ "\n (\"catch\" body line %d)", interp->errorLine));
+ return TCL_ERROR;
+ }
+
+ if (objc >= 3) {
+ if (NULL == Tcl_ObjSetVar2(interp, varNamePtr, NULL,
+ Tcl_GetObjResult(interp), 0)) {
Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "couldn't save command result in variable", -1);
+ Tcl_AppendResult(interp,
+ "couldn't save command result in variable", NULL);
+ return TCL_ERROR;
+ }
+ }
+ if (objc == 4) {
+ Tcl_Obj *options = Tcl_GetReturnOptions(interp, result);
+ if (NULL == Tcl_ObjSetVar2(interp, optionVarNamePtr, NULL,
+ options, 0)) {
+ Tcl_DecrRefCount(options);
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp,
+ "couldn't save return options in variable", NULL);
return TCL_ERROR;
}
}
-
- /*
- * Set the interpreter's object result to an integer object holding the
- * integer Tcl_EvalObj result. Note that we don't bother generating a
- * string representation. We reset the interpreter's object result
- * to an unshared empty object and then set it to be an integer object.
- */
Tcl_ResetResult(interp);
- Tcl_SetIntObj(Tcl_GetObjResult(interp), result);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(result));
return TCL_OK;
}
@@ -286,8 +291,8 @@ Tcl_CatchObjCmd(dummy, interp, objc, objv)
*
* Tcl_CdObjCmd --
*
- * This procedure is invoked to process the "cd" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "cd" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -300,11 +305,11 @@ Tcl_CatchObjCmd(dummy, interp, objc, objv)
/* ARGSUSED */
int
-Tcl_CdObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_CdObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Tcl_Obj *dir;
int result;
@@ -317,7 +322,7 @@ Tcl_CdObjCmd(dummy, interp, objc, objv)
if (objc == 2) {
dir = objv[1];
} else {
- dir = Tcl_NewStringObj("~",1);
+ TclNewLiteralStringObj(dir, "~");
Tcl_IncrRefCount(dir);
}
if (Tcl_FSConvertToPathType(interp, dir) != TCL_OK) {
@@ -326,7 +331,7 @@ Tcl_CdObjCmd(dummy, interp, objc, objv)
result = Tcl_FSChdir(dir);
if (result != TCL_OK) {
Tcl_AppendResult(interp, "couldn't change working directory to \"",
- Tcl_GetString(dir), "\": ", Tcl_PosixError(interp), (char *) NULL);
+ TclGetString(dir), "\": ", Tcl_PosixError(interp), NULL);
result = TCL_ERROR;
}
}
@@ -355,11 +360,11 @@ Tcl_CdObjCmd(dummy, interp, objc, objv)
/* ARGSUSED */
int
-Tcl_ConcatObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_ConcatObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
if (objc >= 2) {
Tcl_SetObjResult(interp, Tcl_ConcatObj(objc-1, objv+1));
@@ -370,14 +375,14 @@ Tcl_ConcatObjCmd(dummy, interp, objc, objv)
/*
*----------------------------------------------------------------------
*
- * Tcl_ContinueObjCmd -
+ * Tcl_ContinueObjCmd --
*
- * This procedure is invoked to process the "continue" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "continue" Tcl command. See
+ * the user documentation for details on what it does.
*
- * With the bytecode compiler, this procedure is only called when
- * a command name is computed at runtime, and is "continue" or the name
- * to which "continue" was renamed: e.g., "set z continue; $z"
+ * With the bytecode compiler, this procedure is only called when a
+ * command name is computed at runtime, and is "continue" or the name to
+ * which "continue" was renamed: e.g., "set z continue; $z"
*
* Results:
* A standard Tcl result.
@@ -390,11 +395,11 @@ Tcl_ConcatObjCmd(dummy, interp, objc, objv)
/* ARGSUSED */
int
-Tcl_ContinueObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_ContinueObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
if (objc != 1) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
@@ -420,29 +425,25 @@ Tcl_ContinueObjCmd(dummy, interp, objc, objv)
*/
int
-Tcl_EncodingObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_EncodingObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- int index, length;
- Tcl_Encoding encoding;
- char *string;
- Tcl_DString ds;
- Tcl_Obj *resultPtr;
+ int index;
static CONST char *optionStrings[] = {
- "convertfrom", "convertto", "names", "system",
+ "convertfrom", "convertto", "dirs", "names", "system",
NULL
};
enum options {
- ENC_CONVERTFROM, ENC_CONVERTTO, ENC_NAMES, ENC_SYSTEM
+ ENC_CONVERTFROM, ENC_CONVERTTO, ENC_DIRS, ENC_NAMES, ENC_SYSTEM
};
if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
- return TCL_ERROR;
+ Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
+ return TCL_ERROR;
}
if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
&index) != TCL_OK) {
@@ -450,79 +451,121 @@ Tcl_EncodingObjCmd(dummy, interp, objc, objv)
}
switch ((enum options) index) {
- case ENC_CONVERTTO:
- case ENC_CONVERTFROM: {
- Tcl_Obj *data;
- if (objc == 3) {
- encoding = Tcl_GetEncoding(interp, NULL);
- data = objv[2];
- } else if (objc == 4) {
- if (TclGetEncodingFromObj(interp, objv[2], &encoding)
- != TCL_OK) {
- return TCL_ERROR;
- }
- data = objv[3];
- } else {
- Tcl_WrongNumArgs(interp, 2, objv, "?encoding? data");
+ case ENC_CONVERTTO:
+ case ENC_CONVERTFROM: {
+ Tcl_Obj *data;
+ Tcl_DString ds;
+ Tcl_Encoding encoding;
+ int length;
+ char *stringPtr;
+
+ if (objc == 3) {
+ encoding = Tcl_GetEncoding(interp, NULL);
+ data = objv[2];
+ } else if (objc == 4) {
+ if (Tcl_GetEncodingFromObj(interp, objv[2], &encoding) != TCL_OK) {
return TCL_ERROR;
}
-
- if ((enum options) index == ENC_CONVERTFROM) {
- /*
- * Treat the string as binary data.
- */
+ data = objv[3];
+ } else {
+ Tcl_WrongNumArgs(interp, 2, objv, "?encoding? data");
+ return TCL_ERROR;
+ }
- string = (char *) Tcl_GetByteArrayFromObj(data, &length);
- Tcl_ExternalToUtfDString(encoding, string, length, &ds);
+ if ((enum options) index == ENC_CONVERTFROM) {
+ /*
+ * Treat the string as binary data.
+ */
- /*
- * Note that we cannot use Tcl_DStringResult here because
- * it will truncate the string at the first null byte.
- */
+ stringPtr = (char *) Tcl_GetByteArrayFromObj(data, &length);
+ Tcl_ExternalToUtfDString(encoding, stringPtr, length, &ds);
- Tcl_SetStringObj(Tcl_GetObjResult(interp),
- Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
- Tcl_DStringFree(&ds);
- } else {
- /*
- * Store the result as binary data.
- */
+ /*
+ * Note that we cannot use Tcl_DStringResult here because it will
+ * truncate the string at the first null byte.
+ */
- string = Tcl_GetStringFromObj(data, &length);
- Tcl_UtfToExternalDString(encoding, string, length, &ds);
- resultPtr = Tcl_GetObjResult(interp);
- Tcl_SetByteArrayObj(resultPtr,
- (unsigned char *) Tcl_DStringValue(&ds),
- Tcl_DStringLength(&ds));
- Tcl_DStringFree(&ds);
- }
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)));
+ Tcl_DStringFree(&ds);
+ } else {
+ /*
+ * Store the result as binary data.
+ */
- Tcl_FreeEncoding(encoding);
- break;
+ stringPtr = TclGetStringFromObj(data, &length);
+ Tcl_UtfToExternalDString(encoding, stringPtr, length, &ds);
+ Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(
+ (unsigned char *) Tcl_DStringValue(&ds),
+ Tcl_DStringLength(&ds)));
+ Tcl_DStringFree(&ds);
}
- case ENC_NAMES: {
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return TCL_ERROR;
- }
- Tcl_GetEncodingNames(interp);
- break;
+
+ Tcl_FreeEncoding(encoding);
+ break;
+ }
+ case ENC_DIRS:
+ return EncodingDirsObjCmd(dummy, interp, objc-1, objv+1);
+ case ENC_NAMES:
+ if (objc > 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
}
- case ENC_SYSTEM: {
- if (objc > 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?encoding?");
- return TCL_ERROR;
- }
- if (objc == 2) {
- Tcl_SetStringObj(Tcl_GetObjResult(interp),
- Tcl_GetEncodingName(NULL), -1);
- } else {
- return Tcl_SetSystemEncoding(interp,
- Tcl_GetStringFromObj(objv[2], NULL));
- }
- break;
+ Tcl_GetEncodingNames(interp);
+ break;
+ case ENC_SYSTEM:
+ if (objc > 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?encoding?");
+ return TCL_ERROR;
+ }
+ if (objc == 2) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ Tcl_GetEncodingName(NULL), -1));
+ } else {
+ return Tcl_SetSystemEncoding(interp, TclGetString(objv[2]));
}
+ break;
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * EncodingDirsObjCmd --
+ *
+ * This command manipulates the encoding search path.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * Can set the encoding search path.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+EncodingDirsObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
+{
+ if (objc > 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "?dirList?");
+ return TCL_ERROR;
}
+ if (objc == 1) {
+ 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);
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, objv[1]);
return TCL_OK;
}
@@ -531,8 +574,8 @@ Tcl_EncodingObjCmd(dummy, interp, objc, objv)
*
* Tcl_ErrorObjCmd --
*
- * This procedure is invoked to process the "error" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "error" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl object result.
@@ -545,36 +588,35 @@ Tcl_EncodingObjCmd(dummy, interp, objc, objv)
/* ARGSUSED */
int
-Tcl_ErrorObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_ErrorObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- Interp *iPtr = (Interp *) interp;
- char *info;
- int infoLen;
+ Tcl_Obj *options, *optName;
if ((objc < 2) || (objc > 4)) {
Tcl_WrongNumArgs(interp, 1, objv, "message ?errorInfo? ?errorCode?");
return TCL_ERROR;
}
-
- if (objc >= 3) { /* process the optional info argument */
- info = Tcl_GetStringFromObj(objv[2], &infoLen);
- if (infoLen > 0) {
- Tcl_AddObjErrorInfo(interp, info, infoLen);
- iPtr->flags |= ERR_ALREADY_LOGGED;
- }
+
+ TclNewLiteralStringObj(options, "-code error -level 0");
+
+ if (objc >= 3) { /* Process the optional info argument */
+ TclNewLiteralStringObj(optName, "-errorinfo");
+ Tcl_ListObjAppendElement(NULL, options, optName);
+ Tcl_ListObjAppendElement(NULL, options, objv[2]);
}
-
- if (objc == 4) {
- Tcl_SetVar2Ex(interp, "errorCode", NULL, objv[3], TCL_GLOBAL_ONLY);
- iPtr->flags |= ERROR_CODE_SET;
+
+ if (objc >= 4) { /* Process the optional code argument */
+ TclNewLiteralStringObj(optName, "-errorcode");
+ Tcl_ListObjAppendElement(NULL, options, optName);
+ Tcl_ListObjAppendElement(NULL, options, objv[3]);
}
-
+
Tcl_SetObjResult(interp, objv[1]);
- return TCL_ERROR;
+ return Tcl_SetReturnOptions(interp, options);
}
/*
@@ -582,7 +624,7 @@ Tcl_ErrorObjCmd(dummy, interp, objc, objv)
*
* Tcl_EvalObjCmd --
*
- * This object-based procedure is invoked to process the "eval" Tcl
+ * This object-based procedure is invoked to process the "eval" Tcl
* command. See the user documentation for details on what it does.
*
* Results:
@@ -596,53 +638,50 @@ Tcl_ErrorObjCmd(dummy, interp, objc, objv)
/* ARGSUSED */
int
-Tcl_EvalObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_EvalObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
int result;
register Tcl_Obj *objPtr;
-#ifdef TCL_TIP280
- Interp* iPtr = (Interp*) interp;
-#endif
+ Interp *iPtr = (Interp *) interp;
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "arg ?arg ...?");
return TCL_ERROR;
}
-
+
if (objc == 2) {
-#ifndef TCL_TIP280
- result = Tcl_EvalObjEx(interp, objv[1], TCL_EVAL_DIRECT);
-#else
- /* TIP #280. Make argument location available to eval'd script */
+ /*
+ * TIP #280. Make argument location available to eval'd script.
+ */
+
CmdFrame* invoker = iPtr->cmdFramePtr;
int word = 1;
TclArgumentGet (interp, objv[1], &invoker, &word);
+
result = TclEvalObjEx(interp, objv[1], TCL_EVAL_DIRECT,
- invoker, word);
-#endif
+ invoker, word);
} else {
/*
* More than one argument: concatenate them together with spaces
- * between, then evaluate the result. Tcl_EvalObjEx will delete
- * the object when it decrements its refcount after eval'ing it.
+ * between, then evaluate the result. Tcl_EvalObjEx will delete the
+ * object when it decrements its refcount after eval'ing it.
*/
- objPtr = Tcl_ConcatObj(objc-1, objv+1);
-#ifndef TCL_TIP280
- result = Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_DIRECT);
-#else
- /* TIP #280. Make invoking context available to eval'd script */
+
+ objPtr = Tcl_ConcatObj(objc-1, objv+1);
+
+ /*
+ * TIP #280. Make invoking context available to eval'd script.
+ */
+
result = TclEvalObjEx(interp, objPtr, TCL_EVAL_DIRECT, NULL, 0);
-#endif
}
if (result == TCL_ERROR) {
- char msg[32 + TCL_INTEGER_SPACE];
-
- sprintf(msg, "\n (\"eval\" body line %d)", interp->errorLine);
- Tcl_AddObjErrorInfo(interp, msg, -1);
+ Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+ "\n (\"eval\" body line %d)", interp->errorLine));
}
return result;
}
@@ -652,8 +691,8 @@ Tcl_EvalObjCmd(dummy, interp, objc, objv)
*
* Tcl_ExitObjCmd --
*
- * This procedure is invoked to process the "exit" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "exit" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl object result.
@@ -666,11 +705,11 @@ Tcl_EvalObjCmd(dummy, interp, objc, objv)
/* ARGSUSED */
int
-Tcl_ExitObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_ExitObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
int value;
@@ -678,7 +717,7 @@ Tcl_ExitObjCmd(dummy, interp, objc, objv)
Tcl_WrongNumArgs(interp, 1, objv, "?returnCode?");
return TCL_ERROR;
}
-
+
if (objc == 1) {
value = 0;
} else if (Tcl_GetIntFromObj(interp, objv[1], &value) != TCL_OK) {
@@ -686,7 +725,7 @@ Tcl_ExitObjCmd(dummy, interp, objc, objv)
}
Tcl_Exit(value);
/*NOTREACHED*/
- return TCL_OK; /* Better not ever reach this! */
+ return TCL_OK; /* Better not ever reach this! */
}
/*
@@ -698,8 +737,8 @@ Tcl_ExitObjCmd(dummy, interp, objc, objv)
* command. See the user documentation for details on what it does.
*
* With the bytecode compiler, this procedure is called in two
- * circumstances: 1) to execute expr commands that are too complicated
- * or too unsafe to try compiling directly into an inline sequence of
+ * circumstances: 1) to execute expr commands that are too complicated or
+ * too unsafe to try compiling directly into an inline sequence of
* instructions, and 2) to execute commands where the command name is
* computed at runtime and is "expr" or the name to which "expr" was
* renamed (e.g., "set z expr; $z 2+3")
@@ -715,16 +754,14 @@ Tcl_ExitObjCmd(dummy, interp, objc, objv)
/* ARGSUSED */
int
-Tcl_ExprObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
-{
- register Tcl_Obj *objPtr;
+Tcl_ExprObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
+{
Tcl_Obj *resultPtr;
- register char *bytes;
- int length, i, result;
+ int result;
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "arg ?arg ...?");
@@ -733,42 +770,18 @@ Tcl_ExprObjCmd(dummy, interp, objc, objv)
if (objc == 2) {
result = Tcl_ExprObj(interp, objv[1], &resultPtr);
- if (result == TCL_OK) {
- Tcl_SetObjResult(interp, resultPtr);
- Tcl_DecrRefCount(resultPtr); /* done with the result object */
- }
- return result;
- }
-
- /*
- * Create a new object holding the concatenated argument strings.
- */
-
- /*** QUESTION: Do we need to copy the slow way? ***/
- bytes = Tcl_GetStringFromObj(objv[1], &length);
- objPtr = Tcl_NewStringObj(bytes, length);
- Tcl_IncrRefCount(objPtr);
- for (i = 2; i < objc; i++) {
- Tcl_AppendToObj(objPtr, " ", 1);
- bytes = Tcl_GetStringFromObj(objv[i], &length);
- Tcl_AppendToObj(objPtr, bytes, length);
+ } else {
+ Tcl_Obj *objPtr = Tcl_ConcatObj(objc-1, objv+1);
+ Tcl_IncrRefCount(objPtr);
+ result = Tcl_ExprObj(interp, objPtr, &resultPtr);
+ Tcl_DecrRefCount(objPtr);
}
- /*
- * Evaluate the concatenated string object.
- */
-
- result = Tcl_ExprObj(interp, objPtr, &resultPtr);
if (result == TCL_OK) {
Tcl_SetObjResult(interp, resultPtr);
- Tcl_DecrRefCount(resultPtr); /* done with the result object */
+ Tcl_DecrRefCount(resultPtr); /* Done with the result object */
}
- /*
- * Free allocated resources.
- */
-
- Tcl_DecrRefCount(objPtr);
return result;
}
@@ -777,12 +790,11 @@ Tcl_ExprObjCmd(dummy, interp, objc, objv)
*
* Tcl_FileObjCmd --
*
- * This procedure is invoked to process the "file" Tcl command.
- * See the user documentation for details on what it does.
- * PLEASE NOTE THAT THIS FAILS WITH FILENAMES AND PATHS WITH
- * EMBEDDED NULLS, WHICH COULD THEORETICALLY HAPPEN ON A MAC.
- * With the object-based Tcl_FS APIs, the above NOTE may no
- * longer be true. In any case this assertion should be tested.
+ * This procedure is invoked to process the "file" Tcl command. See the
+ * user documentation for details on what it does. PLEASE NOTE THAT THIS
+ * FAILS WITH FILENAMES AND PATHS WITH EMBEDDED NULLS. With the
+ * object-based Tcl_FS APIs, the above NOTE may no longer be true. In any
+ * case this assertion should be tested.
*
* Results:
* A standard Tcl result.
@@ -795,610 +807,569 @@ Tcl_ExprObjCmd(dummy, interp, objc, objv)
/* ARGSUSED */
int
-Tcl_FileObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_FileObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- int index;
+ int index, value;
+ Tcl_StatBuf buf;
+ struct utimbuf tval;
-/*
- * This list of constants should match the fileOption string array below.
- */
+ /*
+ * This list of constants should match the fileOption string array below.
+ */
static CONST char *fileOptions[] = {
"atime", "attributes", "channels", "copy",
"delete",
"dirname", "executable", "exists", "extension",
"isdirectory", "isfile", "join", "link",
- "lstat", "mtime", "mkdir", "nativename",
+ "lstat", "mtime", "mkdir", "nativename",
"normalize", "owned",
"pathtype", "readable", "readlink", "rename",
- "rootname", "separator", "size", "split",
- "stat", "system",
+ "rootname", "separator", "size", "split",
+ "stat", "system",
"tail", "type", "volumes", "writable",
- (char *) NULL
+ NULL
};
enum options {
FCMD_ATIME, FCMD_ATTRIBUTES, FCMD_CHANNELS, FCMD_COPY,
FCMD_DELETE,
FCMD_DIRNAME, FCMD_EXECUTABLE, FCMD_EXISTS, FCMD_EXTENSION,
- FCMD_ISDIRECTORY, FCMD_ISFILE, FCMD_JOIN, FCMD_LINK,
- FCMD_LSTAT, FCMD_MTIME, FCMD_MKDIR, FCMD_NATIVENAME,
- FCMD_NORMALIZE, FCMD_OWNED,
+ FCMD_ISDIRECTORY, FCMD_ISFILE, FCMD_JOIN, FCMD_LINK,
+ FCMD_LSTAT, FCMD_MTIME, FCMD_MKDIR, FCMD_NATIVENAME,
+ FCMD_NORMALIZE, FCMD_OWNED,
FCMD_PATHTYPE, FCMD_READABLE, FCMD_READLINK, FCMD_RENAME,
- FCMD_ROOTNAME, FCMD_SEPARATOR, FCMD_SIZE, FCMD_SPLIT,
- FCMD_STAT, FCMD_SYSTEM,
+ FCMD_ROOTNAME, FCMD_SEPARATOR, FCMD_SIZE, FCMD_SPLIT,
+ FCMD_STAT, FCMD_SYSTEM,
FCMD_TAIL, FCMD_TYPE, FCMD_VOLUMES, FCMD_WRITABLE
};
if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
- return TCL_ERROR;
+ Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
+ return TCL_ERROR;
}
if (Tcl_GetIndexFromObj(interp, objv[1], fileOptions, "option", 0,
&index) != TCL_OK) {
- return TCL_ERROR;
+ return TCL_ERROR;
}
switch ((enum options) index) {
- case FCMD_ATIME: {
- Tcl_StatBuf buf;
- struct utimbuf tval;
- if ((objc < 3) || (objc > 4)) {
- Tcl_WrongNumArgs(interp, 2, objv, "name ?time?");
- return TCL_ERROR;
- }
- if (GetStatBuf(interp, objv[2], Tcl_FSStat, &buf) != TCL_OK) {
+ case FCMD_ATIME:
+ case FCMD_MTIME:
+ if ((objc < 3) || (objc > 4)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "name ?time?");
+ return TCL_ERROR;
+ }
+ if (GetStatBuf(interp, objv[2], Tcl_FSStat, &buf) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (objc == 4) {
+ /*
+ * Need separate variable for reading longs from an object on
+ * 64-bit platforms. [Bug #698146]
+ */
+
+ long newTime;
+
+ if (TclGetLongFromObj(interp, objv[3], &newTime) != TCL_OK) {
return TCL_ERROR;
}
- if (objc == 4) {
- long newTime;
- if (Tcl_GetLongFromObj(interp, objv[3], &newTime) != TCL_OK) {
- return TCL_ERROR;
- }
+ if (index == FCMD_ATIME) {
tval.actime = newTime;
tval.modtime = buf.st_mtime;
- if (Tcl_FSUtime(objv[2], &tval) != 0) {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "could not set access time for file \"",
- Tcl_GetString(objv[2]), "\": ",
- Tcl_PosixError(interp), (char *) NULL);
- return TCL_ERROR;
- }
- /*
- * Do another stat to ensure that the we return the
- * new recognized atime - hopefully the same as the
- * one we sent in. However, fs's like FAT don't
- * even know what atime is.
- */
- if (GetStatBuf(interp, objv[2], Tcl_FSStat, &buf) != TCL_OK) {
- return TCL_ERROR;
- }
+ } else { /* index == FCMD_MTIME */
+ tval.actime = buf.st_atime;
+ tval.modtime = newTime;
}
- Tcl_SetLongObj(Tcl_GetObjResult(interp), (long) buf.st_atime);
- return TCL_OK;
- }
- case FCMD_ATTRIBUTES: {
- return TclFileAttrsCmd(interp, objc, objv);
- }
- case FCMD_CHANNELS: {
- if ((objc < 2) || (objc > 3)) {
- Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");
+
+ if (Tcl_FSUtime(objv[2], &tval) != 0) {
+ Tcl_AppendResult(interp, "could not set ",
+ (index == FCMD_ATIME ? "access" : "modification"),
+ " time for file \"", TclGetString(objv[2]), "\": ",
+ Tcl_PosixError(interp), NULL);
return TCL_ERROR;
}
- return Tcl_GetChannelNamesEx(interp,
- ((objc == 2) ? NULL : Tcl_GetString(objv[2])));
- }
- case FCMD_COPY: {
- return TclFileCopyCmd(interp, objc, objv);
- }
- case FCMD_DELETE: {
- return TclFileDeleteCmd(interp, objc, objv);
- }
- case FCMD_DIRNAME: {
- Tcl_Obj *dirPtr;
- if (objc != 3) {
- goto only3Args;
- }
- dirPtr = TclFileDirname(interp, objv[2]);
- if (dirPtr == NULL) {
- return TCL_ERROR;
- } else {
- Tcl_SetObjResult(interp, dirPtr);
- Tcl_DecrRefCount(dirPtr);
- return TCL_OK;
+
+ /*
+ * Do another stat to ensure that the we return the new recognized
+ * atime - hopefully the same as the one we sent in. However, fs's
+ * like FAT don't even know what atime is.
+ */
+
+ if (GetStatBuf(interp, objv[2], Tcl_FSStat, &buf) != TCL_OK) {
+ return TCL_ERROR;
}
}
- case FCMD_EXECUTABLE: {
- if (objc != 3) {
- goto only3Args;
- }
- return CheckAccess(interp, objv[2], X_OK);
+
+ Tcl_SetObjResult(interp, Tcl_NewLongObj((long)
+ (index == FCMD_ATIME ? buf.st_atime : buf.st_mtime)));
+ return TCL_OK;
+ case FCMD_ATTRIBUTES:
+ return TclFileAttrsCmd(interp, objc, objv);
+ case FCMD_CHANNELS:
+ if ((objc < 2) || (objc > 3)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");
+ return TCL_ERROR;
}
- case FCMD_EXISTS: {
- if (objc != 3) {
- goto only3Args;
- }
- return CheckAccess(interp, objv[2], F_OK);
+ return Tcl_GetChannelNamesEx(interp,
+ ((objc == 2) ? NULL : TclGetString(objv[2])));
+ case FCMD_COPY:
+ return TclFileCopyCmd(interp, objc, objv);
+ case FCMD_DELETE:
+ return TclFileDeleteCmd(interp, objc, objv);
+ case FCMD_DIRNAME: {
+ Tcl_Obj *dirPtr;
+
+ if (objc != 3) {
+ goto only3Args;
}
- case FCMD_EXTENSION: {
- char *fileName, *extension;
- if (objc != 3) {
- goto only3Args;
- }
- fileName = Tcl_GetString(objv[2]);
- extension = TclGetExtension(fileName);
- if (extension != NULL) {
- Tcl_SetStringObj(Tcl_GetObjResult(interp), extension, -1);
- }
+ dirPtr = TclPathPart(interp, objv[2], TCL_PATH_DIRNAME);
+ if (dirPtr == NULL) {
+ return TCL_ERROR;
+ } else {
+ Tcl_SetObjResult(interp, dirPtr);
+ Tcl_DecrRefCount(dirPtr);
return TCL_OK;
}
- case FCMD_ISDIRECTORY: {
- int value;
- Tcl_StatBuf buf;
-
- if (objc != 3) {
- goto only3Args;
- }
- value = 0;
- if (GetStatBuf(NULL, objv[2], Tcl_FSStat, &buf) == TCL_OK) {
- value = S_ISDIR(buf.st_mode);
- }
- Tcl_SetBooleanObj(Tcl_GetObjResult(interp), value);
+ }
+ case FCMD_EXECUTABLE:
+ if (objc != 3) {
+ goto only3Args;
+ }
+ return CheckAccess(interp, objv[2], X_OK);
+ case FCMD_EXISTS:
+ if (objc != 3) {
+ goto only3Args;
+ }
+ return CheckAccess(interp, objv[2], F_OK);
+ case FCMD_EXTENSION: {
+ Tcl_Obj *ext;
+
+ if (objc != 3) {
+ goto only3Args;
+ }
+ ext = TclPathPart(interp, objv[2], TCL_PATH_EXTENSION);
+ if (ext != NULL) {
+ Tcl_SetObjResult(interp, ext);
+ Tcl_DecrRefCount(ext);
return TCL_OK;
+ } else {
+ return TCL_ERROR;
}
- case FCMD_ISFILE: {
- int value;
- Tcl_StatBuf buf;
-
- if (objc != 3) {
- goto only3Args;
- }
- value = 0;
- if (GetStatBuf(NULL, objv[2], Tcl_FSStat, &buf) == TCL_OK) {
- value = S_ISREG(buf.st_mode);
- }
- Tcl_SetBooleanObj(Tcl_GetObjResult(interp), value);
- return TCL_OK;
+ }
+ case FCMD_ISDIRECTORY:
+ if (objc != 3) {
+ goto only3Args;
+ }
+ value = 0;
+ if (GetStatBuf(NULL, objv[2], Tcl_FSStat, &buf) == TCL_OK) {
+ value = S_ISDIR(buf.st_mode);
+ }
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(value));
+ return TCL_OK;
+ case FCMD_ISFILE:
+ if (objc != 3) {
+ goto only3Args;
}
- case FCMD_JOIN: {
- Tcl_Obj *resObj;
+ value = 0;
+ if (GetStatBuf(NULL, objv[2], Tcl_FSStat, &buf) == TCL_OK) {
+ value = S_ISREG(buf.st_mode);
+ }
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(value));
+ return TCL_OK;
+ case FCMD_OWNED:
+ if (objc != 3) {
+ goto only3Args;
+ }
+ value = 0;
+ if (GetStatBuf(NULL, objv[2], Tcl_FSStat, &buf) == TCL_OK) {
+ /*
+ * For Windows, there are no user ids associated with a file, so
+ * we always return 1.
+ */
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "name ?name ...?");
- return TCL_ERROR;
- }
- resObj = Tcl_FSJoinToPath(NULL, objc - 2, objv + 2);
- Tcl_SetObjResult(interp, resObj);
- return TCL_OK;
+#if defined(__WIN32__) || defined(__CYGWIN__)
+ value = 1;
+#else
+ value = (geteuid() == buf.st_uid);
+#endif
}
- case FCMD_LINK: {
- Tcl_Obj *contents;
- int index;
-
- if (objc < 3 || objc > 5) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-linktype? linkname ?target?");
- return TCL_ERROR;
- }
-
- /* Index of the 'source' argument */
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(value));
+ return TCL_OK;
+ case FCMD_JOIN: {
+ Tcl_Obj *resObj;
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "name ?name ...?");
+ return TCL_ERROR;
+ }
+ resObj = Tcl_FSJoinToPath(NULL, objc - 2, objv + 2);
+ Tcl_SetObjResult(interp, resObj);
+ return TCL_OK;
+ }
+ case FCMD_LINK: {
+ Tcl_Obj *contents;
+ int index;
+
+ if (objc < 3 || objc > 5) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?-linktype? linkname ?target?");
+ return TCL_ERROR;
+ }
+
+ /*
+ * Index of the 'source' argument.
+ */
+
+ if (objc == 5) {
+ index = 3;
+ } else {
+ index = 2;
+ }
+
+ if (objc > 3) {
+ int linkAction;
if (objc == 5) {
- index = 3;
- } else {
- index = 2;
- }
-
- if (objc > 3) {
- int linkAction;
- if (objc == 5) {
- /* We have a '-linktype' argument */
- static CONST char *linkTypes[] = {
- "-symbolic", "-hard", NULL
- };
- if (Tcl_GetIndexFromObj(interp, objv[2], linkTypes,
- "switch", 0, &linkAction) != TCL_OK) {
- return TCL_ERROR;
- }
- if (linkAction == 0) {
- linkAction = TCL_CREATE_SYMBOLIC_LINK;
- } else {
- linkAction = TCL_CREATE_HARD_LINK;
- }
- } else {
- linkAction = TCL_CREATE_SYMBOLIC_LINK|TCL_CREATE_HARD_LINK;
- }
- if (Tcl_FSConvertToPathType(interp, objv[index]) != TCL_OK) {
+ /*
+ * We have a '-linktype' argument.
+ */
+
+ static CONST char *linkTypes[] = {
+ "-symbolic", "-hard", NULL
+ };
+ if (Tcl_GetIndexFromObj(interp, objv[2], linkTypes, "switch",
+ 0, &linkAction) != TCL_OK) {
return TCL_ERROR;
}
- /* Create link from source to target */
- contents = Tcl_FSLink(objv[index], objv[index+1], linkAction);
- if (contents == NULL) {
- /*
- * We handle two common error cases specially, and
- * for all other errors, we use the standard posix
- * error message.
- */
- if (errno == EEXIST) {
- Tcl_AppendResult(interp, "could not create new link \"",
- Tcl_GetString(objv[index]),
- "\": that path already exists", (char *) NULL);
- } else if (errno == ENOENT) {
- Tcl_AppendResult(interp, "could not create new link \"",
- Tcl_GetString(objv[index]),
- "\" since target \"",
- Tcl_GetString(objv[index+1]),
- "\" doesn't exist",
- (char *) NULL);
- } else {
- Tcl_AppendResult(interp, "could not create new link \"",
- Tcl_GetString(objv[index]), "\" pointing to \"",
- Tcl_GetString(objv[index+1]), "\": ",
- Tcl_PosixError(interp), (char *) NULL);
- }
- return TCL_ERROR;
+ if (linkAction == 0) {
+ linkAction = TCL_CREATE_SYMBOLIC_LINK;
+ } else {
+ linkAction = TCL_CREATE_HARD_LINK;
}
} else {
- if (Tcl_FSConvertToPathType(interp, objv[index]) != TCL_OK) {
- return TCL_ERROR;
- }
- /* Read link */
- contents = Tcl_FSLink(objv[index], NULL, 0);
- if (contents == NULL) {
- Tcl_AppendResult(interp, "could not read link \"",
- Tcl_GetString(objv[index]), "\": ",
- Tcl_PosixError(interp), (char *) NULL);
- return TCL_ERROR;
- }
+ linkAction = TCL_CREATE_SYMBOLIC_LINK|TCL_CREATE_HARD_LINK;
}
- Tcl_SetObjResult(interp, contents);
- if (objc == 3) {
- /*
- * If we are reading a link, we need to free this
- * result refCount. If we are creating a link, this
- * will just be objv[index+1], and so we don't own it.
- */
- Tcl_DecrRefCount(contents);
- }
- return TCL_OK;
- }
- case FCMD_LSTAT: {
- char *varName;
- Tcl_StatBuf buf;
-
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "name varName");
- return TCL_ERROR;
- }
- if (GetStatBuf(interp, objv[2], Tcl_FSLstat, &buf) != TCL_OK) {
+ if (Tcl_FSConvertToPathType(interp, objv[index]) != TCL_OK) {
return TCL_ERROR;
}
- varName = Tcl_GetString(objv[3]);
- return StoreStatData(interp, varName, &buf);
- }
- case FCMD_MTIME: {
- Tcl_StatBuf buf;
- struct utimbuf tval;
- if ((objc < 3) || (objc > 4)) {
- Tcl_WrongNumArgs(interp, 2, objv, "name ?time?");
- return TCL_ERROR;
- }
- if (GetStatBuf(interp, objv[2], Tcl_FSStat, &buf) != TCL_OK) {
- return TCL_ERROR;
- }
- if (objc == 4) {
- long newTime;
+ /*
+ * Create link from source to target.
+ */
- if (Tcl_GetLongFromObj(interp, objv[3], &newTime) != TCL_OK) {
- return TCL_ERROR;
- }
- tval.actime = buf.st_atime;
- tval.modtime = newTime;
- if (Tcl_FSUtime(objv[2], &tval) != 0) {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "could not set modification time for file \"",
- Tcl_GetString(objv[2]), "\": ",
- Tcl_PosixError(interp), (char *) NULL);
- return TCL_ERROR;
- }
+ contents = Tcl_FSLink(objv[index], objv[index+1], linkAction);
+ if (contents == NULL) {
/*
- * Do another stat to ensure that the we return the
- * new recognized atime - hopefully the same as the
- * one we sent in. However, fs's like FAT don't
- * even know what atime is.
+ * We handle three common error cases specially, and for all
+ * other errors, we use the standard posix error message.
*/
- if (GetStatBuf(interp, objv[2], Tcl_FSStat, &buf) != TCL_OK) {
- return TCL_ERROR;
+
+ if (errno == EEXIST) {
+ Tcl_AppendResult(interp, "could not create new link \"",
+ TclGetString(objv[index]),
+ "\": that path already exists", NULL);
+ } else if (errno == ENOENT) {
+ /*
+ * There are two cases here: either the target doesn't
+ * exist, or the directory of the src doesn't exist.
+ */
+
+ int access;
+ Tcl_Obj *dirPtr = TclPathPart(interp, objv[index],
+ TCL_PATH_DIRNAME);
+
+ if (dirPtr == NULL) {
+ return TCL_ERROR;
+ }
+ 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);
+ } else {
+ Tcl_AppendResult(interp,
+ "could not create new link \"",
+ TclGetString(objv[index]), "\": target \"",
+ TclGetString(objv[index+1]),
+ "\" doesn't exist", NULL);
+ }
+ } else {
+ Tcl_AppendResult(interp,
+ "could not create new link \"",
+ TclGetString(objv[index]), "\" pointing to \"",
+ TclGetString(objv[index+1]), "\": ",
+ Tcl_PosixError(interp), NULL);
}
- }
- Tcl_SetLongObj(Tcl_GetObjResult(interp), (long) buf.st_mtime);
- return TCL_OK;
- }
- case FCMD_MKDIR: {
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "name ?name ...?");
return TCL_ERROR;
}
- return TclFileMakeDirsCmd(interp, objc, objv);
- }
- case FCMD_NATIVENAME: {
- CONST char *fileName;
- Tcl_DString ds;
-
- if (objc != 3) {
- goto only3Args;
- }
- fileName = Tcl_GetString(objv[2]);
- fileName = Tcl_TranslateFileName(interp, fileName, &ds);
- if (fileName == NULL) {
+ } else {
+ if (Tcl_FSConvertToPathType(interp, objv[index]) != TCL_OK) {
return TCL_ERROR;
}
- Tcl_SetStringObj(Tcl_GetObjResult(interp), fileName,
- Tcl_DStringLength(&ds));
- Tcl_DStringFree(&ds);
- return TCL_OK;
- }
- case FCMD_NORMALIZE: {
- Tcl_Obj *fileName;
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "filename");
- return TCL_ERROR;
- }
+ /*
+ * Read link
+ */
- fileName = Tcl_FSGetNormalizedPath(interp, objv[2]);
- if (fileName == NULL) {
+ contents = Tcl_FSLink(objv[index], NULL, 0);
+ if (contents == NULL) {
+ Tcl_AppendResult(interp, "could not read link \"",
+ TclGetString(objv[index]), "\": ",
+ Tcl_PosixError(interp), NULL);
return TCL_ERROR;
}
- Tcl_SetObjResult(interp, fileName);
- return TCL_OK;
}
- case FCMD_OWNED: {
- int value;
- Tcl_StatBuf buf;
-
- if (objc != 3) {
- goto only3Args;
- }
- value = 0;
- if (GetStatBuf(NULL, objv[2], Tcl_FSStat, &buf) == TCL_OK) {
- /*
- * For Windows and Macintosh, there are no user ids
- * associated with a file, so we always return 1.
- */
+ Tcl_SetObjResult(interp, contents);
+ if (objc == 3) {
+ /*
+ * If we are reading a link, we need to free this result refCount.
+ * If we are creating a link, this will just be objv[index+1], and
+ * so we don't own it.
+ */
-#if defined(__WIN32__) || defined(MAC_TCL) || defined(__CYGWIN__)
- value = 1;
-#else
- value = (geteuid() == buf.st_uid);
-#endif
- }
- Tcl_SetBooleanObj(Tcl_GetObjResult(interp), value);
- return TCL_OK;
+ Tcl_DecrRefCount(contents);
}
- case FCMD_PATHTYPE: {
- if (objc != 3) {
- goto only3Args;
- }
- switch (Tcl_FSGetPathType(objv[2])) {
- case TCL_PATH_ABSOLUTE:
- Tcl_SetStringObj(Tcl_GetObjResult(interp), "absolute", -1);
- break;
- case TCL_PATH_RELATIVE:
- Tcl_SetStringObj(Tcl_GetObjResult(interp), "relative", -1);
- break;
- case TCL_PATH_VOLUME_RELATIVE:
- Tcl_SetStringObj(Tcl_GetObjResult(interp),
- "volumerelative", -1);
- break;
- }
- return TCL_OK;
+ return TCL_OK;
+ }
+ case FCMD_LSTAT:
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "name varName");
+ return TCL_ERROR;
}
- case FCMD_READABLE: {
- if (objc != 3) {
- goto only3Args;
- }
- return CheckAccess(interp, objv[2], R_OK);
+ if (GetStatBuf(interp, objv[2], Tcl_FSLstat, &buf) != TCL_OK) {
+ return TCL_ERROR;
}
- case FCMD_READLINK: {
- Tcl_Obj *contents;
-
- if (objc != 3) {
- goto only3Args;
- }
-
- if (Tcl_FSConvertToPathType(interp, objv[2]) != TCL_OK) {
- return TCL_ERROR;
- }
-
- contents = Tcl_FSLink(objv[2], NULL, 0);
+ return StoreStatData(interp, objv[3], &buf);
+ case FCMD_STAT:
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "name varName");
+ return TCL_ERROR;
+ }
+ if (GetStatBuf(interp, objv[2], Tcl_FSStat, &buf) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ return StoreStatData(interp, objv[3], &buf);
+ case FCMD_SIZE:
+ if (objc != 3) {
+ goto only3Args;
+ }
+ if (GetStatBuf(interp, objv[2], Tcl_FSStat, &buf) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp,
+ Tcl_NewWideIntObj((Tcl_WideInt) buf.st_size));
+ return TCL_OK;
+ case FCMD_TYPE:
+ if (objc != 3) {
+ goto only3Args;
+ }
+ if (GetStatBuf(interp, objv[2], Tcl_FSLstat, &buf) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ GetTypeFromMode((unsigned short) buf.st_mode), -1));
+ return TCL_OK;
+ case FCMD_MKDIR:
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "name ?name ...?");
+ return TCL_ERROR;
+ }
+ return TclFileMakeDirsCmd(interp, objc, objv);
+ case FCMD_NATIVENAME: {
+ CONST char *fileName;
+ Tcl_DString ds;
- if (contents == NULL) {
- Tcl_AppendResult(interp, "could not readlink \"",
- Tcl_GetString(objv[2]), "\": ",
- Tcl_PosixError(interp), (char *) NULL);
- return TCL_ERROR;
- }
- Tcl_SetObjResult(interp, contents);
- Tcl_DecrRefCount(contents);
- return TCL_OK;
+ if (objc != 3) {
+ goto only3Args;
}
- case FCMD_RENAME: {
- return TclFileRenameCmd(interp, objc, objv);
+ fileName = TclGetString(objv[2]);
+ fileName = Tcl_TranslateFileName(interp, fileName, &ds);
+ if (fileName == NULL) {
+ return TCL_ERROR;
}
- case FCMD_ROOTNAME: {
- int length;
- char *fileName, *extension;
-
- if (objc != 3) {
- goto only3Args;
- }
- fileName = Tcl_GetStringFromObj(objv[2], &length);
- extension = TclGetExtension(fileName);
- if (extension == NULL) {
- Tcl_SetObjResult(interp, objv[2]);
- } else {
- Tcl_SetStringObj(Tcl_GetObjResult(interp), fileName,
- (int) (length - strlen(extension)));
- }
- return TCL_OK;
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(fileName,
+ Tcl_DStringLength(&ds)));
+ Tcl_DStringFree(&ds);
+ return TCL_OK;
+ }
+ case FCMD_NORMALIZE: {
+ Tcl_Obj *fileName;
+
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 2, objv, "filename");
+ return TCL_ERROR;
}
- case FCMD_SEPARATOR: {
- if ((objc < 2) || (objc > 3)) {
- Tcl_WrongNumArgs(interp, 2, objv, "?name?");
- return TCL_ERROR;
- }
- if (objc == 2) {
- char *separator = NULL; /* lint */
- switch (tclPlatform) {
- case TCL_PLATFORM_UNIX:
- separator = "/";
- break;
- case TCL_PLATFORM_WINDOWS:
- separator = "\\";
- break;
- case TCL_PLATFORM_MAC:
- separator = ":";
- break;
- }
- Tcl_SetObjResult(interp, Tcl_NewStringObj(separator,1));
- } else {
- Tcl_Obj *separatorObj = Tcl_FSPathSeparator(objv[2]);
- if (separatorObj != NULL) {
- Tcl_SetObjResult(interp, separatorObj);
- } else {
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj("Unrecognised path",-1));
- return TCL_ERROR;
- }
- }
- return TCL_OK;
+
+ fileName = Tcl_FSGetNormalizedPath(interp, objv[2]);
+ if (fileName == NULL) {
+ return TCL_ERROR;
}
- case FCMD_SIZE: {
- Tcl_StatBuf buf;
-
- if (objc != 3) {
- goto only3Args;
- }
- if (GetStatBuf(interp, objv[2], Tcl_FSStat, &buf) != TCL_OK) {
- return TCL_ERROR;
- }
- Tcl_SetWideIntObj(Tcl_GetObjResult(interp),
- (Tcl_WideInt) buf.st_size);
- return TCL_OK;
+ Tcl_SetObjResult(interp, fileName);
+ return TCL_OK;
+ }
+ case FCMD_PATHTYPE: {
+ Tcl_Obj *typeName;
+
+ if (objc != 3) {
+ goto only3Args;
}
- case FCMD_SPLIT: {
- if (objc != 3) {
- goto only3Args;
- }
- Tcl_SetObjResult(interp, Tcl_FSSplitPath(objv[2], NULL));
+
+ switch (Tcl_FSGetPathType(objv[2])) {
+ case TCL_PATH_ABSOLUTE:
+ TclNewLiteralStringObj(typeName, "absolute");
+ break;
+ case TCL_PATH_RELATIVE:
+ TclNewLiteralStringObj(typeName, "relative");
+ break;
+ case TCL_PATH_VOLUME_RELATIVE:
+ TclNewLiteralStringObj(typeName, "volumerelative");
+ break;
+ default:
return TCL_OK;
}
- case FCMD_STAT: {
- char *varName;
- Tcl_StatBuf buf;
-
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 1, objv, "stat name varName");
- return TCL_ERROR;
- }
- if (GetStatBuf(interp, objv[2], Tcl_FSStat, &buf) != TCL_OK) {
- return TCL_ERROR;
- }
- varName = Tcl_GetString(objv[3]);
- return StoreStatData(interp, varName, &buf);
+ Tcl_SetObjResult(interp, typeName);
+ return TCL_OK;
+ }
+ case FCMD_READABLE:
+ if (objc != 3) {
+ goto only3Args;
}
- case FCMD_SYSTEM: {
- Tcl_Obj* fsInfo;
- if (objc != 3) {
- goto only3Args;
- }
- fsInfo = Tcl_FSFileSystemInfo(objv[2]);
- if (fsInfo != NULL) {
- Tcl_SetObjResult(interp, fsInfo);
- return TCL_OK;
- } else {
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj("Unrecognised path",-1));
- return TCL_ERROR;
- }
+ return CheckAccess(interp, objv[2], R_OK);
+ case FCMD_READLINK: {
+ Tcl_Obj *contents;
+
+ if (objc != 3) {
+ goto only3Args;
}
- case FCMD_TAIL: {
- int splitElements;
- Tcl_Obj *splitPtr;
- if (objc != 3) {
- goto only3Args;
- }
- /*
- * The behaviour we want here is slightly different to
- * the standard Tcl_FSSplitPath in the handling of home
- * directories; Tcl_FSSplitPath preserves the "~" while
- * this code computes the actual full path name, if we
- * had just a single component.
- */
- splitPtr = Tcl_FSSplitPath(objv[2], &splitElements);
- if ((splitElements == 1) && (Tcl_GetString(objv[2])[0] == '~')) {
- Tcl_DecrRefCount(splitPtr);
- splitPtr = Tcl_FSGetNormalizedPath(interp, objv[2]);
- if (splitPtr == NULL) {
- return TCL_ERROR;
- }
- splitPtr = Tcl_FSSplitPath(splitPtr, &splitElements);
- }
+ if (Tcl_FSConvertToPathType(interp, objv[2]) != TCL_OK) {
+ return TCL_ERROR;
+ }
- /*
- * Return the last component, unless it is the only component,
- * and it is the root of an absolute path.
- */
+ contents = Tcl_FSLink(objv[2], NULL, 0);
- if (splitElements > 0) {
- if ((splitElements > 1)
- || (Tcl_FSGetPathType(objv[2]) == TCL_PATH_RELATIVE)) {
-
- Tcl_Obj *tail = NULL;
- Tcl_ListObjIndex(NULL, splitPtr, splitElements-1, &tail);
- Tcl_SetObjResult(interp, tail);
- }
- }
- Tcl_DecrRefCount(splitPtr);
+ if (contents == NULL) {
+ Tcl_AppendResult(interp, "could not readlink \"",
+ TclGetString(objv[2]), "\": ", Tcl_PosixError(interp),
+ NULL);
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, contents);
+ Tcl_DecrRefCount(contents);
+ return TCL_OK;
+ }
+ case FCMD_RENAME:
+ return TclFileRenameCmd(interp, objc, objv);
+ case FCMD_ROOTNAME: {
+ Tcl_Obj *root;
+
+ if (objc != 3) {
+ goto only3Args;
+ }
+ root = TclPathPart(interp, objv[2], TCL_PATH_ROOT);
+ if (root != NULL) {
+ Tcl_SetObjResult(interp, root);
+ Tcl_DecrRefCount(root);
return TCL_OK;
+ } else {
+ return TCL_ERROR;
+ }
+ }
+ case FCMD_SEPARATOR:
+ if ((objc < 2) || (objc > 3)) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?name?");
+ return TCL_ERROR;
}
- case FCMD_TYPE: {
- Tcl_StatBuf buf;
+ if (objc == 2) {
+ char *separator = NULL; /* lint */
- if (objc != 3) {
- goto only3Args;
+ switch (tclPlatform) {
+ case TCL_PLATFORM_UNIX:
+ separator = "/";
+ break;
+ case TCL_PLATFORM_WINDOWS:
+ separator = "\\";
+ break;
}
- if (GetStatBuf(interp, objv[2], Tcl_FSLstat, &buf) != TCL_OK) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(separator, 1));
+ } else {
+ Tcl_Obj *separatorObj = Tcl_FSPathSeparator(objv[2]);
+
+ if (separatorObj == NULL) {
+ Tcl_SetResult(interp, "Unrecognised path", TCL_STATIC);
return TCL_ERROR;
}
- Tcl_SetStringObj(Tcl_GetObjResult(interp),
- GetTypeFromMode((unsigned short) buf.st_mode), -1);
- return TCL_OK;
+ Tcl_SetObjResult(interp, separatorObj);
}
- case FCMD_VOLUMES: {
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return TCL_ERROR;
- }
- Tcl_SetObjResult(interp, Tcl_FSListVolumes());
- return TCL_OK;
+ return TCL_OK;
+ case FCMD_SPLIT: {
+ Tcl_Obj *res;
+
+ if (objc != 3) {
+ goto only3Args;
}
- case FCMD_WRITABLE: {
- if (objc != 3) {
- goto only3Args;
+ res = Tcl_FSSplitPath(objv[2], NULL);
+ if (res == NULL) {
+ /* How can the interp be NULL here?! DKF */
+ if (interp != NULL) {
+ Tcl_AppendResult(interp, "could not read \"",
+ TclGetString(objv[2]),
+ "\": no such file or directory", NULL);
}
- return CheckAccess(interp, objv[2], W_OK);
+ return TCL_ERROR;
}
+ Tcl_SetObjResult(interp, res);
+ return TCL_OK;
}
+ case FCMD_SYSTEM: {
+ Tcl_Obj *fsInfo;
- only3Args:
+ if (objc != 3) {
+ goto only3Args;
+ }
+ fsInfo = Tcl_FSFileSystemInfo(objv[2]);
+ if (fsInfo == NULL) {
+ Tcl_SetResult(interp, "Unrecognised path", TCL_STATIC);
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, fsInfo);
+ return TCL_OK;
+ }
+ case FCMD_TAIL: {
+ Tcl_Obj *dirPtr;
+
+ if (objc != 3) {
+ goto only3Args;
+ }
+ dirPtr = TclPathPart(interp, objv[2], TCL_PATH_TAIL);
+ if (dirPtr == NULL) {
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, dirPtr);
+ Tcl_DecrRefCount(dirPtr);
+ return TCL_OK;
+ }
+ case FCMD_VOLUMES:
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 2, objv, NULL);
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, Tcl_FSListVolumes());
+ return TCL_OK;
+ case FCMD_WRITABLE:
+ if (objc != 3) {
+ goto only3Args;
+ }
+ return CheckAccess(interp, objv[2], W_OK);
+ }
+
+ only3Args:
Tcl_WrongNumArgs(interp, 2, objv, "name");
return TCL_ERROR;
}
@@ -1408,35 +1379,35 @@ Tcl_FileObjCmd(dummy, interp, objc, objv)
*
* CheckAccess --
*
- * Utility procedure used by Tcl_FileObjCmd() to query file
- * attributes available through the access() system call.
+ * Utility procedure used by Tcl_FileObjCmd() to query file attributes
+ * available through the access() system call.
*
* Results:
- * Always returns TCL_OK. Sets interp's result to boolean true or
- * false depending on whether the file has the specified attribute.
+ * Always returns TCL_OK. Sets interp's result to boolean true or false
+ * depending on whether the file has the specified attribute.
*
* Side effects:
* None.
*
*---------------------------------------------------------------------------
*/
-
+
static int
-CheckAccess(interp, objPtr, mode)
- Tcl_Interp *interp; /* Interp for status return. Must not be
+CheckAccess(
+ Tcl_Interp *interp, /* Interp for status return. Must not be
* NULL. */
- Tcl_Obj *objPtr; /* Name of file to check. */
- int mode; /* Attribute to check; passed as argument to
+ Tcl_Obj *pathPtr, /* Name of file to check. */
+ int mode) /* Attribute to check; passed as argument to
* access(). */
{
int value;
-
- if (Tcl_FSConvertToPathType(interp, objPtr) != TCL_OK) {
+
+ if (Tcl_FSConvertToPathType(interp, pathPtr) != TCL_OK) {
value = 0;
} else {
- value = (Tcl_FSAccess(objPtr, mode) == 0);
+ value = (Tcl_FSAccess(pathPtr, mode) == 0);
}
- Tcl_SetBooleanObj(Tcl_GetObjResult(interp), value);
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(value));
return TCL_OK;
}
@@ -1446,14 +1417,14 @@ CheckAccess(interp, objPtr, mode)
*
* GetStatBuf --
*
- * Utility procedure used by Tcl_FileObjCmd() to query file
- * attributes available through the stat() or lstat() system call.
+ * Utility procedure used by Tcl_FileObjCmd() to query file attributes
+ * available through the stat() or lstat() system call.
*
* Results:
- * The return value is TCL_OK if the specified file exists and can
- * be stat'ed, TCL_ERROR otherwise. If TCL_ERROR is returned, an
- * error message is left in interp's result. If TCL_OK is returned,
- * *statPtr is filled with information about the specified file.
+ * The return value is TCL_OK if the specified file exists and can be
+ * stat'ed, TCL_ERROR otherwise. If TCL_ERROR is returned, an error
+ * message is left in interp's result. If TCL_OK is returned, *statPtr is
+ * filled with information about the specified file.
*
* Side effects:
* None.
@@ -1462,27 +1433,27 @@ CheckAccess(interp, objPtr, mode)
*/
static int
-GetStatBuf(interp, objPtr, statProc, statPtr)
- Tcl_Interp *interp; /* Interp for error return. May be NULL. */
- Tcl_Obj *objPtr; /* Path name to examine. */
- Tcl_FSStatProc *statProc; /* Either stat() or lstat() depending on
+GetStatBuf(
+ Tcl_Interp *interp, /* Interp for error return. May be NULL. */
+ Tcl_Obj *pathPtr, /* Path name to examine. */
+ Tcl_FSStatProc *statProc, /* Either stat() or lstat() depending on
* desired behavior. */
- Tcl_StatBuf *statPtr; /* Filled with info about file obtained by
+ Tcl_StatBuf *statPtr) /* Filled with info about file obtained by
* calling (*statProc)(). */
{
int status;
-
- if (Tcl_FSConvertToPathType(interp, objPtr) != TCL_OK) {
+
+ if (Tcl_FSConvertToPathType(interp, pathPtr) != TCL_OK) {
return TCL_ERROR;
}
- status = (*statProc)(objPtr, statPtr);
-
+ status = (*statProc)(pathPtr, statPtr);
+
if (status < 0) {
if (interp != NULL) {
Tcl_AppendResult(interp, "could not read \"",
- Tcl_GetString(objPtr), "\": ",
- Tcl_PosixError(interp), (char *) NULL);
+ TclGetString(pathPtr), "\": ",
+ Tcl_PosixError(interp), NULL);
}
return TCL_ERROR;
}
@@ -1494,13 +1465,13 @@ GetStatBuf(interp, objPtr, statProc, statPtr)
*
* StoreStatData --
*
- * This is a utility procedure that breaks out the fields of a
- * "stat" structure and stores them in textual form into the
- * elements of an associative array.
+ * This is a utility procedure that breaks out the fields of a "stat"
+ * structure and stores them in textual form into the elements of an
+ * associative array.
*
* Results:
- * Returns a standard Tcl return value. If an error occurs then
- * a message is left in interp's result.
+ * Returns a standard Tcl return value. If an error occurs then a message
+ * is left in interp's result.
*
* Side effects:
* Elements of the associative array given by "varName" are modified.
@@ -1509,56 +1480,59 @@ GetStatBuf(interp, objPtr, statProc, statPtr)
*/
static int
-StoreStatData(interp, varName, statPtr)
- Tcl_Interp *interp; /* Interpreter for error reports. */
- char *varName; /* Name of associative array variable
- * in which to store stat results. */
- Tcl_StatBuf *statPtr; /* Pointer to buffer containing
- * stat data to store in varName. */
+StoreStatData(
+ Tcl_Interp *interp, /* Interpreter for error reports. */
+ Tcl_Obj *varName, /* Name of associative array variable in which
+ * to store stat results. */
+ Tcl_StatBuf *statPtr) /* Pointer to buffer containing stat data to
+ * store in varName. */
{
- Tcl_Obj *var = Tcl_NewStringObj(varName, -1);
- Tcl_Obj *field = Tcl_NewObj();
- Tcl_Obj *value;
+ Tcl_Obj *field, *value;
register unsigned short mode;
/*
* Assume Tcl_ObjSetVar2() does not keep a copy of the field name!
+ *
+ * Might be a better idea to call Tcl_SetVar2Ex() instead, except we want
+ * to have an object (i.e. possibly cached) array variable name but a
+ * string element name, so no API exists. Messy.
*/
+
#define STORE_ARY(fieldName, object) \
- Tcl_SetStringObj(field, (fieldName), -1); \
- value = (object); \
- if (Tcl_ObjSetVar2(interp,var,field,value,TCL_LEAVE_ERR_MSG) == NULL) { \
- Tcl_DecrRefCount(var); \
- Tcl_DecrRefCount(field); \
- Tcl_DecrRefCount(value); \
- return TCL_ERROR; \
- }
-
- Tcl_IncrRefCount(var);
- Tcl_IncrRefCount(field);
- STORE_ARY("dev", Tcl_NewLongObj((long)statPtr->st_dev));
+ TclNewLiteralStringObj(field, fieldName); \
+ Tcl_IncrRefCount(field); \
+ value = (object); \
+ if (Tcl_ObjSetVar2(interp,varName,field,value,TCL_LEAVE_ERR_MSG)==NULL) { \
+ TclDecrRefCount(field); \
+ return TCL_ERROR; \
+ } \
+ TclDecrRefCount(field);
+
/*
- * Watch out porters; the inode is meant to be an *unsigned* value,
- * so the cast might fail when there isn't a real arithmentic 'long
- * long' type...
+ * Watch out porters; the inode is meant to be an *unsigned* value, so the
+ * cast might fail when there isn't a real arithmentic 'long long' type...
*/
- STORE_ARY("ino", Tcl_NewWideIntObj((Tcl_WideInt)statPtr->st_ino));
- STORE_ARY("nlink", Tcl_NewLongObj((long)statPtr->st_nlink));
- STORE_ARY("uid", Tcl_NewLongObj((long)statPtr->st_uid));
- STORE_ARY("gid", Tcl_NewLongObj((long)statPtr->st_gid));
- STORE_ARY("size", Tcl_NewWideIntObj((Tcl_WideInt)statPtr->st_size));
-#ifdef HAVE_ST_BLOCKS
- STORE_ARY("blocks",Tcl_NewWideIntObj((Tcl_WideInt)statPtr->st_blocks));
+
+ STORE_ARY("dev", Tcl_NewLongObj((long)statPtr->st_dev));
+ STORE_ARY("ino", Tcl_NewWideIntObj((Tcl_WideInt)statPtr->st_ino));
+ STORE_ARY("nlink", Tcl_NewLongObj((long)statPtr->st_nlink));
+ STORE_ARY("uid", Tcl_NewLongObj((long)statPtr->st_uid));
+ STORE_ARY("gid", Tcl_NewLongObj((long)statPtr->st_gid));
+ STORE_ARY("size", Tcl_NewWideIntObj((Tcl_WideInt)statPtr->st_size));
+#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
+ STORE_ARY("blocks", Tcl_NewWideIntObj((Tcl_WideInt)statPtr->st_blocks));
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+ STORE_ARY("blksize", Tcl_NewLongObj((long)statPtr->st_blksize));
#endif
- STORE_ARY("atime", Tcl_NewLongObj((long)statPtr->st_atime));
- STORE_ARY("mtime", Tcl_NewLongObj((long)statPtr->st_mtime));
- STORE_ARY("ctime", Tcl_NewLongObj((long)statPtr->st_ctime));
+ STORE_ARY("atime", Tcl_NewLongObj((long)statPtr->st_atime));
+ STORE_ARY("mtime", Tcl_NewLongObj((long)statPtr->st_mtime));
+ STORE_ARY("ctime", Tcl_NewLongObj((long)statPtr->st_ctime));
mode = (unsigned short) statPtr->st_mode;
- STORE_ARY("mode", Tcl_NewIntObj(mode));
- STORE_ARY("type", Tcl_NewStringObj(GetTypeFromMode(mode), -1));
+ STORE_ARY("mode", Tcl_NewIntObj(mode));
+ STORE_ARY("type", Tcl_NewStringObj(GetTypeFromMode(mode), -1));
#undef STORE_ARY
- Tcl_DecrRefCount(var);
- Tcl_DecrRefCount(field);
+
return TCL_OK;
}
@@ -1567,8 +1541,7 @@ StoreStatData(interp, varName, statPtr)
*
* GetTypeFromMode --
*
- * Given a mode word, returns a string identifying the type of a
- * file.
+ * Given a mode word, returns a string identifying the type of a file.
*
* Results:
* A static text string giving the file type from mode.
@@ -1580,8 +1553,8 @@ StoreStatData(interp, varName, statPtr)
*/
static char *
-GetTypeFromMode(mode)
- int mode;
+GetTypeFromMode(
+ int mode)
{
if (S_ISREG(mode)) {
return "file";
@@ -1610,103 +1583,98 @@ GetTypeFromMode(mode)
*
* Tcl_ForObjCmd --
*
- * This procedure is invoked to process the "for" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "for" Tcl command. See the
+ * user documentation for details on what it does.
*
- * With the bytecode compiler, this procedure is only called when
- * a command name is computed at runtime, and is "for" or the name
- * to which "for" was renamed: e.g.,
+ * With the bytecode compiler, this procedure is only called when a
+ * command name is computed at runtime, and is "for" or the name to which
+ * "for" was renamed: e.g.,
* "set z for; $z {set i 0} {$i<100} {incr i} {puts $i}"
*
* Results:
- * A standard Tcl result.
+ * A standard Tcl result.
*
* Side effects:
- * See the user documentation.
+ * See the user documentation.
*
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
+ /* ARGSUSED */
int
-Tcl_ForObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_ForObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
int result, value;
-#ifdef TCL_TIP280
- Interp* iPtr = (Interp*) interp;
-#endif
+ Interp *iPtr = (Interp *) interp;
if (objc != 5) {
- Tcl_WrongNumArgs(interp, 1, objv, "start test next command");
- return TCL_ERROR;
+ Tcl_WrongNumArgs(interp, 1, objv, "start test next command");
+ return TCL_ERROR;
}
-#ifndef TCL_TIP280
- result = Tcl_EvalObjEx(interp, objv[1], 0);
-#else
- /* TIP #280. Make invoking context available to initial script */
- result = TclEvalObjEx(interp, objv[1], 0, iPtr->cmdFramePtr,1);
-#endif
+ /*
+ * TIP #280. Make invoking context available to initial script.
+ */
+
+ result = TclEvalObjEx(interp, objv[1], 0, iPtr->cmdFramePtr, 1);
if (result != TCL_OK) {
- if (result == TCL_ERROR) {
- Tcl_AddErrorInfo(interp, "\n (\"for\" initial command)");
- }
- return result;
+ if (result == TCL_ERROR) {
+ Tcl_AddErrorInfo(interp, "\n (\"for\" initial command)");
+ }
+ return result;
}
while (1) {
/*
* We need to reset the result before passing it off to
- * Tcl_ExprBooleanObj. Otherwise, any error message will be appended
+ * Tcl_ExprBooleanObj. Otherwise, any error message will be appended
* to the result of the last evaluation.
*/
Tcl_ResetResult(interp);
- result = Tcl_ExprBooleanObj(interp, objv[2], &value);
- if (result != TCL_OK) {
- return result;
- }
- if (!value) {
- break;
- }
-#ifndef TCL_TIP280
- result = Tcl_EvalObjEx(interp, objv[4], 0);
-#else
- /* TIP #280. Make invoking context available to loop body */
- result = TclEvalObjEx(interp, objv[4], 0, iPtr->cmdFramePtr,4);
-#endif
- if ((result != TCL_OK) && (result != TCL_CONTINUE)) {
- if (result == TCL_ERROR) {
- char msg[32 + TCL_INTEGER_SPACE];
-
- sprintf(msg, "\n (\"for\" body line %d)",interp->errorLine);
- Tcl_AddErrorInfo(interp, msg);
- }
- break;
- }
-#ifndef TCL_TIP280
- result = Tcl_EvalObjEx(interp, objv[3], 0);
-#else
- /* TIP #280. Make invoking context available to next script */
- result = TclEvalObjEx(interp, objv[3], 0, iPtr->cmdFramePtr,3);
-#endif
+ result = Tcl_ExprBooleanObj(interp, objv[2], &value);
+ if (result != TCL_OK) {
+ return result;
+ }
+ if (!value) {
+ break;
+ }
+
+ /*
+ * TIP #280. Make invoking context available to loop body.
+ */
+
+ result = TclEvalObjEx(interp, objv[4], 0, iPtr->cmdFramePtr, 4);
+ if ((result != TCL_OK) && (result != TCL_CONTINUE)) {
+ if (result == TCL_ERROR) {
+ Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+ "\n (\"for\" body line %d)", interp->errorLine));
+ }
+ break;
+ }
+
+ /*
+ * TIP #280. Make invoking context available to next script.
+ */
+
+ result = TclEvalObjEx(interp, objv[3], 0, iPtr->cmdFramePtr, 3);
if (result == TCL_BREAK) {
- break;
- } else if (result != TCL_OK) {
- if (result == TCL_ERROR) {
- Tcl_AddErrorInfo(interp, "\n (\"for\" loop-end command)");
- }
- return result;
- }
+ break;
+ } else if (result != TCL_OK) {
+ if (result == TCL_ERROR) {
+ Tcl_AddErrorInfo(interp, "\n (\"for\" loop-end command)");
+ }
+ return result;
+ }
}
if (result == TCL_BREAK) {
- result = TCL_OK;
+ result = TCL_OK;
}
if (result == TCL_OK) {
- Tcl_ResetResult(interp);
+ Tcl_ResetResult(interp);
}
return result;
}
@@ -1717,7 +1685,7 @@ Tcl_ForObjCmd(dummy, interp, objc, objv)
* Tcl_ForeachObjCmd --
*
* This object-based procedure is invoked to process the "foreach" Tcl
- * command. See the user documentation for details on what it does.
+ * command. See the user documentation for details on what it does.
*
* Results:
* A standard Tcl object result.
@@ -1730,45 +1698,27 @@ Tcl_ForObjCmd(dummy, interp, objc, objv)
/* ARGSUSED */
int
-Tcl_ForeachObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_ForeachObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
int result = TCL_OK;
int i; /* i selects a value list */
int j, maxj; /* Number of loop iterations */
int v; /* v selects a loop variable */
- int numLists; /* Count of value lists */
+ int numLists = (objc-2)/2; /* Count of value lists */
Tcl_Obj *bodyPtr;
+ Interp *iPtr = (Interp *) interp;
- /*
- * We copy the argument object pointers into a local array to avoid
- * the problem that "objv" might become invalid. It is a pointer into
- * the evaluation stack and that stack might be grown and reallocated
- * if the loop body requires a large amount of stack space.
- */
-
-#define NUM_ARGS 9
- Tcl_Obj *(argObjStorage[NUM_ARGS]);
- Tcl_Obj **argObjv = argObjStorage;
-
-#define STATIC_LIST_SIZE 4
- int indexArray[STATIC_LIST_SIZE];
- int varcListArray[STATIC_LIST_SIZE];
- Tcl_Obj **varvListArray[STATIC_LIST_SIZE];
- int argcListArray[STATIC_LIST_SIZE];
- Tcl_Obj **argvListArray[STATIC_LIST_SIZE];
-
- int *index = indexArray; /* Array of value list indices */
- int *varcList = varcListArray; /* # loop variables per list */
- Tcl_Obj ***varvList = varvListArray; /* Array of var name lists */
- int *argcList = argcListArray; /* Array of value list sizes */
- Tcl_Obj ***argvList = argvListArray; /* Array of value lists */
-#ifdef TCL_TIP280
- Interp* iPtr = (Interp*) interp;
-#endif
+ int *index; /* Array of value list indices */
+ int *varcList; /* # loop variables per list */
+ Tcl_Obj ***varvList; /* Array of var name lists */
+ Tcl_Obj **vCopyList; /* Copies of var name list arguments */
+ int *argcList; /* Array of value list sizes */
+ Tcl_Obj ***argvList; /* Array of value lists */
+ Tcl_Obj **aCopyList; /* Copies of value list arguments */
if (objc < 4 || (objc%2 != 0)) {
Tcl_WrongNumArgs(interp, 1, objv,
@@ -1777,65 +1727,54 @@ Tcl_ForeachObjCmd(dummy, interp, objc, objv)
}
/*
- * Create the object argument array "argObjv". Make sure argObjv is
- * large enough to hold the objc arguments.
+ * Manage numList parallel value lists.
+ * argvList[i] is a value list counted by argcList[i]l;
+ * varvList[i] is the list of variables associated with the value list;
+ * varcList[i] is the number of variables associated with the value list;
+ * index[i] is the current pointer into the value list argvList[i].
*/
- if (objc > NUM_ARGS) {
- argObjv = (Tcl_Obj **) ckalloc(objc * sizeof(Tcl_Obj *));
- }
- for (i = 0; i < objc; i++) {
- argObjv[i] = objv[i];
- }
+ index = (int *) TclStackAlloc(interp, 3 * numLists * sizeof(int));
+ varcList = index + numLists;
+ argcList = varcList + numLists;
+ memset(index, 0, 3 * numLists * sizeof(int));
- /*
- * Manage numList parallel value lists.
- * argvList[i] is a value list counted by argcList[i]
- * varvList[i] is the list of variables associated with the value list
- * varcList[i] is the number of variables associated with the value list
- * index[i] is the current pointer into the value list argvList[i]
- */
+ varvList = (Tcl_Obj ***)
+ TclStackAlloc(interp, 2 * numLists * sizeof(Tcl_Obj **));
+ argvList = varvList + numLists;
+ memset(varvList, 0, 2 * numLists * sizeof(Tcl_Obj **));
- numLists = (objc-2)/2;
- if (numLists > STATIC_LIST_SIZE) {
- index = (int *) ckalloc(numLists * sizeof(int));
- varcList = (int *) ckalloc(numLists * sizeof(int));
- varvList = (Tcl_Obj ***) ckalloc(numLists * sizeof(Tcl_Obj **));
- argcList = (int *) ckalloc(numLists * sizeof(int));
- argvList = (Tcl_Obj ***) ckalloc(numLists * sizeof(Tcl_Obj **));
- }
- for (i = 0; i < numLists; i++) {
- index[i] = 0;
- varcList[i] = 0;
- varvList[i] = (Tcl_Obj **) NULL;
- argcList[i] = 0;
- argvList[i] = (Tcl_Obj **) NULL;
- }
+ vCopyList = (Tcl_Obj **)
+ TclStackAlloc(interp, 2 * numLists * sizeof(Tcl_Obj *));
+ aCopyList = vCopyList + numLists;
+ memset(vCopyList, 0, 2 * numLists * sizeof(Tcl_Obj *));
/*
- * Break up the value lists and variable lists into elements
+ * Break up the value lists and variable lists into elements.
*/
maxj = 0;
- for (i = 0; i < numLists; i++) {
- result = Tcl_ListObjGetElements(interp, argObjv[1+i*2],
- &varcList[i], &varvList[i]);
- if (result != TCL_OK) {
+ for (i=0 ; i<numLists ; i++) {
+
+ vCopyList[i] = TclListObjCopy(interp, objv[1+i*2]);
+ if (vCopyList[i] == NULL) {
+ result = TCL_ERROR;
goto done;
}
+ TclListObjGetElements(NULL, vCopyList[i], &varcList[i], &varvList[i]);
if (varcList[i] < 1) {
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "foreach varlist is empty", -1);
+ Tcl_AppendResult(interp, "foreach varlist is empty", NULL);
result = TCL_ERROR;
goto done;
}
-
- result = Tcl_ListObjGetElements(interp, argObjv[2+i*2],
- &argcList[i], &argvList[i]);
- if (result != TCL_OK) {
+
+ aCopyList[i] = TclListObjCopy(interp, objv[2+i*2]);
+ if (aCopyList[i] == NULL) {
+ result = TCL_ERROR;
goto done;
}
-
+ TclListObjGetElements(NULL, aCopyList[i], &argcList[i], &argvList[i]);
+
j = argcList[i] / varcList[i];
if ((argcList[i] % varcList[i]) != 0) {
j++;
@@ -1846,64 +1785,39 @@ Tcl_ForeachObjCmd(dummy, interp, objc, objv)
}
/*
- * Iterate maxj times through the lists in parallel
- * If some value lists run out of values, set loop vars to ""
+ * Iterate maxj times through the lists in parallel. If some value lists
+ * run out of values, set loop vars to ""
*/
-
- bodyPtr = argObjv[objc-1];
- for (j = 0; j < maxj; j++) {
- for (i = 0; i < numLists; i++) {
- /*
- * Refetch the list members; we assume that the sizes are
- * the same, but the array of elements might be different
- * if the internal rep of the objects has been lost and
- * recreated (it is too difficult to accurately tell when
- * this happens, which can lead to some wierd crashes,
- * like Bug #494348...)
- */
- result = Tcl_ListObjGetElements(interp, argObjv[1+i*2],
- &varcList[i], &varvList[i]);
- if (result != TCL_OK) {
- panic("Tcl_ForeachObjCmd: could not reconvert variable list %d to a list object\n", i);
- }
- result = Tcl_ListObjGetElements(interp, argObjv[2+i*2],
- &argcList[i], &argvList[i]);
- if (result != TCL_OK) {
- panic("Tcl_ForeachObjCmd: could not reconvert value list %d to a list object\n", i);
- }
-
- for (v = 0; v < varcList[i]; v++) {
+ bodyPtr = objv[objc-1];
+ for (j=0 ; j<maxj ; j++) {
+ for (i=0 ; i<numLists ; i++) {
+ for (v=0 ; v<varcList[i] ; v++) {
int k = index[i]++;
Tcl_Obj *valuePtr, *varValuePtr;
-
+
if (k < argcList[i]) {
valuePtr = argvList[i][k];
} else {
- valuePtr = Tcl_NewObj(); /* empty string */
+ valuePtr = Tcl_NewObj(); /* Empty string */
}
- Tcl_IncrRefCount(valuePtr);
- varValuePtr = Tcl_ObjSetVar2(interp, varvList[i][v],
- NULL, valuePtr, 0);
- Tcl_DecrRefCount(valuePtr);
+ varValuePtr = Tcl_ObjSetVar2(interp, varvList[i][v], NULL,
+ valuePtr, TCL_LEAVE_ERR_MSG);
if (varValuePtr == NULL) {
- Tcl_ResetResult(interp);
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "couldn't set loop variable: \"",
- Tcl_GetString(varvList[i][v]), "\"", (char *) NULL);
+ Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+ "\n (setting foreach loop variable \"%s\")",
+ TclGetString(varvList[i][v])));
result = TCL_ERROR;
goto done;
}
-
}
}
-#ifndef TCL_TIP280
- result = Tcl_EvalObjEx(interp, bodyPtr, 0);
-#else
- /* TIP #280. Make invoking context available to loop body */
- result = TclEvalObjEx(interp, bodyPtr, 0, iPtr->cmdFramePtr,objc-1);
-#endif
+ /*
+ * TIP #280. Make invoking context available to loop body.
+ */
+
+ result = TclEvalObjEx(interp, bodyPtr, 0, iPtr->cmdFramePtr, objc-1);
if (result != TCL_OK) {
if (result == TCL_CONTINUE) {
result = TCL_OK;
@@ -1911,11 +1825,9 @@ Tcl_ForeachObjCmd(dummy, interp, objc, objv)
result = TCL_OK;
break;
} else if (result == TCL_ERROR) {
- char msg[32 + TCL_INTEGER_SPACE];
-
- sprintf(msg, "\n (\"foreach\" body line %d)",
- interp->errorLine);
- Tcl_AddObjErrorInfo(interp, msg, -1);
+ Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+ "\n (\"foreach\" body line %d)",
+ interp->errorLine));
break;
} else {
break;
@@ -1926,20 +1838,19 @@ Tcl_ForeachObjCmd(dummy, interp, objc, objv)
Tcl_ResetResult(interp);
}
- done:
- if (numLists > STATIC_LIST_SIZE) {
- ckfree((char *) index);
- ckfree((char *) varcList);
- ckfree((char *) argcList);
- ckfree((char *) varvList);
- ckfree((char *) argvList);
- }
- if (argObjv != argObjStorage) {
- ckfree((char *) argObjv);
+ done:
+ for (i=0 ; i<numLists ; i++) {
+ if (vCopyList[i]) {
+ Tcl_DecrRefCount(vCopyList[i]);
+ }
+ if (aCopyList[i]) {
+ Tcl_DecrRefCount(aCopyList[i]);
+ }
}
+ TclStackFree(interp, vCopyList); /* Tcl_Obj * arrays */
+ TclStackFree(interp, varvList); /* Tcl_Obj ** arrays */
+ TclStackFree(interp, index); /* int arrays */
return result;
-#undef STATIC_LIST_SIZE
-#undef NUM_ARGS
}
/*
@@ -1947,8 +1858,8 @@ Tcl_ForeachObjCmd(dummy, interp, objc, objv)
*
* Tcl_FormatObjCmd --
*
- * This procedure is invoked to process the "format" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "format" Tcl command. See
+ * the user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -1961,493 +1872,25 @@ Tcl_ForeachObjCmd(dummy, interp, objc, objv)
/* ARGSUSED */
int
-Tcl_FormatObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_FormatObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- char *format; /* Used to read characters from the format
- * string. */
- int formatLen; /* The length of the format string */
- char *endPtr; /* Points to the last char in format array */
- char newFormat[43]; /* A new format specifier is generated here. */
- int width; /* Field width from field specifier, or 0 if
- * no width given. */
- int precision; /* Field precision from field specifier, or 0
- * if no precision given. */
- int size; /* Number of bytes needed for result of
- * conversion, based on type of conversion
- * ("e", "s", etc.), width, and precision. */
- long intValue; /* Used to hold value to pass to sprintf, if
- * it's a one-word integer or char value */
- char *ptrValue = NULL; /* Used to hold value to pass to sprintf, if
- * it's a one-word value. */
- double doubleValue; /* Used to hold value to pass to sprintf if
- * it's a double value. */
- Tcl_WideInt wideValue; /* Used to hold value to pass to sprintf if
- * it's a 'long long' value. */
- int whichValue; /* Indicates which of intValue, ptrValue,
- * or doubleValue has the value to pass to
- * sprintf, according to the following
- * definitions: */
-# define INT_VALUE 0
-# define CHAR_VALUE 1
-# define PTR_VALUE 2
-# define DOUBLE_VALUE 3
-# define STRING_VALUE 4
-# define WIDE_VALUE 5
-# define MAX_FLOAT_SIZE 320
-
- Tcl_Obj *resultPtr; /* Where result is stored finally. */
- char staticBuf[MAX_FLOAT_SIZE + 1];
- /* A static buffer to copy the format results
- * into */
- char *dst = staticBuf; /* The buffer that sprintf writes into each
- * time the format processes a specifier */
- int dstSize = MAX_FLOAT_SIZE;
- /* The size of the dst buffer */
- int noPercent; /* Special case for speed: indicates there's
- * no field specifier, just a string to copy.*/
- int objIndex; /* Index of argument to substitute next. */
- int gotXpg = 0; /* Non-zero means that an XPG3 %n$-style
- * specifier has been seen. */
- int gotSequential = 0; /* Non-zero means that a regular sequential
- * (non-XPG3) conversion specifier has been
- * seen. */
- int useShort; /* Value to be printed is short (half word). */
- char *end; /* Used to locate end of numerical fields. */
- int stringLen = 0; /* Length of string in characters rather
- * than bytes. Used for %s substitution. */
- int gotMinus; /* Non-zero indicates that a minus flag has
- * been seen in the current field. */
- int gotPrecision; /* Non-zero indicates that a precision has
- * been set for the current field. */
- int gotZero; /* Non-zero indicates that a zero flag has
- * been seen in the current field. */
- int useWide; /* Value to be printed is Tcl_WideInt. */
-
- /*
- * This procedure is a bit nasty. The goal is to use sprintf to
- * do most of the dirty work. There are several problems:
- * 1. this procedure can't trust its arguments.
- * 2. we must be able to provide a large enough result area to hold
- * whatever's generated. This is hard to estimate.
- * 3. there's no way to move the arguments from objv to the call
- * to sprintf in a reasonable way. This is particularly nasty
- * because some of the arguments may be two-word values (doubles
- * and wide-ints).
- * So, what happens here is to scan the format string one % group
- * at a time, making many individual calls to sprintf.
- */
+ Tcl_Obj *resultPtr; /* Where result is stored finally. */
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "formatString ?arg arg ...?");
return TCL_ERROR;
}
- format = Tcl_GetStringFromObj(objv[1], &formatLen);
- endPtr = format + formatLen;
- resultPtr = Tcl_NewObj();
- objIndex = 2;
-
- while (format < endPtr) {
- register char *newPtr = newFormat;
-
- width = precision = noPercent = useShort = 0;
- gotZero = gotMinus = gotPrecision = 0;
- useWide = 0;
- whichValue = PTR_VALUE;
-
- /*
- * Get rid of any characters before the next field specifier.
- */
- if (*format != '%') {
- ptrValue = format;
- while ((*format != '%') && (format < endPtr)) {
- format++;
- }
- size = format - ptrValue;
- noPercent = 1;
- goto doField;
- }
-
- if (format[1] == '%') {
- ptrValue = format;
- size = 1;
- noPercent = 1;
- format += 2;
- goto doField;
- }
-
- /*
- * Parse off a field specifier, compute how many characters
- * will be needed to store the result, and substitute for
- * "*" size specifiers.
- */
- *newPtr = '%';
- newPtr++;
- format++;
- if (isdigit(UCHAR(*format))) { /* INTL: Tcl source. */
- int tmp;
-
- /*
- * Check for an XPG3-style %n$ specification. Note: there
- * must not be a mixture of XPG3 specs and non-XPG3 specs
- * in the same format string.
- */
-
- tmp = strtoul(format, &end, 10); /* INTL: "C" locale. */
- if (*end != '$') {
- goto notXpg;
- }
- format = end+1;
- gotXpg = 1;
- if (gotSequential) {
- goto mixedXPG;
- }
- objIndex = tmp+1;
- if ((objIndex < 2) || (objIndex >= objc)) {
- goto badIndex;
- }
- goto xpgCheckDone;
- }
-
- notXpg:
- gotSequential = 1;
- if (gotXpg) {
- goto mixedXPG;
- }
-
- xpgCheckDone:
- while ((*format == '-') || (*format == '#') || (*format == '0')
- || (*format == ' ') || (*format == '+')) {
- if (*format == '-') {
- gotMinus = 1;
- }
- if (*format == '0') {
- /*
- * This will be handled by sprintf for numbers, but we
- * need to do the char/string ones ourselves
- */
- gotZero = 1;
- }
- *newPtr = *format;
- newPtr++;
- format++;
- }
- if (isdigit(UCHAR(*format))) { /* INTL: Tcl source. */
- width = strtoul(format, &end, 10); /* INTL: Tcl source. */
- format = end;
- } else if (*format == '*') {
- if (objIndex >= objc) {
- goto badIndex;
- }
- if (Tcl_GetIntFromObj(interp, /* INTL: Tcl source. */
- objv[objIndex], &width) != TCL_OK) {
- goto fmtError;
- }
- if (width < 0) {
- width = -width;
- *newPtr = '-';
- gotMinus = 1;
- newPtr++;
- }
- objIndex++;
- format++;
- }
- if (width > 100000) {
- /*
- * Don't allow arbitrarily large widths: could cause core
- * dump when we try to allocate a zillion bytes of memory
- * below.
- */
-
- width = 100000;
- } else if (width < 0) {
- width = 0;
- }
- if (width != 0) {
- TclFormatInt(newPtr, width); /* INTL: printf format. */
- while (*newPtr != 0) {
- newPtr++;
- }
- }
- if (*format == '.') {
- *newPtr = '.';
- newPtr++;
- format++;
- gotPrecision = 1;
- }
- if (isdigit(UCHAR(*format))) { /* INTL: Tcl source. */
- precision = strtoul(format, &end, 10); /* INTL: "C" locale. */
- format = end;
- } else if (*format == '*') {
- if (objIndex >= objc) {
- goto badIndex;
- }
- if (Tcl_GetIntFromObj(interp, /* INTL: Tcl source. */
- objv[objIndex], &precision) != TCL_OK) {
- goto fmtError;
- }
- objIndex++;
- format++;
- }
- if (gotPrecision) {
- TclFormatInt(newPtr, precision); /* INTL: printf format. */
- while (*newPtr != 0) {
- newPtr++;
- }
- }
- if (*format == 'l') {
- useWide = 1;
- /*
- * Only add a 'll' modifier for integer values as it makes
- * some libc's go into spasm otherwise. [Bug #702622]
- */
- switch (format[1]) {
- case 'i':
- case 'd':
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- strcpy(newPtr, TCL_LL_MODIFIER);
- newPtr += TCL_LL_MODIFIER_SIZE;
- }
- format++;
- } else if (*format == 'h') {
- useShort = 1;
- *newPtr = 'h';
- newPtr++;
- format++;
- }
- *newPtr = *format;
- newPtr++;
- *newPtr = 0;
- if (objIndex >= objc) {
- goto badIndex;
- }
- switch (*format) {
- case 'i':
- newPtr[-1] = 'd';
- case 'd':
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- if (useWide) {
- if (Tcl_GetWideIntFromObj(interp, /* INTL: Tcl source. */
- objv[objIndex], &wideValue) != TCL_OK) {
- goto fmtError;
- }
- whichValue = WIDE_VALUE;
- size = 40 + precision;
- break;
- }
- if (Tcl_GetLongFromObj(interp, /* INTL: Tcl source. */
- objv[objIndex], &intValue) != TCL_OK) {
- if (Tcl_GetWideIntFromObj(interp, /* INTL: Tcl source. */
- objv[objIndex], &wideValue) != TCL_OK) {
- goto fmtError;
- }
- intValue = Tcl_WideAsLong(wideValue);
- }
-
-#if (LONG_MAX > INT_MAX)
- if (!useShort) {
- /*
- * Add the 'l' for long format type because we are on an
- * LP64 archtecture and we are really going to pass a long
- * argument to sprintf.
- *
- * Do not add this if we're going to pass in a short (i.e.
- * if we've got an 'h' modifier already in the string); some
- * libc implementations of sprintf() do not like it at all.
- * [Bug 1154163]
- */
- newPtr++;
- *newPtr = 0;
- newPtr[-1] = newPtr[-2];
- newPtr[-2] = 'l';
- }
-#endif /* LONG_MAX > INT_MAX */
- whichValue = INT_VALUE;
- size = 40 + precision;
- break;
- case 's':
- /*
- * Compute the length of the string in characters and add
- * any additional space required by the field width. All
- * of the extra characters will be spaces, so one byte per
- * character is adequate.
- */
-
- whichValue = STRING_VALUE;
- ptrValue = Tcl_GetStringFromObj(objv[objIndex], &size);
- stringLen = Tcl_NumUtfChars(ptrValue, size);
- if (gotPrecision && (precision < stringLen)) {
- stringLen = precision;
- }
- size = Tcl_UtfAtIndex(ptrValue, stringLen) - ptrValue;
- if (width > stringLen) {
- size += (width - stringLen);
- }
- break;
- case 'c':
- if (Tcl_GetLongFromObj(interp, /* INTL: Tcl source. */
- objv[objIndex], &intValue) != TCL_OK) {
- goto fmtError;
- }
- whichValue = CHAR_VALUE;
- size = width + TCL_UTF_MAX;
- break;
- case 'e':
- case 'E':
- case 'f':
- case 'g':
- case 'G':
- if (Tcl_GetDoubleFromObj(interp, /* INTL: Tcl source. */
- objv[objIndex], &doubleValue) != TCL_OK) {
- goto fmtError;
- }
- whichValue = DOUBLE_VALUE;
- size = MAX_FLOAT_SIZE;
- if (precision > 10) {
- size += precision;
- }
- break;
- case 0:
- Tcl_SetResult(interp,
- "format string ended in middle of field specifier",
- TCL_STATIC);
- goto fmtError;
- default:
- {
- char buf[40];
-
- sprintf(buf, "bad field specifier \"%c\"", *format);
- Tcl_SetResult(interp, buf, TCL_VOLATILE);
- goto fmtError;
- }
- }
- objIndex++;
- format++;
-
- /*
- * Make sure that there's enough space to hold the formatted
- * result, then format it.
- */
-
- doField:
- if (width > size) {
- size = width;
- }
- if (noPercent) {
- Tcl_AppendToObj(resultPtr, ptrValue, size);
- } else {
- if (size > dstSize) {
- if (dst != staticBuf) {
- ckfree(dst);
- }
- dst = (char *) ckalloc((unsigned) (size + 1));
- dstSize = size;
- }
- switch (whichValue) {
- case DOUBLE_VALUE:
- sprintf(dst, newFormat, doubleValue); /* INTL: user locale. */
- break;
- case WIDE_VALUE:
- sprintf(dst, newFormat, wideValue);
- break;
- case INT_VALUE:
- if (useShort) {
- sprintf(dst, newFormat, (short) intValue);
- } else {
- sprintf(dst, newFormat, intValue);
- }
- break;
- case CHAR_VALUE: {
- char *ptr;
- char padChar = (gotZero ? '0' : ' ');
- ptr = dst;
- if (!gotMinus) {
- for ( ; --width > 0; ptr++) {
- *ptr = padChar;
- }
- }
- ptr += Tcl_UniCharToUtf(intValue, ptr);
- for ( ; --width > 0; ptr++) {
- *ptr = padChar;
- }
- *ptr = '\0';
- break;
- }
- case STRING_VALUE: {
- char *ptr;
- char padChar = (gotZero ? '0' : ' ');
- int pad;
-
- ptr = dst;
- if (width > stringLen) {
- pad = width - stringLen;
- } else {
- pad = 0;
- }
-
- if (!gotMinus) {
- while (pad > 0) {
- *ptr++ = padChar;
- pad--;
- }
- }
-
- size = Tcl_UtfAtIndex(ptrValue, stringLen) - ptrValue;
- if (size) {
- memcpy(ptr, ptrValue, (size_t) size);
- ptr += size;
- }
- while (pad > 0) {
- *ptr++ = padChar;
- pad--;
- }
- *ptr = '\0';
- break;
- }
- default:
- sprintf(dst, newFormat, ptrValue);
- break;
- }
- Tcl_AppendToObj(resultPtr, dst, -1);
- }
+ resultPtr = Tcl_Format(interp, TclGetString(objv[1]), objc-2, objv+2);
+ if (resultPtr == NULL) {
+ return TCL_ERROR;
}
-
Tcl_SetObjResult(interp, resultPtr);
- if (dst != staticBuf) {
- ckfree(dst);
- }
return TCL_OK;
-
- mixedXPG:
- Tcl_SetResult(interp,
- "cannot mix \"%\" and \"%n$\" conversion specifiers", TCL_STATIC);
- goto fmtError;
-
- badIndex:
- if (gotXpg) {
- Tcl_SetResult(interp,
- "\"%n$\" argument index out of range", TCL_STATIC);
- } else {
- Tcl_SetResult(interp,
- "not enough arguments for all format specifiers", TCL_STATIC);
- }
-
- fmtError:
- if (dst != staticBuf) {
- ckfree(dst);
- }
- Tcl_DecrRefCount(resultPtr);
- return TCL_ERROR;
}
/*
@@ -2457,4 +1900,3 @@ Tcl_FormatObjCmd(dummy, interp, objc, objv)
* fill-column: 78
* End:
*/
-
diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c
index 21dbdc8..13db6d5 100644
--- a/generic/tclCmdIL.c
+++ b/generic/tclCmdIL.c
@@ -1,62 +1,80 @@
-/*
+/*
* tclCmdIL.c --
*
- * This file contains the top-level command routines for most of
- * the Tcl built-in commands whose names begin with the letters
- * I through L. It contains only commands in the generic core
- * (i.e. those that don't depend much upon UNIX facilities).
+ * This file contains the top-level command routines for most of the Tcl
+ * built-in commands whose names begin with the letters I through L. It
+ * contains only commands in the generic core (i.e. those that don't
+ * depend much upon UNIX facilities).
*
* Copyright (c) 1987-1993 The Regents of the University of California.
* Copyright (c) 1993-1997 Lucent Technologies.
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
* Copyright (c) 1998-1999 by Scriptics Corporation.
- * Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
+ * Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
+ * Copyright (c) 2005 Donal K. Fellows.
*
- * 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.
*/
#include "tclInt.h"
-#include "tclPort.h"
#include "tclRegexp.h"
/*
- * During execution of the "lsort" command, structures of the following
- * type are used to arrange the objects being sorted into a collection
- * of linked lists.
+ * During execution of the "lsort" command, structures of the following type
+ * are used to arrange the objects being sorted into a collection of linked
+ * lists.
*/
typedef struct SortElement {
- Tcl_Obj *objPtr; /* Object being sorted. */
- int count; /* number of same elements in list */
- struct SortElement *nextPtr; /* Next element in the list, or
- * NULL for end of list. */
+ union {
+ char *strValuePtr;
+ long intValue;
+ double doubleValue;
+ Tcl_Obj *objValuePtr;
+ } index;
+ Tcl_Obj *objPtr; /* Object being sorted, or its index. */
+ struct SortElement *nextPtr;/* Next element in the list, or NULL for end
+ * of list. */
} SortElement;
/*
- * The "lsort" command needs to pass certain information down to the
- * function that compares two list elements, and the comparison function
- * needs to pass success or failure information back up to the top-level
- * "lsort" command. The following structure is used to pass this
- * information.
+ * These function pointer types are used with the "lsearch" and "lsort"
+ * commands to facilitate the "-nocase" option.
+ */
+
+typedef int (*SortStrCmpFn_t) (const char *, const char *);
+typedef int (*SortMemCmpFn_t) (const void *, const void *, size_t);
+
+/*
+ * The "lsort" command needs to pass certain information down to the function
+ * that compares two list elements, and the comparison function needs to pass
+ * success or failure information back up to the top-level "lsort" command.
+ * The following structure is used to pass this information.
*/
typedef struct SortInfo {
int isIncreasing; /* Nonzero means sort in increasing order. */
- int sortMode; /* The sort mode. One of SORTMODE_*
- * values defined below */
- Tcl_Obj *compareCmdPtr; /* The Tcl comparison command when sortMode
- * is SORTMODE_COMMAND. Pre-initialized to
- * hold base of command.*/
- int index; /* If the -index option was specified, this
- * holds the index of the list element
- * to extract for comparison. If -index
- * wasn't specified, this is -1. */
- Tcl_Interp *interp; /* The interpreter in which the sortis
- * being done. */
- int resultCode; /* Completion code for the lsort command.
- * If an error occurs during the sort this
- * is changed from TCL_OK to TCL_ERROR. */
+ int sortMode; /* The sort mode. One of SORTMODE_* values
+ * defined below. */
+ Tcl_Obj *compareCmdPtr; /* The Tcl comparison command when sortMode is
+ * SORTMODE_COMMAND. Pre-initialized to hold
+ * base of command. */
+ int *indexv; /* If the -index option was specified, this
+ * holds the indexes contained in the list
+ * supplied as an argument to that option.
+ * NULL if no indexes supplied, and points to
+ * singleIndex field when only one
+ * supplied. */
+ int indexc; /* Number of indexes in indexv array. */
+ int singleIndex; /* Static space for common index case. */
+ int unique;
+ int numElements;
+ Tcl_Interp *interp; /* The interpreter in which the sort is being
+ * done. */
+ int resultCode; /* Completion code for the lsort command. If
+ * an error occurs during the sort this is
+ * changed from TCL_OK to TCL_ERROR. */
} SortInfo;
/*
@@ -64,115 +82,113 @@ typedef struct SortInfo {
* following values.
*/
-#define SORTMODE_ASCII 0
-#define SORTMODE_INTEGER 1
-#define SORTMODE_REAL 2
-#define SORTMODE_COMMAND 3
-#define SORTMODE_DICTIONARY 4
+#define SORTMODE_ASCII 0
+#define SORTMODE_INTEGER 1
+#define SORTMODE_REAL 2
+#define SORTMODE_COMMAND 3
+#define SORTMODE_DICTIONARY 4
+#define SORTMODE_ASCII_NC 8
/*
- * Magic values for the index field of the SortInfo structure.
- * Note that the index "end-1" will be translated to SORTIDX_END-1, etc.
+ * Magic values for the index field of the SortInfo structure. Note that the
+ * index "end-1" will be translated to SORTIDX_END-1, etc.
*/
-#define SORTIDX_NONE -1 /* Not indexed; use whole value. */
-#define SORTIDX_END -2 /* Indexed from end. */
+
+#define SORTIDX_NONE -1 /* Not indexed; use whole value. */
+#define SORTIDX_END -2 /* Indexed from end. */
/*
* Forward declarations for procedures defined in this file:
*/
-static void AppendLocals _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_Obj *listPtr, CONST char *pattern,
- int includeLinks));
-static int DictionaryCompare _ANSI_ARGS_((char *left,
- char *right));
-static int InfoArgsCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int InfoBodyCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int InfoCmdCountCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int InfoCommandsCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int InfoCompleteCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int InfoDefaultCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int InfoExistsCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-#ifdef TCL_TIP280
+static int DictionaryCompare(char *left, char *right);
+static int InfoArgsCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static int InfoBodyCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static int InfoCmdCountCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static int InfoCommandsCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static int InfoCompleteCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static int InfoDefaultCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
/* TIP #280 - New 'info' subcommand 'frame' */
-static int InfoFrameCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-#endif
-static int InfoFunctionsCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int InfoGlobalsCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int InfoHostnameCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int InfoLevelCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int InfoLibraryCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int InfoLoadedCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int InfoLocalsCmd _ANSI_ARGS_((ClientData dummy,
+static int InfoFrameCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static int InfoFunctionsCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static int InfoHostnameCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static int InfoLevelCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static int InfoLibraryCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static int InfoLoadedCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static int InfoNameOfExecutableCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int InfoNameOfExecutableCmd _ANSI_ARGS_((
- ClientData dummy, Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int InfoPatchLevelCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int InfoProcsCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int InfoScriptCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int InfoSharedlibCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int InfoTclVersionCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static int InfoVarsCmd _ANSI_ARGS_((ClientData dummy,
- Tcl_Interp *interp, int objc,
- Tcl_Obj *CONST objv[]));
-static SortElement * MergeSort _ANSI_ARGS_((SortElement *headPt,
- SortInfo *infoPtr));
-static SortElement * MergeLists _ANSI_ARGS_((SortElement *leftPtr,
- SortElement *rightPtr, SortInfo *infoPtr));
-static int SortCompare _ANSI_ARGS_((Tcl_Obj *firstPtr,
- Tcl_Obj *second, SortInfo *infoPtr));
+ Tcl_Obj *CONST objv[]);
+static int InfoPatchLevelCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static int InfoProcsCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static int InfoScriptCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static int InfoSharedlibCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static int InfoTclVersionCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *CONST objv[]);
+static SortElement * MergeLists(SortElement *leftPtr, SortElement *rightPtr,
+ SortInfo *infoPtr);
+static int SortCompare(SortElement *firstPtr, SortElement *second,
+ SortInfo *infoPtr);
+static Tcl_Obj * SelectObjFromSublist(Tcl_Obj *firstPtr,
+ SortInfo *infoPtr);
+
+/*
+ * Array of values describing how to implement each standard subcommand of the
+ * "info" command.
+ */
+
+static const EnsembleImplMap defaultInfoMap[] = {
+ {"args", InfoArgsCmd, NULL},
+ {"body", InfoBodyCmd, NULL},
+ {"cmdcount", InfoCmdCountCmd, NULL},
+ {"commands", InfoCommandsCmd, NULL},
+ {"complete", InfoCompleteCmd, NULL},
+ {"default", InfoDefaultCmd, NULL},
+ {"exists", TclInfoExistsCmd, TclCompileInfoExistsCmd},
+ {"frame", InfoFrameCmd, NULL},
+ {"functions", InfoFunctionsCmd, NULL},
+ {"globals", TclInfoGlobalsCmd, NULL},
+ {"hostname", InfoHostnameCmd, NULL},
+ {"level", InfoLevelCmd, NULL},
+ {"library", InfoLibraryCmd, NULL},
+ {"loaded", InfoLoadedCmd, NULL},
+ {"locals", TclInfoLocalsCmd, NULL},
+ {"nameofexecutable", InfoNameOfExecutableCmd, NULL},
+ {"patchlevel", InfoPatchLevelCmd, NULL},
+ {"procs", InfoProcsCmd, NULL},
+ {"script", InfoScriptCmd, NULL},
+ {"sharedlibextension", InfoSharedlibCmd, NULL},
+ {"tclversion", InfoTclVersionCmd, NULL},
+ {"vars", TclInfoVarsCmd, NULL},
+ {NULL, NULL, NULL}
+};
/*
*----------------------------------------------------------------------
*
* Tcl_IfObjCmd --
*
- * This procedure is invoked to process the "if" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "if" Tcl command. See the
+ * user documentation for details on what it does.
*
- * With the bytecode compiler, this procedure is only called when
- * a command name is computed at runtime, and is "if" or the name
- * to which "if" was renamed: e.g., "set z if; $z 1 {puts foo}"
+ * With the bytecode compiler, this procedure is only called when a
+ * command name is computed at runtime, and is "if" or the name to which
+ * "if" was renamed: e.g., "set z if; $z 1 {puts foo}"
*
* Results:
* A standard Tcl result.
@@ -183,34 +199,32 @@ static int SortCompare _ANSI_ARGS_((Tcl_Obj *firstPtr,
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
int
-Tcl_IfObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_IfObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- int thenScriptIndex = 0; /* then script to be evaled after syntax check */
-#ifdef TCL_TIP280
- Interp* iPtr = (Interp*) interp;
-#endif
+ int thenScriptIndex = 0; /* "then" script to be evaled after syntax
+ * check. */
+ Interp *iPtr = (Interp *) interp;
int i, result, value;
char *clause;
+
i = 1;
while (1) {
/*
- * At this point in the loop, objv and objc refer to an expression
- * to test, either for the main expression or an expression
- * following an "elseif". The arguments after the expression must
- * be "then" (optional) and a script to execute if the expression is
- * true.
+ * At this point in the loop, objv and objc refer to an expression to
+ * test, either for the main expression or an expression following an
+ * "elseif". The arguments after the expression must be "then"
+ * (optional) and a script to execute if the expression is true.
*/
if (i >= objc) {
- clause = Tcl_GetString(objv[i-1]);
- Tcl_AppendResult(interp, "wrong # args: no expression after \"",
- clause, "\" argument", (char *) NULL);
+ clause = TclGetString(objv[i-1]);
+ Tcl_AppendResult(interp, "wrong # args: ",
+ "no expression after \"", clause, "\" argument", NULL);
return TCL_ERROR;
}
if (!thenScriptIndex) {
@@ -221,13 +235,13 @@ Tcl_IfObjCmd(dummy, interp, objc, objv)
}
i++;
if (i >= objc) {
- missingScript:
- clause = Tcl_GetString(objv[i-1]);
- Tcl_AppendResult(interp, "wrong # args: no script following \"",
- clause, "\" argument", (char *) NULL);
+ missingScript:
+ clause = TclGetString(objv[i-1]);
+ Tcl_AppendResult(interp, "wrong # args: ",
+ "no script following \"", clause, "\" argument", NULL);
return TCL_ERROR;
}
- clause = Tcl_GetString(objv[i]);
+ clause = TclGetString(objv[i]);
if ((i < objc) && (strcmp(clause, "then") == 0)) {
i++;
}
@@ -238,26 +252,25 @@ Tcl_IfObjCmd(dummy, interp, objc, objv)
thenScriptIndex = i;
value = 0;
}
-
+
/*
- * The expression evaluated to false. Skip the command, then
- * see if there is an "else" or "elseif" clause.
+ * The expression evaluated to false. Skip the command, then see if
+ * there is an "else" or "elseif" clause.
*/
i++;
if (i >= objc) {
if (thenScriptIndex) {
-#ifndef TCL_TIP280
- return Tcl_EvalObjEx(interp, objv[thenScriptIndex], 0);
-#else
- /* TIP #280. Make invoking context available to branch */
+ /*
+ * TIP #280. Make invoking context available to branch.
+ */
+
return TclEvalObjEx(interp, objv[thenScriptIndex], 0,
- iPtr->cmdFramePtr,thenScriptIndex);
-#endif
+ iPtr->cmdFramePtr, thenScriptIndex);
}
return TCL_OK;
}
- clause = Tcl_GetString(objv[i]);
+ clause = TclGetString(objv[i]);
if ((clause[0] == 'e') && (strcmp(clause, "elseif") == 0)) {
i++;
continue;
@@ -266,40 +279,33 @@ Tcl_IfObjCmd(dummy, interp, objc, objv)
}
/*
- * Couldn't find a "then" or "elseif" clause to execute. Check now
- * for an "else" clause. We know that there's at least one more
- * argument when we get here.
+ * Couldn't find a "then" or "elseif" clause to execute. Check now for an
+ * "else" clause. We know that there's at least one more argument when we
+ * get here.
*/
if (strcmp(clause, "else") == 0) {
i++;
if (i >= objc) {
- Tcl_AppendResult(interp,
- "wrong # args: no script following \"else\" argument",
- (char *) NULL);
+ Tcl_AppendResult(interp, "wrong # args: ",
+ "no script following \"else\" argument", NULL);
return TCL_ERROR;
}
}
if (i < objc - 1) {
- Tcl_AppendResult(interp,
- "wrong # args: extra words after \"else\" clause in \"if\" command",
- (char *) NULL);
+ Tcl_AppendResult(interp, "wrong # args: ",
+ "extra words after \"else\" clause in \"if\" command", NULL);
return TCL_ERROR;
}
if (thenScriptIndex) {
-#ifndef TCL_TIP280
- return Tcl_EvalObjEx(interp, objv[thenScriptIndex], 0);
-#else
- /* TIP #280. Make invoking context available to branch/else */
+ /*
+ * TIP #280. Make invoking context available to branch/else.
+ */
+
return TclEvalObjEx(interp, objv[thenScriptIndex], 0,
- iPtr->cmdFramePtr,thenScriptIndex);
-#endif
+ iPtr->cmdFramePtr, thenScriptIndex);
}
-#ifndef TCL_TIP280
- return Tcl_EvalObjEx(interp, objv[i], 0);
-#else
- return TclEvalObjEx(interp, objv[i], 0, iPtr->cmdFramePtr,i);
-#endif
+ return TclEvalObjEx(interp, objv[i], 0, iPtr->cmdFramePtr, i);
}
/*
@@ -307,12 +313,12 @@ Tcl_IfObjCmd(dummy, interp, objc, objv)
*
* Tcl_IncrObjCmd --
*
- * This procedure is invoked to process the "incr" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "incr" Tcl command. See the
+ * user documentation for details on what it does.
*
- * With the bytecode compiler, this procedure is only called when
- * a command name is computed at runtime, and is "incr" or the name
- * to which "incr" was renamed: e.g., "set z incr; $z i -1"
+ * With the bytecode compiler, this procedure is only called when a
+ * command name is computed at runtime, and is "incr" or the name to
+ * which "incr" was renamed: e.g., "set z incr; $z i -1"
*
* Results:
* A standard Tcl result.
@@ -323,64 +329,30 @@ Tcl_IfObjCmd(dummy, interp, objc, objv)
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
int
-Tcl_IncrObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_IncrObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- long incrAmount;
- Tcl_Obj *newValuePtr;
-
+ Tcl_Obj *newValuePtr, *incrPtr;
+
if ((objc != 2) && (objc != 3)) {
- Tcl_WrongNumArgs(interp, 1, objv, "varName ?increment?");
+ Tcl_WrongNumArgs(interp, 1, objv, "varName ?increment?");
return TCL_ERROR;
}
- /*
- * Calculate the amount to increment by.
- */
-
- if (objc == 2) {
- incrAmount = 1;
+ if (objc == 3) {
+ incrPtr = objv[2];
} else {
- if (Tcl_GetLongFromObj(interp, objv[2], &incrAmount) != TCL_OK) {
- Tcl_AddErrorInfo(interp, "\n (reading increment)");
- return TCL_ERROR;
- }
- /*
- * Need to be a bit cautious to ensure that [expr]-like rules
- * are enforced for interpretation of wide integers, despite
- * the fact that the underlying API itself is a 'long' only one.
- */
- if (objv[2]->typePtr == &tclIntType) {
- incrAmount = objv[2]->internalRep.longValue;
- } else if (objv[2]->typePtr == &tclWideIntType) {
- TclGetLongFromWide(incrAmount,objv[2]);
- } else {
- Tcl_WideInt wide;
-
- if (Tcl_GetWideIntFromObj(interp, objv[2], &wide) != TCL_OK) {
- Tcl_AddErrorInfo(interp, "\n (reading increment)");
- return TCL_ERROR;
- }
- incrAmount = Tcl_WideAsLong(wide);
- if ((wide <= Tcl_LongAsWide(LONG_MAX))
- && (wide >= Tcl_LongAsWide(LONG_MIN))) {
- objv[2]->typePtr = &tclIntType;
- objv[2]->internalRep.longValue = incrAmount;
- }
- }
+ incrPtr = Tcl_NewIntObj(1);
}
-
- /*
- * Increment the variable's value.
- */
+ Tcl_IncrRefCount(incrPtr);
+ newValuePtr = TclIncrObjVar2(interp, objv[1], NULL,
+ incrPtr, TCL_LEAVE_ERR_MSG);
+ Tcl_DecrRefCount(incrPtr);
- newValuePtr = TclIncrVar2(interp, objv[1], (Tcl_Obj *) NULL, incrAmount,
- TCL_LEAVE_ERR_MSG);
if (newValuePtr == NULL) {
return TCL_ERROR;
}
@@ -391,141 +363,31 @@ Tcl_IncrObjCmd(dummy, interp, objc, objv)
*/
Tcl_SetObjResult(interp, newValuePtr);
- return TCL_OK;
+ return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
- * Tcl_InfoObjCmd --
+ * TclInitInfoCmd --
*
- * This procedure is invoked to process the "info" Tcl command.
- * See the user documentation for details on what it does.
+ * This function is called to create the "info" Tcl command. See the user
+ * documentation for details on what it does.
*
* Results:
- * A standard Tcl result.
+ * FIXME
*
* Side effects:
- * See the user documentation.
+ * none
*
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
-int
-Tcl_InfoObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Arbitrary value passed to the command. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_Command
+TclInitInfoCmd(
+ Tcl_Interp *interp) /* Current interpreter. */
{
- static CONST char *subCmds[] = {
- "args", "body", "cmdcount", "commands",
- "complete", "default", "exists",
-#ifdef TCL_TIP280
- "frame",
-#endif
- "functions",
- "globals", "hostname", "level", "library", "loaded",
- "locals", "nameofexecutable", "patchlevel", "procs",
- "script", "sharedlibextension", "tclversion", "vars",
- (char *) NULL};
- enum ISubCmdIdx {
- IArgsIdx, IBodyIdx, ICmdCountIdx, ICommandsIdx,
- ICompleteIdx, IDefaultIdx, IExistsIdx,
-#ifdef TCL_TIP280
- IFrameIdx,
-#endif
- IFunctionsIdx,
- IGlobalsIdx, IHostnameIdx, ILevelIdx, ILibraryIdx, ILoadedIdx,
- ILocalsIdx, INameOfExecutableIdx, IPatchLevelIdx, IProcsIdx,
- IScriptIdx, ISharedLibExtensionIdx, ITclVersionIdx, IVarsIdx
- };
- int index, result;
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
- return TCL_ERROR;
- }
-
- result = Tcl_GetIndexFromObj(interp, objv[1], subCmds, "option", 0,
- (int *) &index);
- if (result != TCL_OK) {
- return result;
- }
-
- switch (index) {
- case IArgsIdx:
- result = InfoArgsCmd(clientData, interp, objc, objv);
- break;
- case IBodyIdx:
- result = InfoBodyCmd(clientData, interp, objc, objv);
- break;
- case ICmdCountIdx:
- result = InfoCmdCountCmd(clientData, interp, objc, objv);
- break;
- case ICommandsIdx:
- result = InfoCommandsCmd(clientData, interp, objc, objv);
- break;
- case ICompleteIdx:
- result = InfoCompleteCmd(clientData, interp, objc, objv);
- break;
- case IDefaultIdx:
- result = InfoDefaultCmd(clientData, interp, objc, objv);
- break;
- case IExistsIdx:
- result = InfoExistsCmd(clientData, interp, objc, objv);
- break;
-#ifdef TCL_TIP280
- case IFrameIdx:
- /* TIP #280 - New method 'frame' */
- result = InfoFrameCmd(clientData, interp, objc, objv);
- break;
-#endif
- case IFunctionsIdx:
- result = InfoFunctionsCmd(clientData, interp, objc, objv);
- break;
- case IGlobalsIdx:
- result = InfoGlobalsCmd(clientData, interp, objc, objv);
- break;
- case IHostnameIdx:
- result = InfoHostnameCmd(clientData, interp, objc, objv);
- break;
- case ILevelIdx:
- result = InfoLevelCmd(clientData, interp, objc, objv);
- break;
- case ILibraryIdx:
- result = InfoLibraryCmd(clientData, interp, objc, objv);
- break;
- case ILoadedIdx:
- result = InfoLoadedCmd(clientData, interp, objc, objv);
- break;
- case ILocalsIdx:
- result = InfoLocalsCmd(clientData, interp, objc, objv);
- break;
- case INameOfExecutableIdx:
- result = InfoNameOfExecutableCmd(clientData, interp, objc, objv);
- break;
- case IPatchLevelIdx:
- result = InfoPatchLevelCmd(clientData, interp, objc, objv);
- break;
- case IProcsIdx:
- result = InfoProcsCmd(clientData, interp, objc, objv);
- break;
- case IScriptIdx:
- result = InfoScriptCmd(clientData, interp, objc, objv);
- break;
- case ISharedLibExtensionIdx:
- result = InfoSharedlibCmd(clientData, interp, objc, objv);
- break;
- case ITclVersionIdx:
- result = InfoTclVersionCmd(clientData, interp, objc, objv);
- break;
- case IVarsIdx:
- result = InfoVarsCmd(clientData, interp, objc, objv);
- break;
- }
- return result;
+ return TclMakeEnsemble(interp, "info", defaultInfoMap);
}
/*
@@ -533,27 +395,27 @@ Tcl_InfoObjCmd(clientData, interp, objc, objv)
*
* InfoArgsCmd --
*
- * Called to implement the "info args" command that returns the
- * argument list for a procedure. Handles the following syntax:
+ * Called to implement the "info args" command that returns the argument
+ * list for a procedure. Handles the following syntax:
*
- * info args procName
+ * info args procName
*
* Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ * Returns TCL_OK if successful and TCL_ERROR if there is an error.
*
* Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message.
+ * Returns a result in the interpreter's result object. If there is an
+ * error, the result is an error message.
*
*----------------------------------------------------------------------
*/
static int
-InfoArgsCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+InfoArgsCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
register Interp *iPtr = (Interp *) interp;
char *name;
@@ -561,30 +423,29 @@ InfoArgsCmd(dummy, interp, objc, objv)
CompiledLocal *localPtr;
Tcl_Obj *listObjPtr;
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "procname");
- return TCL_ERROR;
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "procname");
+ return TCL_ERROR;
}
- name = Tcl_GetString(objv[2]);
+ name = TclGetString(objv[1]);
procPtr = TclFindProc(iPtr, name);
if (procPtr == NULL) {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "\"", name, "\" isn't a procedure", (char *) NULL);
- return TCL_ERROR;
+ Tcl_AppendResult(interp, "\"", name, "\" isn't a procedure", NULL);
+ return TCL_ERROR;
}
/*
* Build a return list containing the arguments.
*/
-
- listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
+
+ listObjPtr = Tcl_NewListObj(0, NULL);
for (localPtr = procPtr->firstLocalPtr; localPtr != NULL;
- localPtr = localPtr->nextPtr) {
- if (TclIsVarArgument(localPtr)) {
- Tcl_ListObjAppendElement(interp, listObjPtr,
+ localPtr = localPtr->nextPtr) {
+ if (TclIsVarArgument(localPtr)) {
+ Tcl_ListObjAppendElement(interp, listObjPtr,
Tcl_NewStringObj(localPtr->name, -1));
- }
+ }
}
Tcl_SetObjResult(interp, listObjPtr);
return TCL_OK;
@@ -595,65 +456,65 @@ InfoArgsCmd(dummy, interp, objc, objv)
*
* InfoBodyCmd --
*
- * Called to implement the "info body" command that returns the body
- * for a procedure. Handles the following syntax:
+ * Called to implement the "info body" command that returns the body for
+ * a procedure. Handles the following syntax:
*
- * info body procName
+ * info body procName
*
* Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ * Returns TCL_OK if successful and TCL_ERROR if there is an error.
*
* Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message.
+ * Returns a result in the interpreter's result object. If there is an
+ * error, the result is an error message.
*
*----------------------------------------------------------------------
*/
static int
-InfoBodyCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+InfoBodyCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
register Interp *iPtr = (Interp *) interp;
char *name;
Proc *procPtr;
Tcl_Obj *bodyPtr, *resultPtr;
-
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "procname");
- return TCL_ERROR;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "procname");
+ return TCL_ERROR;
}
- name = Tcl_GetString(objv[2]);
+ name = TclGetString(objv[1]);
procPtr = TclFindProc(iPtr, name);
if (procPtr == NULL) {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "\"", name, "\" isn't a procedure", (char *) NULL);
- return TCL_ERROR;
+ Tcl_AppendResult(interp, "\"", name, "\" isn't a procedure", NULL);
+ return TCL_ERROR;
}
- /*
+ /*
* Here we used to return procPtr->bodyPtr, except when the body was
- * bytecompiled - in that case, the return was a copy of the body's
- * string rep. In order to better isolate the implementation details
- * of the compiler/engine subsystem, we now always return a copy of
- * the string rep. It is important to return a copy so that later
- * manipulations of the object do not invalidate the internal rep.
+ * bytecompiled - in that case, the return was a copy of the body's string
+ * rep. In order to better isolate the implementation details of the
+ * compiler/engine subsystem, we now always return a copy of the string
+ * rep. It is important to return a copy so that later manipulations of
+ * the object do not invalidate the internal rep.
*/
bodyPtr = procPtr->bodyPtr;
if (bodyPtr->bytes == NULL) {
/*
- * The string rep might not be valid if the procedure has
- * never been run before. [Bug #545644]
+ * The string rep might not be valid if the procedure has never been
+ * run before. [Bug #545644]
*/
- (void) Tcl_GetString(bodyPtr);
+
+ (void) TclGetString(bodyPtr);
}
resultPtr = Tcl_NewStringObj(bodyPtr->bytes, bodyPtr->length);
-
+
Tcl_SetObjResult(interp, resultPtr);
return TCL_OK;
}
@@ -663,37 +524,37 @@ InfoBodyCmd(dummy, interp, objc, objv)
*
* InfoCmdCountCmd --
*
- * Called to implement the "info cmdcount" command that returns the
- * number of commands that have been executed. Handles the following
- * syntax:
+ * Called to implement the "info cmdcount" command that returns the
+ * number of commands that have been executed. Handles the following
+ * syntax:
*
- * info cmdcount
+ * info cmdcount
*
* Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ * Returns TCL_OK if successful and TCL_ERROR if there is an error.
*
* Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message.
+ * Returns a result in the interpreter's result object. If there is an
+ * error, the result is an error message.
*
*----------------------------------------------------------------------
*/
static int
-InfoCmdCountCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+InfoCmdCountCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Interp *iPtr = (Interp *) interp;
-
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return TCL_ERROR;
+
+ if (objc != 1) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return TCL_ERROR;
}
- Tcl_SetIntObj(Tcl_GetObjResult(interp), iPtr->cmdCount);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(iPtr->cmdCount));
return TCL_OK;
}
@@ -702,31 +563,31 @@ InfoCmdCountCmd(dummy, interp, objc, objv)
*
* InfoCommandsCmd --
*
- * Called to implement the "info commands" command that returns the
- * list of commands in the interpreter that match an optional pattern.
- * The pattern, if any, consists of an optional sequence of namespace
- * names separated by "::" qualifiers, which is followed by a
- * glob-style pattern that restricts which commands are returned.
- * Handles the following syntax:
+ * Called to implement the "info commands" command that returns the list
+ * of commands in the interpreter that match an optional pattern. The
+ * pattern, if any, consists of an optional sequence of namespace names
+ * separated by "::" qualifiers, which is followed by a glob-style
+ * pattern that restricts which commands are returned. Handles the
+ * following syntax:
*
- * info commands ?pattern?
+ * info commands ?pattern?
*
* Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ * Returns TCL_OK if successful and TCL_ERROR if there is an error.
*
* Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message.
+ * Returns a result in the interpreter's result object. If there is an
+ * error, the result is an error message.
*
*----------------------------------------------------------------------
*/
static int
-InfoCommandsCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+InfoCommandsCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
char *cmdName, *pattern;
CONST char *simplePattern;
@@ -734,42 +595,42 @@ InfoCommandsCmd(dummy, interp, objc, objv)
Tcl_HashSearch search;
Namespace *nsPtr;
Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp);
- Namespace *currNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
+ Namespace *currNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
Tcl_Obj *listPtr, *elemObjPtr;
- int specificNsInPattern = 0; /* Init. to avoid compiler warning. */
+ int specificNsInPattern = 0;/* Init. to avoid compiler warning. */
Tcl_Command cmd;
+ int i;
/*
- * Get the pattern and find the "effective namespace" in which to
- * list commands.
+ * Get the pattern and find the "effective namespace" in which to list
+ * commands.
*/
- if (objc == 2) {
- simplePattern = NULL;
+ if (objc == 1) {
+ simplePattern = NULL;
nsPtr = currNsPtr;
specificNsInPattern = 0;
- } else if (objc == 3) {
+ } else if (objc == 2) {
/*
* From the pattern, get the effective namespace and the simple
- * pattern (no namespace qualifiers or ::'s) at the end. If an
- * error was found while parsing the pattern, return it. Otherwise,
- * if the namespace wasn't found, just leave nsPtr NULL: we will
- * return an empty list since no commands there can be found.
+ * pattern (no namespace qualifiers or ::'s) at the end. If an error
+ * was found while parsing the pattern, return it. Otherwise, if the
+ * namespace wasn't found, just leave nsPtr NULL: we will return an
+ * empty list since no commands there can be found.
*/
Namespace *dummy1NsPtr, *dummy2NsPtr;
-
- pattern = Tcl_GetString(objv[2]);
- TclGetNamespaceForQualName(interp, pattern, (Namespace *) NULL,
- /*flags*/ 0, &nsPtr, &dummy1NsPtr, &dummy2NsPtr, &simplePattern);
+ pattern = TclGetString(objv[1]);
+ TclGetNamespaceForQualName(interp, pattern, (Namespace *) NULL, 0,
+ &nsPtr, &dummy1NsPtr, &dummy2NsPtr, &simplePattern);
- if (nsPtr != NULL) { /* we successfully found the pattern's ns */
+ if (nsPtr != NULL) { /* We successfully found the pattern's ns. */
specificNsInPattern = (strcmp(simplePattern, pattern) != 0);
}
} else {
- Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");
- return TCL_ERROR;
+ Tcl_WrongNumArgs(interp, 1, objv, "?pattern?");
+ return TCL_ERROR;
}
/*
@@ -781,20 +642,20 @@ InfoCommandsCmd(dummy, interp, objc, objv)
}
/*
- * Scan through the effective namespace's command table and create a
- * list with all commands that match the pattern. If a specific
- * namespace was requested in the pattern, qualify the command names
- * with the namespace name.
+ * Scan through the effective namespace's command table and create a list
+ * with all commands that match the pattern. If a specific namespace was
+ * requested in the pattern, qualify the command names with the namespace
+ * name.
*/
- listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
+ listPtr = Tcl_NewListObj(0, NULL);
if (simplePattern != NULL && TclMatchIsTrivial(simplePattern)) {
/*
- * Special case for when the pattern doesn't include any of
- * glob's special characters. This lets us avoid scans of any
- * hash tables.
+ * Special case for when the pattern doesn't include any of glob's
+ * special characters. This lets us avoid scans of any hash tables.
*/
+
entryPtr = Tcl_FindHashEntry(&nsPtr->cmdTable, simplePattern);
if (entryPtr != NULL) {
if (specificNsInPattern) {
@@ -806,21 +667,48 @@ InfoCommandsCmd(dummy, interp, objc, objv)
elemObjPtr = Tcl_NewStringObj(cmdName, -1);
}
Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr);
- } else if ((nsPtr != globalNsPtr) && !specificNsInPattern) {
- entryPtr = Tcl_FindHashEntry(&globalNsPtr->cmdTable,
- simplePattern);
+ Tcl_SetObjResult(interp, listPtr);
+ return TCL_OK;
+ }
+ if ((nsPtr != globalNsPtr) && !specificNsInPattern) {
+ Tcl_HashTable *tablePtr = NULL; /* Quell warning. */
+
+ for (i=0 ; i<nsPtr->commandPathLength ; i++) {
+ Namespace *pathNsPtr = nsPtr->commandPathArray[i].nsPtr;
+
+ if (pathNsPtr == NULL) {
+ continue;
+ }
+ tablePtr = &pathNsPtr->cmdTable;
+ entryPtr = Tcl_FindHashEntry(tablePtr, simplePattern);
+ if (entryPtr != NULL) {
+ break;
+ }
+ }
+ if (entryPtr == NULL) {
+ tablePtr = &globalNsPtr->cmdTable;
+ entryPtr = Tcl_FindHashEntry(tablePtr, simplePattern);
+ }
if (entryPtr != NULL) {
- cmdName = Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr);
+ cmdName = Tcl_GetHashKey(tablePtr, entryPtr);
Tcl_ListObjAppendElement(interp, listPtr,
Tcl_NewStringObj(cmdName, -1));
+ Tcl_SetObjResult(interp, listPtr);
+ return TCL_OK;
}
}
- } else {
+ } else if (nsPtr->commandPathLength == 0 || specificNsInPattern) {
+ /*
+ * The pattern is non-trivial, but either there is no explicit path or
+ * there is an explicit namespace in the pattern. In both cases, the
+ * old matching scheme is perfect.
+ */
+
entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
while (entryPtr != NULL) {
cmdName = Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr);
if ((simplePattern == NULL)
- || Tcl_StringMatch(cmdName, simplePattern)) {
+ || Tcl_StringMatch(cmdName, simplePattern)) {
if (specificNsInPattern) {
cmd = (Tcl_Command) Tcl_GetHashValue(entryPtr);
elemObjPtr = Tcl_NewObj();
@@ -835,19 +723,19 @@ InfoCommandsCmd(dummy, interp, objc, objv)
/*
* If the effective namespace isn't the global :: namespace, and a
- * specific namespace wasn't requested in the pattern, then add in
- * all global :: commands that match the simple pattern. Of course,
- * we add in only those commands that aren't hidden by a command in
- * the effective namespace.
+ * specific namespace wasn't requested in the pattern, then add in all
+ * global :: commands that match the simple pattern. Of course, we add
+ * in only those commands that aren't hidden by a command in the
+ * effective namespace.
*/
-
+
if ((nsPtr != globalNsPtr) && !specificNsInPattern) {
entryPtr = Tcl_FirstHashEntry(&globalNsPtr->cmdTable, &search);
while (entryPtr != NULL) {
cmdName = Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr);
if ((simplePattern == NULL)
- || Tcl_StringMatch(cmdName, simplePattern)) {
- if (Tcl_FindHashEntry(&nsPtr->cmdTable, cmdName) == NULL) {
+ || Tcl_StringMatch(cmdName, simplePattern)) {
+ if (Tcl_FindHashEntry(&nsPtr->cmdTable,cmdName) == NULL) {
Tcl_ListObjAppendElement(interp, listPtr,
Tcl_NewStringObj(cmdName, -1));
}
@@ -855,8 +743,97 @@ InfoCommandsCmd(dummy, interp, objc, objv)
entryPtr = Tcl_NextHashEntry(&search);
}
}
+ } else {
+ /*
+ * The pattern is non-trivial (can match more than one command name),
+ * there is an explicit path, and there is no explicit namespace in
+ * the pattern. This means that we have to traverse the path to
+ * discover all the commands defined.
+ */
+
+ Tcl_HashTable addedCommandsTable;
+ int isNew;
+ int foundGlobal = (nsPtr == globalNsPtr);
+
+ /*
+ * We keep a hash of the objects already added to the result list.
+ */
+
+ Tcl_InitObjHashTable(&addedCommandsTable);
+
+ entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
+ while (entryPtr != NULL) {
+ cmdName = Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr);
+ if ((simplePattern == NULL)
+ || Tcl_StringMatch(cmdName, simplePattern)) {
+ elemObjPtr = Tcl_NewStringObj(cmdName, -1);
+ Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr);
+ (void) Tcl_CreateHashEntry(&addedCommandsTable,
+ (char *)elemObjPtr, &isNew);
+ }
+ entryPtr = Tcl_NextHashEntry(&search);
+ }
+
+ /*
+ * Search the path next.
+ */
+
+ for (i=0 ; i<nsPtr->commandPathLength ; i++) {
+ Namespace *pathNsPtr = nsPtr->commandPathArray[i].nsPtr;
+
+ if (pathNsPtr == NULL) {
+ continue;
+ }
+ if (pathNsPtr == globalNsPtr) {
+ foundGlobal = 1;
+ }
+ entryPtr = Tcl_FirstHashEntry(&pathNsPtr->cmdTable, &search);
+ while (entryPtr != NULL) {
+ cmdName = Tcl_GetHashKey(&pathNsPtr->cmdTable, entryPtr);
+ if ((simplePattern == NULL)
+ || Tcl_StringMatch(cmdName, simplePattern)) {
+ elemObjPtr = Tcl_NewStringObj(cmdName, -1);
+ (void) Tcl_CreateHashEntry(&addedCommandsTable,
+ (char *) elemObjPtr, &isNew);
+ if (isNew) {
+ Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr);
+ } else {
+ TclDecrRefCount(elemObjPtr);
+ }
+ }
+ entryPtr = Tcl_NextHashEntry(&search);
+ }
+ }
+
+ /*
+ * If the effective namespace isn't the global :: namespace, and a
+ * specific namespace wasn't requested in the pattern, then add in all
+ * global :: commands that match the simple pattern. Of course, we add
+ * in only those commands that aren't hidden by a command in the
+ * effective namespace.
+ */
+
+ if (!foundGlobal) {
+ entryPtr = Tcl_FirstHashEntry(&globalNsPtr->cmdTable, &search);
+ while (entryPtr != NULL) {
+ cmdName = Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr);
+ if ((simplePattern == NULL)
+ || Tcl_StringMatch(cmdName, simplePattern)) {
+ elemObjPtr = Tcl_NewStringObj(cmdName, -1);
+ if (Tcl_FindHashEntry(&addedCommandsTable,
+ (char *) elemObjPtr) == NULL) {
+ Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr);
+ } else {
+ TclDecrRefCount(elemObjPtr);
+ }
+ }
+ entryPtr = Tcl_NextHashEntry(&search);
+ }
+ }
+
+ Tcl_DeleteHashTable(&addedCommandsTable);
}
-
+
Tcl_SetObjResult(interp, listPtr);
return TCL_OK;
}
@@ -866,40 +843,36 @@ InfoCommandsCmd(dummy, interp, objc, objv)
*
* InfoCompleteCmd --
*
- * Called to implement the "info complete" command that determines
- * whether a string is a complete Tcl command. Handles the following
- * syntax:
+ * Called to implement the "info complete" command that determines
+ * whether a string is a complete Tcl command. Handles the following
+ * syntax:
*
- * info complete command
+ * info complete command
*
* Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ * Returns TCL_OK if successful and TCL_ERROR if there is an error.
*
* Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message.
+ * Returns a result in the interpreter's result object. If there is an
+ * error, the result is an error message.
*
*----------------------------------------------------------------------
*/
static int
-InfoCompleteCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+InfoCompleteCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "command");
- return TCL_ERROR;
- }
-
- if (TclObjCommandComplete(objv[2])) {
- Tcl_SetIntObj(Tcl_GetObjResult(interp), 1);
- } else {
- Tcl_SetIntObj(Tcl_GetObjResult(interp), 0);
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "command");
+ return TCL_ERROR;
}
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
+ TclObjCommandComplete(objv[1])));
return TCL_OK;
}
@@ -908,28 +881,27 @@ InfoCompleteCmd(dummy, interp, objc, objv)
*
* InfoDefaultCmd --
*
- * Called to implement the "info default" command that returns the
- * default value for a procedure argument. Handles the following
- * syntax:
+ * Called to implement the "info default" command that returns the
+ * default value for a procedure argument. Handles the following syntax:
*
- * info default procName arg varName
+ * info default procName arg varName
*
* Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ * Returns TCL_OK if successful and TCL_ERROR if there is an error.
*
* Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message.
+ * Returns a result in the interpreter's result object. If there is an
+ * error, the result is an error message.
*
*----------------------------------------------------------------------
*/
static int
-InfoDefaultCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+InfoDefaultCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Interp *iPtr = (Interp *) interp;
char *procName, *argName, *varName;
@@ -937,484 +909,447 @@ InfoDefaultCmd(dummy, interp, objc, objv)
CompiledLocal *localPtr;
Tcl_Obj *valueObjPtr;
- if (objc != 5) {
- Tcl_WrongNumArgs(interp, 2, objv, "procname arg varname");
- return TCL_ERROR;
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 1, objv, "procname arg varname");
+ return TCL_ERROR;
}
- procName = Tcl_GetString(objv[2]);
- argName = Tcl_GetString(objv[3]);
+ procName = TclGetString(objv[1]);
+ argName = TclGetString(objv[2]);
procPtr = TclFindProc(iPtr, procName);
if (procPtr == NULL) {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "\"", procName, "\" isn't a procedure", (char *) NULL);
- return TCL_ERROR;
+ Tcl_AppendResult(interp, "\"", procName, "\" isn't a procedure",NULL);
+ return TCL_ERROR;
}
for (localPtr = procPtr->firstLocalPtr; localPtr != NULL;
- localPtr = localPtr->nextPtr) {
- if (TclIsVarArgument(localPtr)
+ localPtr = localPtr->nextPtr) {
+ if (TclIsVarArgument(localPtr)
&& (strcmp(argName, localPtr->name) == 0)) {
- if (localPtr->defValuePtr != NULL) {
- valueObjPtr = Tcl_ObjSetVar2(interp, objv[4], NULL,
+ if (localPtr->defValuePtr != NULL) {
+ valueObjPtr = Tcl_ObjSetVar2(interp, objv[3], NULL,
localPtr->defValuePtr, 0);
- if (valueObjPtr == NULL) {
- defStoreError:
- varName = Tcl_GetString(objv[4]);
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "couldn't store default value in variable \"",
- varName, "\"", (char *) NULL);
- return TCL_ERROR;
- }
- Tcl_SetIntObj(Tcl_GetObjResult(interp), 1);
- } else {
- Tcl_Obj *nullObjPtr = Tcl_NewObj();
- Tcl_IncrRefCount(nullObjPtr);
- valueObjPtr = Tcl_ObjSetVar2(interp, objv[4], NULL,
+ if (valueObjPtr == NULL) {
+ goto defStoreError;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
+ } else {
+ Tcl_Obj *nullObjPtr = Tcl_NewObj();
+ valueObjPtr = Tcl_ObjSetVar2(interp, objv[3], NULL,
nullObjPtr, 0);
- Tcl_DecrRefCount(nullObjPtr); /* free unneeded obj */
- if (valueObjPtr == NULL) {
- goto defStoreError;
- }
- Tcl_SetIntObj(Tcl_GetObjResult(interp), 0);
- }
- return TCL_OK;
- }
- }
-
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "procedure \"", procName, "\" doesn't have an argument \"",
- argName, "\"", (char *) NULL);
+ if (valueObjPtr == NULL) {
+ goto defStoreError;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
+ }
+ return TCL_OK;
+ }
+ }
+
+ Tcl_AppendResult(interp, "procedure \"", procName,
+ "\" doesn't have an argument \"", argName, "\"", NULL);
+ return TCL_ERROR;
+
+ defStoreError:
+ varName = TclGetString(objv[3]);
+ Tcl_AppendResult(interp, "couldn't store default value in variable \"",
+ varName, "\"", NULL);
return TCL_ERROR;
}
/*
*----------------------------------------------------------------------
*
- * InfoExistsCmd --
+ * TclInfoExistsCmd --
*
- * Called to implement the "info exists" command that determines
- * whether a variable exists. Handles the following syntax:
+ * Called to implement the "info exists" command that determines whether
+ * a variable exists. Handles the following syntax:
*
- * info exists varName
+ * info exists varName
*
* Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ * Returns TCL_OK if successful and TCL_ERROR if there is an error.
*
* Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message.
+ * Returns a result in the interpreter's result object. If there is an
+ * error, the result is an error message.
*
*----------------------------------------------------------------------
*/
-static int
-InfoExistsCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+int
+TclInfoExistsCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
char *varName;
Var *varPtr;
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "varName");
- return TCL_ERROR;
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "varName");
+ return TCL_ERROR;
}
- varName = Tcl_GetString(objv[2]);
+ varName = TclGetString(objv[1]);
varPtr = TclVarTraceExists(interp, varName);
- if ((varPtr != NULL) && !TclIsVarUndefined(varPtr)) {
- Tcl_SetIntObj(Tcl_GetObjResult(interp), 1);
- } else {
- Tcl_SetIntObj(Tcl_GetObjResult(interp), 0);
- }
+
+ Tcl_SetObjResult(interp,
+ Tcl_NewBooleanObj(varPtr && varPtr->value.objPtr));
return TCL_OK;
}
-#ifdef TCL_TIP280
/*
*----------------------------------------------------------------------
*
* InfoFrameCmd --
* TIP #280
*
- * Called to implement the "info frame" command that returns the
- * location of either the currently executing command, or its caller.
- * Handles the following syntax:
+ * Called to implement the "info frame" command that returns the location
+ * of either the currently executing command, or its caller. Handles the
+ * following syntax:
*
- * info frame ?number?
+ * info frame ?number?
*
* Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ * Returns TCL_OK if successful and TCL_ERROR if there is an error.
*
* Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message.
+ * Returns a result in the interpreter's result object. If there is an
+ * error, the result is an error message.
*
*----------------------------------------------------------------------
*/
static int
-InfoFrameCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+InfoFrameCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Interp *iPtr = (Interp *) interp;
+ int level;
+ CmdFrame *framePtr;
- if (objc == 2) {
- /* just "info frame" */
- int levels = (iPtr->cmdFramePtr == NULL
- ? 0
- : iPtr->cmdFramePtr->level);
+ if (objc == 1) {
+ /*
+ * Just "info frame".
+ */
+
+ int levels =
+ (iPtr->cmdFramePtr == NULL ? 0 : iPtr->cmdFramePtr->level);
Tcl_SetObjResult(interp, Tcl_NewIntObj (levels));
- return TCL_OK;
-
- } else if (objc == 3) {
- /* "info frame level" */
- int level;
- CmdFrame *framePtr;
-
- if (Tcl_GetIntFromObj(interp, objv[2], &level) != TCL_OK) {
- return TCL_ERROR;
- }
- if (level <= 0) {
- /* Relative adressing */
-
- if (iPtr->cmdFramePtr == NULL) {
- levelError:
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "bad level \"",
- Tcl_GetString(objv[2]),
- "\"", (char *) NULL);
- return TCL_ERROR;
- }
- /* Convert to absolute. */
-
- level += iPtr->cmdFramePtr->level;
- }
- for (framePtr = iPtr->cmdFramePtr;
- framePtr != NULL;
- framePtr = framePtr->nextPtr) {
+ return TCL_OK;
+ } else if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "?number?");
+ return TCL_ERROR;
+ }
- if (framePtr->level == level) {
- break;
- }
- }
- if (framePtr == NULL) {
- goto levelError;
- }
+ /*
+ * We've got "info frame level" and must parse the level first.
+ */
+ if (TclGetIntFromObj(interp, objv[1], &level) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (level <= 0) {
/*
- * Pull the information and construct the dictionary to return, as
- * list. Regarding use of the CmdFrame fields see tclInt.h, and its
- * definition.
+ * Negative levels are adressing relative to the current frame's
+ * depth.
*/
- {
- Tcl_Obj* lv [20]; /* Keep uptodate when more keys are added to the dict */
- int lc = 0;
+ if (iPtr->cmdFramePtr == NULL) {
+ levelError:
+ Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "bad level \"",
+ TclGetString(objv[1]), "\"", NULL);
+ return TCL_ERROR;
+ }
- /* This array is indexed by the TCL_LOCATION_... values, except
- * for _LAST.
- */
+ /*
+ * Convert to absolute.
+ */
- static CONST char* typeString [TCL_LOCATION_LAST] = {
- "eval", "eval", "eval", "precompiled", "source", "proc"
- };
+ level += iPtr->cmdFramePtr->level;
+ }
- Proc* procPtr = framePtr->framePtr ? framePtr->framePtr->procPtr : NULL;
+ for (framePtr = iPtr->cmdFramePtr; framePtr != NULL;
+ framePtr = framePtr->nextPtr) {
+ if (framePtr->level == level) {
+ break;
+ }
+ }
+ if (framePtr == NULL) {
+ goto levelError;
+ }
- switch (framePtr->type) {
- case TCL_LOCATION_EVAL:
- /* Evaluation, dynamic script. Type, line, cmd, the latter
- * through str. */
+ Tcl_SetObjResult(interp, TclInfoFrame(interp, framePtr));
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInfoFrame --
+ *
+ * Core of InfoFrameCmd, returns TIP280 dict for a given frame.
+ *
+ * Results:
+ * Returns TIP280 dict.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
- lv [lc ++] = Tcl_NewStringObj ("type",-1);
- lv [lc ++] = Tcl_NewStringObj (typeString [framePtr->type],-1);
- lv [lc ++] = Tcl_NewStringObj ("line",-1);
- lv [lc ++] = Tcl_NewIntObj (framePtr->line[0]);
- lv [lc ++] = Tcl_NewStringObj ("cmd",-1);
- lv [lc ++] = Tcl_NewStringObj (framePtr->cmd.str.cmd,
- framePtr->cmd.str.len);
- break;
+Tcl_Obj *
+TclInfoFrame(
+ Tcl_Interp *interp, /* Current interpreter. */
+ CmdFrame *framePtr) /* Frame to get info for. */
+{
+ Interp *iPtr = (Interp *) interp;
+ Tcl_Obj *lv[20]; /* Keep uptodate when more keys are added to
+ * the dict. */
+ int lc = 0;
+ /*
+ * This array is indexed by the TCL_LOCATION_... values, except
+ * for _LAST.
+ */
+ static CONST char *typeString[TCL_LOCATION_LAST] = {
+ "eval", "eval", "eval", "precompiled", "source", "proc"
+ };
+ Tcl_Obj *tmpObj;
+ Proc *procPtr =
+ framePtr->framePtr ? framePtr->framePtr->procPtr : NULL;
- case TCL_LOCATION_EVAL_LIST:
- /* List optimized evaluation. Type, line, cmd, the latter
- * through listPtr, possibly a frame. */
+ /*
+ * Pull the information and construct the dictionary to return, as list.
+ * Regarding use of the CmdFrame fields see tclInt.h, and its definition.
+ */
- lv [lc ++] = Tcl_NewStringObj ("type",-1);
- lv [lc ++] = Tcl_NewStringObj (typeString [framePtr->type],-1);
- lv [lc ++] = Tcl_NewStringObj ("line",-1);
- lv [lc ++] = Tcl_NewIntObj (1);
+#define ADD_PAIR(name, value) \
+ TclNewLiteralStringObj(tmpObj, name); \
+ lv[lc++] = tmpObj; \
+ lv[lc++] = (value)
- /* 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.
- */
+ switch (framePtr->type) {
+ case TCL_LOCATION_EVAL:
+ /*
+ * Evaluation, dynamic script. Type, line, cmd, the latter through
+ * str.
+ */
- lv [lc ++] = Tcl_NewStringObj ("cmd",-1);
- lv [lc ++] = Tcl_DuplicateObj (framePtr->cmd.listPtr);
- break;
+ 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_PREBC:
- /* Precompiled. Result contains the type as signal, nothing
- * else */
+ case TCL_LOCATION_EVAL_LIST:
+ /*
+ * List optimized evaluation. Type, line, cmd, the latter through
+ * listPtr, possibly a frame.
+ */
- lv [lc ++] = Tcl_NewStringObj ("type",-1);
- lv [lc ++] = Tcl_NewStringObj (typeString [framePtr->type],-1);
- break;
+ ADD_PAIR("type", Tcl_NewStringObj(typeString[framePtr->type], -1));
+ ADD_PAIR("line", Tcl_NewIntObj(1));
- case TCL_LOCATION_BC: {
- /* Execution of bytecode. Talk to the BC engine to fill out
- * the frame. */
+ /*
+ * 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.
+ */
- CmdFrame f = *framePtr;
+ ADD_PAIR("cmd", Tcl_DuplicateObj(framePtr->cmd.listPtr));
+ break;
- /* Note: Type BC => f.data.eval.path is not used.
- * f.data.tebc.codePtr is used instead.
- */
+ case TCL_LOCATION_PREBC:
+ /*
+ * Precompiled. Result contains the type as signal, nothing else.
+ */
- TclGetSrcInfoForPc (&f);
- /* Now filled: cmd.str.(cmd,len), line */
- /* Possibly modified: type, path! */
+ ADD_PAIR("type", Tcl_NewStringObj(typeString[framePtr->type], -1));
+ break;
- lv [lc ++] = Tcl_NewStringObj ("type",-1);
- lv [lc ++] = Tcl_NewStringObj (typeString [f.type],-1);
- lv [lc ++] = Tcl_NewStringObj ("line",-1);
- lv [lc ++] = Tcl_NewIntObj (f.line[0]);
+ case TCL_LOCATION_BC: {
+ /*
+ * Execution of bytecode. Talk to the BC engine to fill out the frame.
+ */
- if (f.type == TCL_LOCATION_SOURCE) {
- lv [lc ++] = Tcl_NewStringObj ("file",-1);
- lv [lc ++] = f.data.eval.path;
- /* Death of reference by TclGetSrcInfoForPc */
- Tcl_DecrRefCount (f.data.eval.path);
- }
+ CmdFrame *fPtr;
- lv [lc ++] = Tcl_NewStringObj ("cmd",-1);
- lv [lc ++] = Tcl_NewStringObj (f.cmd.str.cmd, f.cmd.str.len);
- break;
- }
+ fPtr = (CmdFrame *) TclStackAlloc(interp, sizeof(CmdFrame));
+ *fPtr = *framePtr;
- case TCL_LOCATION_SOURCE:
- /* Evaluation of a script file */
-
- lv [lc ++] = Tcl_NewStringObj ("type",-1);
- lv [lc ++] = Tcl_NewStringObj (typeString [framePtr->type],-1);
- lv [lc ++] = Tcl_NewStringObj ("line",-1);
- lv [lc ++] = Tcl_NewIntObj (framePtr->line[0]);
- lv [lc ++] = Tcl_NewStringObj ("file",-1);
- lv [lc ++] = framePtr->data.eval.path;
- /* Refcount framePtr->data.eval.path goes up when lv
- * is converted into the result list object.
- */
- lv [lc ++] = Tcl_NewStringObj ("cmd",-1);
- lv [lc ++] = Tcl_NewStringObj (framePtr->cmd.str.cmd,
- framePtr->cmd.str.len);
- break;
+ /*
+ * Note:
+ * Type BC => f.data.eval.path is not used.
+ * f.data.tebc.codePtr is used instead.
+ */
- case TCL_LOCATION_PROC:
- Tcl_Panic ("TCL_LOCATION_PROC found in standard frame");
- break;
- }
+ TclGetSrcInfoForPc(fPtr);
+
+ /*
+ * Now filled: cmd.str.(cmd,len), line
+ * Possibly modified: type, path!
+ */
+
+ ADD_PAIR("type", Tcl_NewStringObj(typeString[fPtr->type], -1));
+ if (fPtr->line) {
+ ADD_PAIR("line", Tcl_NewIntObj(fPtr->line[0]));
+ }
+
+ if (fPtr->type == TCL_LOCATION_SOURCE) {
+ ADD_PAIR("file", fPtr->data.eval.path);
/*
- * 'proc'. Common to all frame types. Conditional on having an
- * associated Procedure CallFrame.
+ * Death of reference by TclGetSrcInfoForPc.
*/
- if (procPtr != NULL) {
- Tcl_HashEntry* namePtr = procPtr->cmdPtr->hPtr;
- /*
- * ITcl seems to provide us with weird, maybe bogus Command
- * structures (methods?) which may have no HashEntry pointing
- * to the name information, or a HashEntry without owning
- * HashTable. Therefore check again that our data is valid.
- */
- if (namePtr && namePtr->tablePtr) {
- char* procName = Tcl_GetHashKey (namePtr->tablePtr, namePtr);
- char* nsName = procPtr->cmdPtr->nsPtr->fullName;
+ Tcl_DecrRefCount(fPtr->data.eval.path);
+ }
- lv [lc ++] = Tcl_NewStringObj ("proc",-1);
- lv [lc ++] = Tcl_NewStringObj (nsName,-1);
+ ADD_PAIR("cmd",
+ Tcl_NewStringObj(fPtr->cmd.str.cmd, fPtr->cmd.str.len));
+ TclStackFree(interp, fPtr);
+ break;
+ }
- if (strcmp (nsName, "::") != 0) {
- Tcl_AppendToObj (lv [lc-1], "::", -1);
- }
- Tcl_AppendToObj (lv [lc-1], procName, -1);
- }
- }
+ case TCL_LOCATION_SOURCE:
+ /*
+ * Evaluation of a script file.
+ */
- /* 'level'. Common to all frame types. Conditional on having an
- * associated _visible_ CallFrame */
+ ADD_PAIR("type", Tcl_NewStringObj(typeString[framePtr->type], -1));
+ ADD_PAIR("line", Tcl_NewIntObj(framePtr->line[0]));
+ ADD_PAIR("file", framePtr->data.eval.path);
- if ((framePtr->framePtr != NULL) && (iPtr->varFramePtr != NULL)) {
- CallFrame* current = framePtr->framePtr;
- CallFrame* top = iPtr->varFramePtr;
- CallFrame* idx;
+ /*
+ * Refcount framePtr->data.eval.path goes up when lv is converted into
+ * the result list object.
+ */
- for (idx = top;
- idx != NULL;
- idx = idx->callerVarPtr) {
- if (idx == current) {
- int c = framePtr->framePtr->level;
- int t = iPtr->varFramePtr->level;
+ ADD_PAIR("cmd", Tcl_NewStringObj(framePtr->cmd.str.cmd,
+ framePtr->cmd.str.len));
+ break;
- lv [lc ++] = Tcl_NewStringObj ("level",-1);
- lv [lc ++] = Tcl_NewIntObj (t - c);
- break;
- }
- }
+ case TCL_LOCATION_PROC:
+ Tcl_Panic("TCL_LOCATION_PROC found in standard frame");
+ break;
+ }
+
+ /*
+ * 'proc'. Common to all frame types. Conditional on having an associated
+ * Procedure CallFrame.
+ */
+
+ if (procPtr != NULL) {
+ Tcl_HashEntry *namePtr = procPtr->cmdPtr->hPtr;
+
+ if (namePtr) {
+ /*
+ * This is a regular command.
+ */
+
+ char *procName = Tcl_GetHashKey(namePtr->tablePtr, namePtr);
+ char *nsName = procPtr->cmdPtr->nsPtr->fullName;
+
+ ADD_PAIR("proc", Tcl_NewStringObj(nsName, -1));
+
+ if (strcmp(nsName, "::") != 0) {
+ Tcl_AppendToObj(lv[lc-1], "::", -1);
}
+ Tcl_AppendToObj(lv[lc-1], procName, -1);
+ } else if (procPtr->cmdPtr->clientData) {
+ ExtraFrameInfo *efiPtr = procPtr->cmdPtr->clientData;
+ int i;
- Tcl_SetObjResult(interp, Tcl_NewListObj (lc, lv));
- return TCL_OK;
+ /*
+ * This is a non-standard command. Luckily, it's told us how to
+ * render extra information about its frame.
+ */
+
+ for (i=0 ; i<efiPtr->length ; i++) {
+ lv[lc++] = Tcl_NewStringObj(efiPtr->fields[i].name, -1);
+ if (efiPtr->fields[i].proc) {
+ lv[lc++] =
+ efiPtr->fields[i].proc(efiPtr->fields[i].clientData);
+ } else {
+ lv[lc++] = efiPtr->fields[i].clientData;
+ }
+ }
}
}
- Tcl_WrongNumArgs(interp, 2, objv, "?number?");
+ /*
+ * 'level'. Common to all frame types. Conditional on having an associated
+ * _visible_ CallFrame.
+ */
- return TCL_ERROR;
-}
-#endif
-
-/*
- *----------------------------------------------------------------------
- *
- * InfoFunctionsCmd --
- *
- * Called to implement the "info functions" command that returns the
- * list of math functions matching an optional pattern. Handles the
- * following syntax:
- *
- * info functions ?pattern?
- *
- * Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
- *
- * Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message.
- *
- *----------------------------------------------------------------------
- */
+ if ((framePtr->framePtr != NULL) && (iPtr->varFramePtr != NULL)) {
+ CallFrame *current = framePtr->framePtr;
+ CallFrame *top = iPtr->varFramePtr;
+ CallFrame *idx;
-static int
-InfoFunctionsCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
-{
- char *pattern;
- Tcl_Obj *listPtr;
+ for (idx=top ; idx!=NULL ; idx=idx->callerVarPtr) {
+ if (idx == current) {
+ int c = framePtr->framePtr->level;
+ int t = iPtr->varFramePtr->level;
- if (objc == 2) {
- pattern = NULL;
- } else if (objc == 3) {
- pattern = Tcl_GetString(objv[2]);
- } else {
- Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");
- return TCL_ERROR;
+ ADD_PAIR("level", Tcl_NewIntObj(t - c));
+ break;
+ }
+ }
}
- listPtr = Tcl_ListMathFuncs(interp, pattern);
- if (listPtr == NULL) {
- return TCL_ERROR;
- }
- Tcl_SetObjResult(interp, listPtr);
- return TCL_OK;
+ return Tcl_NewListObj(lc, lv);
}
/*
*----------------------------------------------------------------------
*
- * InfoGlobalsCmd --
+ * InfoFunctionsCmd --
*
- * Called to implement the "info globals" command that returns the list
- * of global variables matching an optional pattern. Handles the
- * following syntax:
+ * Called to implement the "info functions" command that returns the list
+ * of math functions matching an optional pattern. Handles the following
+ * syntax:
*
- * info globals ?pattern?
+ * info functions ?pattern?
*
* Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ * Returns TCL_OK if successful and TCL_ERROR if there is an error.
*
* Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message.
+ * Returns a result in the interpreter's result object. If there is an
+ * error, the result is an error message.
*
*----------------------------------------------------------------------
*/
static int
-InfoGlobalsCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+InfoFunctionsCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- char *varName, *pattern;
- Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp);
- register Tcl_HashEntry *entryPtr;
- Tcl_HashSearch search;
- Var *varPtr;
- Tcl_Obj *listPtr;
+ char *pattern;
- if (objc == 2) {
- pattern = NULL;
- } else if (objc == 3) {
- pattern = Tcl_GetString(objv[2]);
- /*
- * Strip leading global-namespace qualifiers. [Bug 1057461]
- */
- if (pattern[0] == ':' && pattern[1] == ':') {
- while (*pattern == ':') {
- pattern++;
- }
- }
+ if (objc == 1) {
+ pattern = NULL;
+ } else if (objc == 2) {
+ pattern = TclGetString(objv[1]);
} else {
- Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");
- return TCL_ERROR;
+ Tcl_WrongNumArgs(interp, 1, objv, "?pattern?");
+ return TCL_ERROR;
}
- /*
- * Scan through the global :: namespace's variable table and create a
- * list of all global variables that match the pattern.
- */
-
- listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
- if (pattern != NULL && TclMatchIsTrivial(pattern)) {
- entryPtr = Tcl_FindHashEntry(&globalNsPtr->varTable, pattern);
- if (entryPtr != NULL) {
- varPtr = (Var *) Tcl_GetHashValue(entryPtr);
- if (!TclIsVarUndefined(varPtr)) {
- Tcl_ListObjAppendElement(interp, listPtr,
- Tcl_NewStringObj(pattern, -1));
- }
- }
- } else {
- for (entryPtr = Tcl_FirstHashEntry(&globalNsPtr->varTable, &search);
- entryPtr != NULL;
- entryPtr = Tcl_NextHashEntry(&search)) {
- varPtr = (Var *) Tcl_GetHashValue(entryPtr);
- if (TclIsVarUndefined(varPtr)) {
- continue;
- }
- varName = Tcl_GetHashKey(&globalNsPtr->varTable, entryPtr);
- if ((pattern == NULL) || Tcl_StringMatch(varName, pattern)) {
- Tcl_ListObjAppendElement(interp, listPtr,
- Tcl_NewStringObj(varName, -1));
- }
- }
- }
- Tcl_SetObjResult(interp, listPtr);
+ Tcl_SetObjResult(interp, Tcl_ListMathFuncs(interp, pattern));
return TCL_OK;
}
@@ -1423,43 +1358,42 @@ InfoGlobalsCmd(dummy, interp, objc, objv)
*
* InfoHostnameCmd --
*
- * Called to implement the "info hostname" command that returns the
- * host name. Handles the following syntax:
+ * Called to implement the "info hostname" command that returns the host
+ * name. Handles the following syntax:
*
- * info hostname
+ * info hostname
*
* Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ * Returns TCL_OK if successful and TCL_ERROR if there is an error.
*
* Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message.
+ * Returns a result in the interpreter's result object. If there is an
+ * error, the result is an error message.
*
*----------------------------------------------------------------------
*/
static int
-InfoHostnameCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+InfoHostnameCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
CONST char *name;
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return TCL_ERROR;
+
+ if (objc != 1) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return TCL_ERROR;
}
name = Tcl_GetHostName();
if (name) {
- Tcl_SetStringObj(Tcl_GetObjResult(interp), name, -1);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(name, -1));
return TCL_OK;
- } else {
- Tcl_SetStringObj(Tcl_GetObjResult(interp),
- "unable to determine name of host", -1);
- return TCL_ERROR;
}
+ Tcl_SetResult(interp, "unable to determine name of host", TCL_STATIC);
+ return TCL_ERROR;
}
/*
@@ -1467,71 +1401,69 @@ InfoHostnameCmd(dummy, interp, objc, objv)
*
* InfoLevelCmd --
*
- * Called to implement the "info level" command that returns
- * information about the call stack. Handles the following syntax:
+ * Called to implement the "info level" command that returns information
+ * about the call stack. Handles the following syntax:
*
- * info level ?number?
+ * info level ?number?
*
* Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ * Returns TCL_OK if successful and TCL_ERROR if there is an error.
*
* Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message.
+ * Returns a result in the interpreter's result object. If there is an
+ * error, the result is an error message.
*
*----------------------------------------------------------------------
*/
static int
-InfoLevelCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+InfoLevelCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Interp *iPtr = (Interp *) interp;
- int level;
- CallFrame *framePtr;
- Tcl_Obj *listPtr;
- if (objc == 2) { /* just "info level" */
- if (iPtr->varFramePtr == NULL) {
- Tcl_SetIntObj(Tcl_GetObjResult(interp), 0);
- } else {
- Tcl_SetIntObj(Tcl_GetObjResult(interp), iPtr->varFramePtr->level);
- }
- return TCL_OK;
- } else if (objc == 3) {
- if (Tcl_GetIntFromObj(interp, objv[2], &level) != TCL_OK) {
- return TCL_ERROR;
- }
- if (level <= 0) {
- if (iPtr->varFramePtr == NULL) {
- levelError:
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "bad level \"",
- Tcl_GetString(objv[2]),
- "\"", (char *) NULL);
- return TCL_ERROR;
- }
- level += iPtr->varFramePtr->level;
- }
- for (framePtr = iPtr->varFramePtr; framePtr != NULL;
- framePtr = framePtr->callerVarPtr) {
- if (framePtr->level == level) {
- break;
- }
- }
- if (framePtr == NULL) {
- goto levelError;
- }
-
- listPtr = Tcl_NewListObj(framePtr->objc, framePtr->objv);
- Tcl_SetObjResult(interp, listPtr);
- return TCL_OK;
- }
-
- Tcl_WrongNumArgs(interp, 2, objv, "?number?");
+ if (objc == 1) { /* Just "info level" */
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(iPtr->varFramePtr->level));
+ return TCL_OK;
+ }
+
+ if (objc == 2) {
+ int level;
+ CallFrame *framePtr, *rootFramePtr = iPtr->rootFramePtr;
+
+ if (TclGetIntFromObj(interp, objv[1], &level) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (level <= 0) {
+ if (iPtr->varFramePtr == rootFramePtr) {
+ goto levelError;
+ }
+ level += iPtr->varFramePtr->level;
+ }
+ for (framePtr=iPtr->varFramePtr ; framePtr!=rootFramePtr;
+ framePtr=framePtr->callerVarPtr) {
+ if (framePtr->level == level) {
+ break;
+ }
+ }
+ if (framePtr == rootFramePtr) {
+ goto levelError;
+ }
+
+ Tcl_SetObjResult(interp,
+ Tcl_NewListObj(framePtr->objc, framePtr->objv));
+ return TCL_OK;
+ }
+
+ Tcl_WrongNumArgs(interp, 1, objv, "?number?");
+ return TCL_ERROR;
+
+ levelError:
+ Tcl_AppendResult(interp, "bad level \"", TclGetString(objv[1]), "\"",
+ NULL);
return TCL_ERROR;
}
@@ -1540,43 +1472,42 @@ InfoLevelCmd(dummy, interp, objc, objv)
*
* InfoLibraryCmd --
*
- * Called to implement the "info library" command that returns the
- * library directory for the Tcl installation. Handles the following
- * syntax:
+ * Called to implement the "info library" command that returns the
+ * library directory for the Tcl installation. Handles the following
+ * syntax:
*
- * info library
+ * info library
*
* Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ * Returns TCL_OK if successful and TCL_ERROR if there is an error.
*
* Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message.
+ * Returns a result in the interpreter's result object. If there is an
+ * error, the result is an error message.
*
*----------------------------------------------------------------------
*/
static int
-InfoLibraryCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+InfoLibraryCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
CONST char *libDirName;
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return TCL_ERROR;
+ if (objc != 1) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return TCL_ERROR;
}
libDirName = Tcl_GetVar(interp, "tcl_library", TCL_GLOBAL_ONLY);
if (libDirName != NULL) {
- Tcl_SetStringObj(Tcl_GetObjResult(interp), libDirName, -1);
- return TCL_OK;
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(libDirName, -1));
+ return TCL_OK;
}
- Tcl_SetStringObj(Tcl_GetObjResult(interp),
- "no library has been specified for Tcl", -1);
+ Tcl_SetResult(interp, "no library has been specified for Tcl",TCL_STATIC);
return TCL_ERROR;
}
@@ -1585,174 +1516,42 @@ InfoLibraryCmd(dummy, interp, objc, objv)
*
* InfoLoadedCmd --
*
- * Called to implement the "info loaded" command that returns the
- * packages that have been loaded into an interpreter. Handles the
- * following syntax:
+ * Called to implement the "info loaded" command that returns the
+ * packages that have been loaded into an interpreter. Handles the
+ * following syntax:
*
- * info loaded ?interp?
+ * info loaded ?interp?
*
* Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ * Returns TCL_OK if successful and TCL_ERROR if there is an error.
*
* Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message.
+ * Returns a result in the interpreter's result object. If there is an
+ * error, the result is an error message.
*
*----------------------------------------------------------------------
*/
static int
-InfoLoadedCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+InfoLoadedCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
char *interpName;
- int result;
- if ((objc != 2) && (objc != 3)) {
- Tcl_WrongNumArgs(interp, 2, objv, "?interp?");
- return TCL_ERROR;
+ if ((objc != 1) && (objc != 2)) {
+ Tcl_WrongNumArgs(interp, 1, objv, "?interp?");
+ return TCL_ERROR;
}
- if (objc == 2) { /* get loaded pkgs in all interpreters */
+ if (objc == 1) { /* Get loaded pkgs in all interpreters. */
interpName = NULL;
- } else { /* get pkgs just in specified interp */
- interpName = Tcl_GetString(objv[2]);
- }
- result = TclGetLoadedPackages(interp, interpName);
- return result;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * InfoLocalsCmd --
- *
- * Called to implement the "info locals" command to return a list of
- * local variables that match an optional pattern. Handles the
- * following syntax:
- *
- * info locals ?pattern?
- *
- * Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
- *
- * Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-InfoLocalsCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
-{
- Interp *iPtr = (Interp *) interp;
- char *pattern;
- Tcl_Obj *listPtr;
-
- if (objc == 2) {
- pattern = NULL;
- } else if (objc == 3) {
- pattern = Tcl_GetString(objv[2]);
- } else {
- Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");
- return TCL_ERROR;
- }
-
- if (iPtr->varFramePtr == NULL || !iPtr->varFramePtr->isProcCallFrame) {
- return TCL_OK;
- }
-
- /*
- * Return a list containing names of first the compiled locals (i.e. the
- * ones stored in the call frame), then the variables in the local hash
- * table (if one exists).
- */
-
- listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
- AppendLocals(interp, listPtr, pattern, 0);
- Tcl_SetObjResult(interp, listPtr);
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * AppendLocals --
- *
- * Append the local variables for the current frame to the
- * specified list object.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-AppendLocals(interp, listPtr, pattern, includeLinks)
- Tcl_Interp *interp; /* Current interpreter. */
- Tcl_Obj *listPtr; /* List object to append names to. */
- CONST char *pattern; /* Pattern to match against. */
- int includeLinks; /* 1 if upvars should be included, else 0. */
-{
- Interp *iPtr = (Interp *) interp;
- CompiledLocal *localPtr;
- Var *varPtr;
- int i, localVarCt;
- char *varName;
- Tcl_HashTable *localVarTablePtr;
- register Tcl_HashEntry *entryPtr;
- Tcl_HashSearch search;
-
- localPtr = iPtr->varFramePtr->procPtr->firstLocalPtr;
- localVarCt = iPtr->varFramePtr->numCompiledLocals;
- varPtr = iPtr->varFramePtr->compiledLocals;
- localVarTablePtr = iPtr->varFramePtr->varTablePtr;
-
- for (i = 0; i < localVarCt; i++) {
- /*
- * Skip nameless (temporary) variables and undefined variables
- */
-
- if (!TclIsVarTemporary(localPtr) && !TclIsVarUndefined(varPtr)
- && (includeLinks || !TclIsVarLink(varPtr))) {
- varName = varPtr->name;
- if ((pattern == NULL) || Tcl_StringMatch(varName, pattern)) {
- Tcl_ListObjAppendElement(interp, listPtr,
- Tcl_NewStringObj(varName, -1));
- }
- }
- varPtr++;
- localPtr = localPtr->nextPtr;
- }
-
- if (localVarTablePtr != NULL) {
- for (entryPtr = Tcl_FirstHashEntry(localVarTablePtr, &search);
- entryPtr != NULL;
- entryPtr = Tcl_NextHashEntry(&search)) {
- varPtr = (Var *) Tcl_GetHashValue(entryPtr);
- if (!TclIsVarUndefined(varPtr)
- && (includeLinks || !TclIsVarLink(varPtr))) {
- varName = Tcl_GetHashKey(localVarTablePtr, entryPtr);
- if ((pattern == NULL)
- || Tcl_StringMatch(varName, pattern)) {
- Tcl_ListObjAppendElement(interp, listPtr,
- Tcl_NewStringObj(varName, -1));
- }
- }
- }
+ } else { /* Get pkgs just in specified interp. */
+ interpName = TclGetString(objv[1]);
}
+ return TclGetLoadedPackages(interp, interpName);
}
/*
@@ -1760,41 +1559,34 @@ AppendLocals(interp, listPtr, pattern, includeLinks)
*
* InfoNameOfExecutableCmd --
*
- * Called to implement the "info nameofexecutable" command that returns
- * the name of the binary file running this application. Handles the
- * following syntax:
+ * Called to implement the "info nameofexecutable" command that returns
+ * the name of the binary file running this application. Handles the
+ * following syntax:
*
- * info nameofexecutable
+ * info nameofexecutable
*
* Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ * Returns TCL_OK if successful and TCL_ERROR if there is an error.
*
* Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message.
+ * Returns a result in the interpreter's result object. If there is an
+ * error, the result is an error message.
*
*----------------------------------------------------------------------
*/
static int
-InfoNameOfExecutableCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+InfoNameOfExecutableCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- CONST char *nameOfExecutable;
-
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return TCL_ERROR;
- }
-
- nameOfExecutable = Tcl_GetNameOfExecutable();
-
- if (nameOfExecutable != NULL) {
- Tcl_SetStringObj(Tcl_GetObjResult(interp), nameOfExecutable, -1);
+ if (objc != 1) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return TCL_ERROR;
}
+ Tcl_SetObjResult(interp, TclGetObjNameOfExecutable());
return TCL_OK;
}
@@ -1803,41 +1595,41 @@ InfoNameOfExecutableCmd(dummy, interp, objc, objv)
*
* InfoPatchLevelCmd --
*
- * Called to implement the "info patchlevel" command that returns the
- * default value for an argument to a procedure. Handles the following
- * syntax:
+ * Called to implement the "info patchlevel" command that returns the
+ * default value for an argument to a procedure. Handles the following
+ * syntax:
*
- * info patchlevel
+ * info patchlevel
*
* Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ * Returns TCL_OK if successful and TCL_ERROR if there is an error.
*
* Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message.
+ * Returns a result in the interpreter's result object. If there is an
+ * error, the result is an error message.
*
*----------------------------------------------------------------------
*/
static int
-InfoPatchLevelCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+InfoPatchLevelCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
CONST char *patchlevel;
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return TCL_ERROR;
+ if (objc != 1) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return TCL_ERROR;
}
patchlevel = Tcl_GetVar(interp, "tcl_patchLevel",
- (TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG));
+ (TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG));
if (patchlevel != NULL) {
- Tcl_SetStringObj(Tcl_GetObjResult(interp), patchlevel, -1);
- return TCL_OK;
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(patchlevel, -1));
+ return TCL_OK;
}
return TCL_ERROR;
}
@@ -1847,31 +1639,31 @@ InfoPatchLevelCmd(dummy, interp, objc, objv)
*
* InfoProcsCmd --
*
- * Called to implement the "info procs" command that returns the
- * list of procedures in the interpreter that match an optional pattern.
- * The pattern, if any, consists of an optional sequence of namespace
- * names separated by "::" qualifiers, which is followed by a
- * glob-style pattern that restricts which commands are returned.
- * Handles the following syntax:
+ * Called to implement the "info procs" command that returns the list of
+ * procedures in the interpreter that match an optional pattern. The
+ * pattern, if any, consists of an optional sequence of namespace names
+ * separated by "::" qualifiers, which is followed by a glob-style
+ * pattern that restricts which commands are returned. Handles the
+ * following syntax:
*
- * info procs ?pattern?
+ * info procs ?pattern?
*
* Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ * Returns TCL_OK if successful and TCL_ERROR if there is an error.
*
* Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message.
+ * Returns a result in the interpreter's result object. If there is an
+ * error, the result is an error message.
*
*----------------------------------------------------------------------
*/
static int
-InfoProcsCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+InfoProcsCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
char *cmdName, *pattern;
CONST char *simplePattern;
@@ -1879,44 +1671,44 @@ InfoProcsCmd(dummy, interp, objc, objv)
#ifdef INFO_PROCS_SEARCH_GLOBAL_NS
Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp);
#endif
- Namespace *currNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
+ Namespace *currNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
Tcl_Obj *listPtr, *elemObjPtr;
- int specificNsInPattern = 0; /* Init. to avoid compiler warning. */
+ int specificNsInPattern = 0;/* Init. to avoid compiler warning. */
register Tcl_HashEntry *entryPtr;
Tcl_HashSearch search;
Command *cmdPtr, *realCmdPtr;
/*
- * Get the pattern and find the "effective namespace" in which to
- * list procs.
+ * Get the pattern and find the "effective namespace" in which to list
+ * procs.
*/
- if (objc == 2) {
+ if (objc == 1) {
simplePattern = NULL;
nsPtr = currNsPtr;
specificNsInPattern = 0;
- } else if (objc == 3) {
+ } else if (objc == 2) {
/*
* From the pattern, get the effective namespace and the simple
- * pattern (no namespace qualifiers or ::'s) at the end. If an
- * error was found while parsing the pattern, return it. Otherwise,
- * if the namespace wasn't found, just leave nsPtr NULL: we will
- * return an empty list since no commands there can be found.
+ * pattern (no namespace qualifiers or ::'s) at the end. If an error
+ * was found while parsing the pattern, return it. Otherwise, if the
+ * namespace wasn't found, just leave nsPtr NULL: we will return an
+ * empty list since no commands there can be found.
*/
Namespace *dummy1NsPtr, *dummy2NsPtr;
- pattern = Tcl_GetString(objv[2]);
+ pattern = TclGetString(objv[1]);
TclGetNamespaceForQualName(interp, pattern, (Namespace *) NULL,
/*flags*/ 0, &nsPtr, &dummy1NsPtr, &dummy2NsPtr,
&simplePattern);
- if (nsPtr != NULL) { /* we successfully found the pattern's ns */
+ if (nsPtr != NULL) { /* We successfully found the pattern's ns. */
specificNsInPattern = (strcmp(simplePattern, pattern) != 0);
}
} else {
- Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");
- return TCL_ERROR;
+ Tcl_WrongNumArgs(interp, 1, objv, "?pattern?");
+ return TCL_ERROR;
}
if (nsPtr == NULL) {
@@ -1924,13 +1716,13 @@ InfoProcsCmd(dummy, interp, objc, objv)
}
/*
- * Scan through the effective namespace's command table and create a
- * list with all procs that match the pattern. If a specific
- * namespace was requested in the pattern, qualify the command names
- * with the namespace name.
+ * Scan through the effective namespace's command table and create a list
+ * with all procs that match the pattern. If a specific namespace was
+ * requested in the pattern, qualify the command names with the namespace
+ * name.
*/
- listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
+ listPtr = Tcl_NewListObj(0, NULL);
#ifndef INFO_PROCS_SEARCH_GLOBAL_NS
if (simplePattern != NULL && TclMatchIsTrivial(simplePattern)) {
entryPtr = Tcl_FindHashEntry(&nsPtr->cmdTable, simplePattern);
@@ -1944,7 +1736,7 @@ InfoProcsCmd(dummy, interp, objc, objv)
goto simpleProcOK;
}
} else {
- simpleProcOK:
+ simpleProcOK:
if (specificNsInPattern) {
elemObjPtr = Tcl_NewObj();
Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr,
@@ -1962,7 +1754,7 @@ InfoProcsCmd(dummy, interp, objc, objv)
while (entryPtr != NULL) {
cmdName = Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr);
if ((simplePattern == NULL)
- || Tcl_StringMatch(cmdName, simplePattern)) {
+ || Tcl_StringMatch(cmdName, simplePattern)) {
cmdPtr = (Command *) Tcl_GetHashValue(entryPtr);
if (!TclIsProc(cmdPtr)) {
@@ -1972,7 +1764,7 @@ InfoProcsCmd(dummy, interp, objc, objv)
goto procOK;
}
} else {
- procOK:
+ procOK:
if (specificNsInPattern) {
elemObjPtr = Tcl_NewObj();
Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr,
@@ -1988,35 +1780,36 @@ InfoProcsCmd(dummy, interp, objc, objv)
/*
* If the effective namespace isn't the global :: namespace, and a
- * specific namespace wasn't requested in the pattern, then add in
- * all global :: procs that match the simple pattern. Of course,
- * we add in only those procs that aren't hidden by a proc in
- * the effective namespace.
+ * specific namespace wasn't requested in the pattern, then add in all
+ * global :: procs that match the simple pattern. Of course, we add in
+ * only those procs that aren't hidden by a proc in the effective
+ * namespace.
*/
#ifdef INFO_PROCS_SEARCH_GLOBAL_NS
/*
- * If "info procs" worked like "info commands", returning the
- * commands also seen in the global namespace, then you would
- * include this code. As this could break backwards compatibilty
- * with 8.0-8.2, we decided not to "fix" it in 8.3, leaving the
- * behavior slightly different.
+ * If "info procs" worked like "info commands", returning the commands
+ * also seen in the global namespace, then you would include this
+ * code. As this could break backwards compatibilty with 8.0-8.2, we
+ * decided not to "fix" it in 8.3, leaving the behavior slightly
+ * different.
*/
+
if ((nsPtr != globalNsPtr) && !specificNsInPattern) {
entryPtr = Tcl_FirstHashEntry(&globalNsPtr->cmdTable, &search);
while (entryPtr != NULL) {
cmdName = Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr);
if ((simplePattern == NULL)
- || Tcl_StringMatch(cmdName, simplePattern)) {
- if (Tcl_FindHashEntry(&nsPtr->cmdTable, cmdName) == NULL) {
+ || Tcl_StringMatch(cmdName, simplePattern)) {
+ if (Tcl_FindHashEntry(&nsPtr->cmdTable,cmdName) == NULL) {
cmdPtr = (Command *) Tcl_GetHashValue(entryPtr);
realCmdPtr = (Command *) TclGetOriginalCommand(
- (Tcl_Command) cmdPtr);
+ (Tcl_Command) cmdPtr);
if (TclIsProc(cmdPtr) || ((realCmdPtr != NULL)
&& TclIsProc(realCmdPtr))) {
Tcl_ListObjAppendElement(interp, listPtr,
- Tcl_NewStringObj(cmdName, -1));
+ Tcl_NewStringObj(cmdName, -1));
}
}
}
@@ -2035,47 +1828,46 @@ InfoProcsCmd(dummy, interp, objc, objv)
*
* InfoScriptCmd --
*
- * Called to implement the "info script" command that returns the
- * script file that is currently being evaluated. Handles the
- * following syntax:
+ * Called to implement the "info script" command that returns the script
+ * file that is currently being evaluated. Handles the following syntax:
*
- * info script ?newName?
+ * info script ?newName?
*
* If newName is specified, it will set that as the internal name.
*
* Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ * Returns TCL_OK if successful and TCL_ERROR if there is an error.
*
* Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message. It may change the
- * internal script filename.
+ * Returns a result in the interpreter's result object. If there is an
+ * error, the result is an error message. It may change the internal
+ * script filename.
*
*----------------------------------------------------------------------
*/
static int
-InfoScriptCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+InfoScriptCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Interp *iPtr = (Interp *) interp;
- if ((objc != 2) && (objc != 3)) {
- Tcl_WrongNumArgs(interp, 2, objv, "?filename?");
- return TCL_ERROR;
+ if ((objc != 1) && (objc != 2)) {
+ Tcl_WrongNumArgs(interp, 1, objv, "?filename?");
+ return TCL_ERROR;
}
- if (objc == 3) {
+ if (objc == 2) {
if (iPtr->scriptFile != NULL) {
Tcl_DecrRefCount(iPtr->scriptFile);
}
- iPtr->scriptFile = objv[2];
+ iPtr->scriptFile = objv[1];
Tcl_IncrRefCount(iPtr->scriptFile);
}
if (iPtr->scriptFile != NULL) {
- Tcl_SetObjResult(interp, iPtr->scriptFile);
+ Tcl_SetObjResult(interp, iPtr->scriptFile);
}
return TCL_OK;
}
@@ -2085,36 +1877,36 @@ InfoScriptCmd(dummy, interp, objc, objv)
*
* InfoSharedlibCmd --
*
- * Called to implement the "info sharedlibextension" command that
- * returns the file extension used for shared libraries. Handles the
- * following syntax:
+ * Called to implement the "info sharedlibextension" command that returns
+ * the file extension used for shared libraries. Handles the following
+ * syntax:
*
- * info sharedlibextension
+ * info sharedlibextension
*
* Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ * Returns TCL_OK if successful and TCL_ERROR if there is an error.
*
* Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message.
+ * Returns a result in the interpreter's result object. If there is an
+ * error, the result is an error message.
*
*----------------------------------------------------------------------
*/
static int
-InfoSharedlibCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+InfoSharedlibCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return TCL_ERROR;
+ if (objc != 1) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return TCL_ERROR;
}
-
+
#ifdef TCL_SHLIB_EXT
- Tcl_SetStringObj(Tcl_GetObjResult(interp), TCL_SHLIB_EXT, -1);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(TCL_SHLIB_EXT, -1));
#endif
return TCL_OK;
}
@@ -2124,40 +1916,40 @@ InfoSharedlibCmd(dummy, interp, objc, objv)
*
* InfoTclVersionCmd --
*
- * Called to implement the "info tclversion" command that returns the
- * version number for this Tcl library. Handles the following syntax:
+ * Called to implement the "info tclversion" command that returns the
+ * version number for this Tcl library. Handles the following syntax:
*
- * info tclversion
+ * info tclversion
*
* Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ * Returns TCL_OK if successful and TCL_ERROR if there is an error.
*
* Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message.
+ * Returns a result in the interpreter's result object. If there is an
+ * error, the result is an error message.
*
*----------------------------------------------------------------------
*/
static int
-InfoTclVersionCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+InfoTclVersionCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- CONST char *version;
+ Tcl_Obj *version;
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 2, objv, NULL);
- return TCL_ERROR;
+ if (objc != 1) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return TCL_ERROR;
}
- version = Tcl_GetVar(interp, "tcl_version",
- (TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG));
+ version = Tcl_GetVar2Ex(interp, "tcl_version", NULL,
+ (TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG));
if (version != NULL) {
- Tcl_SetStringObj(Tcl_GetObjResult(interp), version, -1);
- return TCL_OK;
+ Tcl_SetObjResult(interp, version);
+ return TCL_OK;
}
return TCL_ERROR;
}
@@ -2165,204 +1957,67 @@ InfoTclVersionCmd(dummy, interp, objc, objv)
/*
*----------------------------------------------------------------------
*
- * InfoVarsCmd --
- *
- * Called to implement the "info vars" command that returns the
- * list of variables in the interpreter that match an optional pattern.
- * The pattern, if any, consists of an optional sequence of namespace
- * names separated by "::" qualifiers, which is followed by a
- * glob-style pattern that restricts which variables are returned.
- * Handles the following syntax:
+ * Tcl_JoinObjCmd --
*
- * info vars ?pattern?
+ * This procedure is invoked to process the "join" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ * A standard Tcl object result.
*
* Side effects:
- * Returns a result in the interpreter's result object. If there is
- * an error, the result is an error message.
+ * See the user documentation.
*
*----------------------------------------------------------------------
*/
-static int
-InfoVarsCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+int
+Tcl_JoinObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* The argument objects. */
{
- Interp *iPtr = (Interp *) interp;
- char *varName, *pattern;
- CONST char *simplePattern;
- register Tcl_HashEntry *entryPtr;
- Tcl_HashSearch search;
- Var *varPtr;
- Namespace *nsPtr;
- Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp);
- Namespace *currNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
- Tcl_Obj *listPtr, *elemObjPtr;
- int specificNsInPattern = 0; /* Init. to avoid compiler warning. */
-
- /*
- * Get the pattern and find the "effective namespace" in which to
- * list variables. We only use this effective namespace if there's
- * no active Tcl procedure frame.
- */
-
- if (objc == 2) {
- simplePattern = NULL;
- nsPtr = currNsPtr;
- specificNsInPattern = 0;
- } else if (objc == 3) {
- /*
- * From the pattern, get the effective namespace and the simple
- * pattern (no namespace qualifiers or ::'s) at the end. If an
- * error was found while parsing the pattern, return it. Otherwise,
- * if the namespace wasn't found, just leave nsPtr NULL: we will
- * return an empty list since no variables there can be found.
- */
+ int listLen, i;
+ Tcl_Obj *resObjPtr, *joinObjPtr, **elemPtrs;
- Namespace *dummy1NsPtr, *dummy2NsPtr;
-
- pattern = Tcl_GetString(objv[2]);
- TclGetNamespaceForQualName(interp, pattern, (Namespace *) NULL,
- /*flags*/ 0, &nsPtr, &dummy1NsPtr, &dummy2NsPtr,
- &simplePattern);
-
- if (nsPtr != NULL) { /* we successfully found the pattern's ns */
- specificNsInPattern = (strcmp(simplePattern, pattern) != 0);
- }
- } else {
- Tcl_WrongNumArgs(interp, 2, objv, "?pattern?");
- return TCL_ERROR;
+ if ((objc < 2) || (objc > 3)) {
+ Tcl_WrongNumArgs(interp, 1, objv, "list ?joinString?");
+ return TCL_ERROR;
}
/*
- * If the namespace specified in the pattern wasn't found, just return.
+ * Make sure the list argument is a list object and get its length and a
+ * pointer to its array of element pointers.
*/
- if (nsPtr == NULL) {
- return TCL_OK;
+ if (TclListObjGetElements(interp, objv[1], &listLen,
+ &elemPtrs) != TCL_OK) {
+ return TCL_ERROR;
}
-
- listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
-
- if ((iPtr->varFramePtr == NULL)
- || !iPtr->varFramePtr->isProcCallFrame
- || specificNsInPattern) {
- /*
- * There is no frame pointer, the frame pointer was pushed only
- * to activate a namespace, or we are in a procedure call frame
- * but a specific namespace was specified. Create a list containing
- * only the variables in the effective namespace's variable table.
- */
-
- if (simplePattern != NULL && TclMatchIsTrivial(simplePattern)) {
- /*
- * If we can just do hash lookups, that simplifies things
- * a lot.
- */
- entryPtr = Tcl_FindHashEntry(&nsPtr->varTable, simplePattern);
- if (entryPtr != NULL) {
- varPtr = (Var *) Tcl_GetHashValue(entryPtr);
- if (!TclIsVarUndefined(varPtr)
- || (varPtr->flags & VAR_NAMESPACE_VAR)) {
- if (specificNsInPattern) {
- elemObjPtr = Tcl_NewObj();
- Tcl_GetVariableFullName(interp, (Tcl_Var) varPtr,
- elemObjPtr);
- } else {
- elemObjPtr = Tcl_NewStringObj(simplePattern, -1);
- }
- Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr);
- }
- } else if ((nsPtr != globalNsPtr) && !specificNsInPattern) {
- entryPtr = Tcl_FindHashEntry(&globalNsPtr->varTable,
- simplePattern);
- if (entryPtr != NULL) {
- varPtr = (Var *) Tcl_GetHashValue(entryPtr);
- if (!TclIsVarUndefined(varPtr)
- || (varPtr->flags & VAR_NAMESPACE_VAR)) {
- Tcl_ListObjAppendElement(interp, listPtr,
- Tcl_NewStringObj(simplePattern, -1));
- }
- }
- }
- } else {
- /*
- * Have to scan the tables of variables.
- */
+ joinObjPtr = (objc == 2) ? Tcl_NewStringObj(" ", 1) : objv[2];
+ Tcl_IncrRefCount(joinObjPtr);
- entryPtr = Tcl_FirstHashEntry(&nsPtr->varTable, &search);
- while (entryPtr != NULL) {
- varPtr = (Var *) Tcl_GetHashValue(entryPtr);
- if (!TclIsVarUndefined(varPtr)
- || (varPtr->flags & VAR_NAMESPACE_VAR)) {
- varName = Tcl_GetHashKey(&nsPtr->varTable, entryPtr);
- if ((simplePattern == NULL)
- || Tcl_StringMatch(varName, simplePattern)) {
- if (specificNsInPattern) {
- elemObjPtr = Tcl_NewObj();
- Tcl_GetVariableFullName(interp, (Tcl_Var) varPtr,
- elemObjPtr);
- } else {
- elemObjPtr = Tcl_NewStringObj(varName, -1);
- }
- Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr);
- }
- }
- entryPtr = Tcl_NextHashEntry(&search);
- }
-
- /*
- * If the effective namespace isn't the global ::
- * namespace, and a specific namespace wasn't requested in
- * the pattern (i.e., the pattern only specifies variable
- * names), then add in all global :: variables that match
- * the simple pattern. Of course, add in only those
- * variables that aren't hidden by a variable in the
- * effective namespace.
- */
-
- if ((nsPtr != globalNsPtr) && !specificNsInPattern) {
- entryPtr = Tcl_FirstHashEntry(&globalNsPtr->varTable, &search);
- while (entryPtr != NULL) {
- varPtr = (Var *) Tcl_GetHashValue(entryPtr);
- if (!TclIsVarUndefined(varPtr)
- || (varPtr->flags & VAR_NAMESPACE_VAR)) {
- varName = Tcl_GetHashKey(&globalNsPtr->varTable,
- entryPtr);
- if ((simplePattern == NULL)
- || Tcl_StringMatch(varName, simplePattern)) {
- if (Tcl_FindHashEntry(&nsPtr->varTable,
- varName) == NULL) {
- Tcl_ListObjAppendElement(interp, listPtr,
- Tcl_NewStringObj(varName, -1));
- }
- }
- }
- entryPtr = Tcl_NextHashEntry(&search);
- }
- }
+ resObjPtr = Tcl_NewObj();
+ for (i = 0; i < listLen; i++) {
+ if (i > 0) {
+ Tcl_AppendObjToObj(resObjPtr, joinObjPtr);
}
- } else if (((Interp *)interp)->varFramePtr->procPtr != NULL) {
- AppendLocals(interp, listPtr, simplePattern, 1);
+ Tcl_AppendObjToObj(resObjPtr, elemPtrs[i]);
}
-
- Tcl_SetObjResult(interp, listPtr);
+ Tcl_DecrRefCount(joinObjPtr);
+ Tcl_SetObjResult(interp, resObjPtr);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
- * Tcl_JoinObjCmd --
+ * Tcl_LassignObjCmd --
*
- * This procedure is invoked to process the "join" Tcl command.
- * See the user documentation for details on what it does.
+ * This object-based procedure is invoked to process the "lassign" Tcl
+ * command. See the user documentation for details on what it does.
*
* Results:
* A standard Tcl object result.
@@ -2373,54 +2028,59 @@ InfoVarsCmd(dummy, interp, objc, objv)
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
int
-Tcl_JoinObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* The argument objects. */
+Tcl_LassignObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- char *joinString, *bytes;
- int joinLength, listLen, length, i, result;
- Tcl_Obj **elemPtrs;
- Tcl_Obj *resObjPtr;
+ Tcl_Obj *listCopyPtr;
+ Tcl_Obj **listObjv; /* The contents of the list. */
+ int listObjc; /* The length of the list. */
+ int code = TCL_OK;
- if (objc == 2) {
- joinString = " ";
- joinLength = 1;
- } else if (objc == 3) {
- joinString = Tcl_GetStringFromObj(objv[2], &joinLength);
- } else {
- Tcl_WrongNumArgs(interp, 1, objv, "list ?joinString?");
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "list varName ?varName ...?");
return TCL_ERROR;
}
- /*
- * Make sure the list argument is a list object and get its length and
- * a pointer to its array of element pointers.
- */
-
- result = Tcl_ListObjGetElements(interp, objv[1], &listLen, &elemPtrs);
- if (result != TCL_OK) {
- return result;
+ listCopyPtr = TclListObjCopy(interp, objv[1]);
+ if (listCopyPtr == NULL) {
+ return TCL_ERROR;
}
- /*
- * Now concatenate strings to form the "joined" result. We append
- * directly into the interpreter's result object.
- */
+ TclListObjGetElements(NULL, listCopyPtr, &listObjc, &listObjv);
- resObjPtr = Tcl_GetObjResult(interp);
+ objc -= 2;
+ objv += 2;
+ while (code == TCL_OK && objc > 0 && listObjc > 0) {
+ if (NULL == Tcl_ObjSetVar2(interp, *objv++, NULL,
+ *listObjv++, TCL_LEAVE_ERR_MSG)) {
+ code = TCL_ERROR;
+ }
+ objc--; listObjc--;
+ }
- for (i = 0; i < listLen; i++) {
- bytes = Tcl_GetStringFromObj(elemPtrs[i], &length);
- if (i > 0) {
- Tcl_AppendToObj(resObjPtr, joinString, joinLength);
+ if (code == TCL_OK && objc > 0) {
+ Tcl_Obj *emptyObj;
+ TclNewObj(emptyObj);
+ Tcl_IncrRefCount(emptyObj);
+ while (code == TCL_OK && objc-- > 0) {
+ if (NULL == Tcl_ObjSetVar2(interp, *objv++, NULL,
+ emptyObj, TCL_LEAVE_ERR_MSG)) {
+ code = TCL_ERROR;
+ }
}
- Tcl_AppendToObj(resObjPtr, bytes, length);
+ Tcl_DecrRefCount(emptyObj);
}
- return TCL_OK;
+
+ if (code == TCL_OK && listObjc > 0) {
+ Tcl_SetObjResult(interp, Tcl_NewListObj(listObjc, listObjv));
+ }
+
+ Tcl_DecrRefCount(listCopyPtr);
+ return code;
}
/*
@@ -2440,16 +2100,15 @@ Tcl_JoinObjCmd(dummy, interp, objc, objv)
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
int
-Tcl_LindexObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_LindexObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- Tcl_Obj *elemPtr; /* Pointer to the element being extracted */
+ Tcl_Obj *elemPtr; /* Pointer to the element being extracted. */
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "list ?index...?");
@@ -2457,31 +2116,27 @@ Tcl_LindexObjCmd(dummy, interp, objc, objv)
}
/*
- * If objc == 3, then objv[ 2 ] may be either a single index or
- * a list of indices: go to TclLindexList to determine which.
- * If objc >= 4, or objc == 2, then objv[ 2 .. objc-2 ] are all
- * single indices and processed as such in TclLindexFlat.
+ * If objc==3, then objv[2] may be either a single index or a list of
+ * indices: go to TclLindexList to determine which. If objc>=4, or
+ * objc==2, then objv[2 .. objc-2] are all single indices and processed as
+ * such in TclLindexFlat.
*/
- if ( objc == 3 ) {
-
- elemPtr = TclLindexList( interp, objv[ 1 ], objv[ 2 ] );
-
+ if (objc == 3) {
+ elemPtr = TclLindexList(interp, objv[1], objv[2]);
} else {
-
- elemPtr = TclLindexFlat( interp, objv[ 1 ], objc-2, objv+2 );
-
+ elemPtr = TclLindexFlat(interp, objv[1], objc-2, objv+2);
}
-
+
/*
- * Set the interpreter's object result to the last element extracted
+ * Set the interpreter's object result to the last element extracted.
*/
- if ( elemPtr == NULL ) {
+ if (elemPtr == NULL) {
return TCL_ERROR;
} else {
Tcl_SetObjResult(interp, elemPtr);
- Tcl_DecrRefCount( elemPtr );
+ Tcl_DecrRefCount(elemPtr);
return TCL_OK;
}
}
@@ -2489,306 +2144,14 @@ Tcl_LindexObjCmd(dummy, interp, objc, objv)
/*
*----------------------------------------------------------------------
*
- * TclLindexList --
- *
- * This procedure handles the 'lindex' command when objc==3.
- *
- * Results:
- * Returns a pointer to the object extracted, or NULL if an
- * error occurred.
- *
- * Side effects:
- * None.
- *
- * If objv[1] can be parsed as a list, TclLindexList handles extraction
- * of the desired element locally. Otherwise, it invokes
- * TclLindexFlat to treat objv[1] as a scalar.
- *
- * The reference count of the returned object includes one reference
- * corresponding to the pointer returned. Thus, the calling code will
- * usually do something like:
- * Tcl_SetObjResult( interp, result );
- * Tcl_DecrRefCount( result );
- *
- *----------------------------------------------------------------------
- */
-
-Tcl_Obj *
-TclLindexList( interp, listPtr, argPtr )
- Tcl_Interp* interp; /* Tcl interpreter */
- Tcl_Obj* listPtr; /* List being unpacked */
- Tcl_Obj* argPtr; /* Index or index list */
-{
-
- Tcl_Obj **elemPtrs; /* Elements of the list being manipulated. */
- int listLen; /* Length of the list being manipulated. */
- int index; /* Index into the list */
- int result; /* Result returned from a Tcl library call */
- int i; /* Current index number */
- Tcl_Obj** indices; /* Array of list indices */
- int indexCount; /* Size of the array of list indices */
- Tcl_Obj* oldListPtr; /* Temp location to preserve the list
- * pointer when replacing it with a sublist */
-
- /*
- * Determine whether argPtr designates a list or a single index.
- * We have to be careful about the order of the checks to avoid
- * repeated shimmering; see TIP#22 and TIP#33 for the details.
- */
-
- if ( argPtr->typePtr != &tclListType
- && TclGetIntForIndex( NULL , argPtr, 0, &index ) == TCL_OK ) {
-
- /*
- * argPtr designates a single index.
- */
-
- return TclLindexFlat( interp, listPtr, 1, &argPtr );
-
- } else if ( Tcl_ListObjGetElements( NULL, argPtr, &indexCount, &indices )
- != TCL_OK ) {
-
- /*
- * argPtr designates something that is neither an index nor a
- * well-formed list. Report the error via TclLindexFlat.
- */
-
- return TclLindexFlat( interp, listPtr, 1, &argPtr );
- }
-
- /*
- * Record the reference to the list that we are maintaining in
- * the activation record.
- */
-
- Tcl_IncrRefCount( listPtr );
-
- /*
- * argPtr designates a list, and the 'else if' above has parsed it
- * into indexCount and indices.
- */
-
- for ( i = 0; i < indexCount; ++i ) {
-
- /*
- * Convert the current listPtr to a list if necessary.
- */
-
- result = Tcl_ListObjGetElements( interp, listPtr,
- &listLen, &elemPtrs);
- if (result != TCL_OK) {
- Tcl_DecrRefCount( listPtr );
- return NULL;
- }
-
- /*
- * Get the index from indices[ i ]
- */
-
- result = TclGetIntForIndex( interp, indices[ i ],
- /*endValue*/ (listLen - 1),
- &index );
- if ( result != TCL_OK ) {
- /*
- * Index could not be parsed
- */
-
- Tcl_DecrRefCount( listPtr );
- return NULL;
-
- } else if ( index < 0
- || index >= listLen ) {
- /*
- * Index is out of range
- */
- Tcl_DecrRefCount( listPtr );
- listPtr = Tcl_NewObj();
- Tcl_IncrRefCount( listPtr );
- return listPtr;
- }
-
- /*
- * Make sure listPtr still refers to a list object.
- * If it shared a Tcl_Obj structure with the arguments, then
- * it might have just been converted to something else.
- */
-
- if (listPtr->typePtr != &tclListType) {
- result = Tcl_ListObjGetElements(interp, listPtr, &listLen,
- &elemPtrs);
- if (result != TCL_OK) {
- Tcl_DecrRefCount( listPtr );
- return NULL;
- }
- }
-
- /*
- * Extract the pointer to the appropriate element
- */
-
- oldListPtr = listPtr;
- listPtr = elemPtrs[ index ];
- Tcl_IncrRefCount( listPtr );
- Tcl_DecrRefCount( oldListPtr );
-
- /*
- * The work we did above may have caused the internal rep
- * of *argPtr to change to something else. Get it back.
- */
-
- result = Tcl_ListObjGetElements( interp, argPtr,
- &indexCount, &indices );
- if ( result != TCL_OK ) {
- /*
- * This can't happen unless some extension corrupted a Tcl_Obj.
- */
- Tcl_DecrRefCount( listPtr );
- return NULL;
- }
-
- } /* end for */
-
- /*
- * Return the last object extracted. Its reference count will include
- * the reference being returned.
- */
-
- return listPtr;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TclLindexFlat --
- *
- * This procedure handles the 'lindex' command, given that the
- * arguments to the command are known to be a flat list.
- *
- * Results:
- * Returns a standard Tcl result.
- *
- * Side effects:
- * None.
- *
- * This procedure is called from either tclExecute.c or
- * Tcl_LindexObjCmd whenever either is presented with
- * objc == 2 or objc >= 4. It is also called from TclLindexList
- * for the objc==3 case once it is determined that objv[2] cannot
- * be parsed as a list.
- *
- *----------------------------------------------------------------------
- */
-
-Tcl_Obj *
-TclLindexFlat( interp, listPtr, indexCount, indexArray )
- Tcl_Interp* interp; /* Tcl interpreter */
- Tcl_Obj* listPtr; /* Tcl object representing the list */
- int indexCount; /* Count of indices */
- Tcl_Obj* CONST indexArray[];
- /* Array of pointers to Tcl objects
- * representing the indices in the
- * list */
-{
-
- int i; /* Current list index */
- int result; /* Result of Tcl library calls */
- int listLen; /* Length of the current list being
- * processed */
- Tcl_Obj** elemPtrs; /* Array of pointers to the elements
- * of the current list */
- int index; /* Parsed version of the current element
- * of indexArray */
- Tcl_Obj* oldListPtr; /* Temporary to hold listPtr so that
- * its ref count can be decremented. */
-
- /*
- * Record the reference to the 'listPtr' object that we are
- * maintaining in the C activation record.
- */
-
- Tcl_IncrRefCount( listPtr );
-
- for ( i = 0; i < indexCount; ++i ) {
-
- /*
- * Convert the current listPtr to a list if necessary.
- */
-
- result = Tcl_ListObjGetElements(interp, listPtr,
- &listLen, &elemPtrs);
- if (result != TCL_OK) {
- Tcl_DecrRefCount( listPtr );
- return NULL;
- }
-
- /*
- * Get the index from objv[i]
- */
-
- result = TclGetIntForIndex( interp, indexArray[ i ],
- /*endValue*/ (listLen - 1),
- &index );
- if ( result != TCL_OK ) {
-
- /* Index could not be parsed */
-
- Tcl_DecrRefCount( listPtr );
- return NULL;
-
- } else if ( index < 0
- || index >= listLen ) {
-
- /*
- * Index is out of range
- */
-
- Tcl_DecrRefCount( listPtr );
- listPtr = Tcl_NewObj();
- Tcl_IncrRefCount( listPtr );
- return listPtr;
- }
-
- /*
- * Make sure listPtr still refers to a list object.
- * It might have been converted to something else above
- * if objv[1] overlaps with one of the other parameters.
- */
-
- if (listPtr->typePtr != &tclListType) {
- result = Tcl_ListObjGetElements(interp, listPtr, &listLen,
- &elemPtrs);
- if (result != TCL_OK) {
- Tcl_DecrRefCount( listPtr );
- return NULL;
- }
- }
-
- /*
- * Extract the pointer to the appropriate element
- */
-
- oldListPtr = listPtr;
- listPtr = elemPtrs[ index ];
- Tcl_IncrRefCount( listPtr );
- Tcl_DecrRefCount( oldListPtr );
-
- }
-
- return listPtr;
-
-}
-
-/*
- *----------------------------------------------------------------------
- *
* Tcl_LinsertObjCmd --
*
* This object-based procedure is invoked to process the "linsert" Tcl
* command. See the user documentation for details on what it does.
*
* Results:
- * A new Tcl list object formed by inserting zero or more elements
- * into a list.
+ * A new Tcl list object formed by inserting zero or more elements into a
+ * list.
*
* Side effects:
* See the user documentation.
@@ -2796,34 +2159,33 @@ TclLindexFlat( interp, listPtr, indexCount, indexArray )
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
int
-Tcl_LinsertObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- register int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_LinsertObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ register int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Tcl_Obj *listPtr;
- int index, isDuplicate, len, result;
+ int index, len, result;
if (objc < 4) {
Tcl_WrongNumArgs(interp, 1, objv, "list index element ?element ...?");
return TCL_ERROR;
}
- result = Tcl_ListObjLength(interp, objv[1], &len);
+ result = TclListObjLength(interp, objv[1], &len);
if (result != TCL_OK) {
return result;
}
/*
- * Get the index. "end" is interpreted to be the index after the last
+ * Get the index. "end" is interpreted to be the index after the last
* element, such that using it will cause any inserted elements to be
* appended to the list.
*/
- result = TclGetIntForIndex(interp, objv[2], /*end*/ len, &index);
+ result = TclGetIntForIndexM(interp, objv[2], /*end*/ len, &index);
if (result != TCL_OK) {
return result;
}
@@ -2832,33 +2194,25 @@ Tcl_LinsertObjCmd(dummy, interp, objc, objv)
}
/*
- * If the list object is unshared we can modify it directly. Otherwise
- * we create a copy to modify: this is "copy on write".
+ * If the list object is unshared we can modify it directly. Otherwise we
+ * create a copy to modify: this is "copy on write".
*/
listPtr = objv[1];
- isDuplicate = 0;
if (Tcl_IsShared(listPtr)) {
- listPtr = Tcl_DuplicateObj(listPtr);
- isDuplicate = 1;
+ listPtr = TclListObjCopy(NULL, listPtr);
}
if ((objc == 4) && (index == len)) {
/*
* Special case: insert one element at the end of the list.
*/
- result = Tcl_ListObjAppendElement(interp, listPtr, objv[3]);
- } else if (objc > 3) {
- result = Tcl_ListObjReplace(interp, listPtr, index, 0,
- (objc-3), &(objv[3]));
- }
- if (result != TCL_OK) {
- if (isDuplicate) {
- Tcl_DecrRefCount(listPtr); /* free unneeded obj */
- }
- return result;
+
+ Tcl_ListObjAppendElement(NULL, listPtr, objv[3]);
+ } else {
+ Tcl_ListObjReplace(NULL, listPtr, index, 0, (objc-3), &(objv[3]));
}
-
+
/*
* Set the interpreter's object result.
*/
@@ -2872,8 +2226,8 @@ Tcl_LinsertObjCmd(dummy, interp, objc, objv)
*
* Tcl_ListObjCmd --
*
- * This procedure is invoked to process the "list" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "list" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl object result.
@@ -2884,21 +2238,21 @@ Tcl_LinsertObjCmd(dummy, interp, objc, objv)
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
int
-Tcl_ListObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- register int objc; /* Number of arguments. */
- register Tcl_Obj *CONST objv[]; /* The argument objects. */
+Tcl_ListObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ register int objc, /* Number of arguments. */
+ register Tcl_Obj *CONST objv[])
+ /* The argument objects. */
{
/*
* If there are no list elements, the result is an empty object.
- * Otherwise modify the interpreter's result object to be a list object.
+ * Otherwise set the interpreter's result object to be a list object.
*/
-
+
if (objc > 1) {
- Tcl_SetListObj(Tcl_GetObjResult(interp), (objc-1), &(objv[1]));
+ Tcl_SetObjResult(interp, Tcl_NewListObj((objc-1), &(objv[1])));
}
return TCL_OK;
}
@@ -2909,7 +2263,7 @@ Tcl_ListObjCmd(dummy, interp, objc, objv)
* Tcl_LlengthObjCmd --
*
* This object-based procedure is invoked to process the "llength" Tcl
- * command. See the user documentation for details on what it does.
+ * command. See the user documentation for details on what it does.
*
* Results:
* A standard Tcl object result.
@@ -2920,13 +2274,13 @@ Tcl_ListObjCmd(dummy, interp, objc, objv)
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
int
-Tcl_LlengthObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- register Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_LlengthObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ register Tcl_Obj *CONST objv[])
+ /* Argument objects. */
{
int listLen, result;
@@ -2935,17 +2289,17 @@ Tcl_LlengthObjCmd(dummy, interp, objc, objv)
return TCL_ERROR;
}
- result = Tcl_ListObjLength(interp, objv[1], &listLen);
+ result = TclListObjLength(interp, objv[1], &listLen);
if (result != TCL_OK) {
return result;
}
/*
* Set the interpreter's object result to an integer object holding the
- * length.
+ * length.
*/
- Tcl_SetIntObj(Tcl_GetObjResult(interp), listLen);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(listLen));
return TCL_OK;
}
@@ -2954,8 +2308,8 @@ Tcl_LlengthObjCmd(dummy, interp, objc, objv)
*
* Tcl_LrangeObjCmd --
*
- * This procedure is invoked to process the "lrange" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "lrange" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl object result.
@@ -2966,17 +2320,16 @@ Tcl_LlengthObjCmd(dummy, interp, objc, objv)
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
int
-Tcl_LrangeObjCmd(notUsed, interp, objc, objv)
- ClientData notUsed; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- register Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_LrangeObjCmd(
+ ClientData notUsed, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ register Tcl_Obj *CONST objv[])
+ /* Argument objects. */
{
- Tcl_Obj *listPtr;
- Tcl_Obj **elemPtrs;
- int listLen, first, last, numElems, result;
+ Tcl_Obj *listPtr, **elemPtrs;
+ int listLen, first, result;
if (objc != 4) {
Tcl_WrongNumArgs(interp, 1, objv, "list first last");
@@ -2984,62 +2337,143 @@ Tcl_LrangeObjCmd(notUsed, interp, objc, objv)
}
/*
- * Make sure the list argument is a list object and get its length and
- * a pointer to its array of element pointers.
+ * Make sure the list argument is a list object and get its length and a
+ * pointer to its array of element pointers.
*/
- listPtr = objv[1];
- result = Tcl_ListObjGetElements(interp, listPtr, &listLen, &elemPtrs);
- if (result != TCL_OK) {
- return result;
+ listPtr = TclListObjCopy(interp, objv[1]);
+ if (listPtr == NULL) {
+ return TCL_ERROR;
}
+ TclListObjGetElements(NULL, listPtr, &listLen, &elemPtrs);
- /*
- * Get the first and last indexes.
- */
-
- result = TclGetIntForIndex(interp, objv[2], /*endValue*/ (listLen - 1),
+ result = TclGetIntForIndexM(interp, objv[2], /*endValue*/ listLen - 1,
&first);
- if (result != TCL_OK) {
- return result;
- }
- if (first < 0) {
- first = 0;
+ if (result == TCL_OK) {
+ int last;
+
+ if (first < 0) {
+ first = 0;
+ }
+
+ result = TclGetIntForIndexM(interp, objv[3], /*endValue*/ listLen - 1,
+ &last);
+ if (result == TCL_OK) {
+ if (last >= listLen) {
+ last = (listLen - 1);
+ }
+
+ if (first <= last) {
+ int numElems = (last - first + 1);
+
+ Tcl_SetObjResult(interp,
+ Tcl_NewListObj(numElems, &(elemPtrs[first])));
+ }
+ }
}
- result = TclGetIntForIndex(interp, objv[3], /*endValue*/ (listLen - 1),
- &last);
- if (result != TCL_OK) {
- return result;
+ Tcl_DecrRefCount(listPtr);
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LrepeatObjCmd --
+ *
+ * This procedure is invoked to process the "lrepeat" Tcl command. See
+ * the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl object result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LrepeatObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ register int objc, /* Number of arguments. */
+ register Tcl_Obj *CONST objv[])
+ /* The argument objects. */
+{
+ int elementCount, i, totalElems;
+ Tcl_Obj *listPtr, **dataArray;
+ List *listRepPtr;
+
+ /*
+ * Check arguments for legality:
+ * lrepeat posInt value ?value ...?
+ */
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "positiveCount value ?value ...?");
+ return TCL_ERROR;
}
- if (last >= listLen) {
- last = (listLen - 1);
+ if (TCL_ERROR == TclGetIntFromObj(interp, objv[1], &elementCount)) {
+ return TCL_ERROR;
}
-
- if (first > last) {
- return TCL_OK; /* the result is an empty object */
+ if (elementCount < 1) {
+ Tcl_AppendResult(interp, "must have a count of at least 1", NULL);
+ return TCL_ERROR;
}
/*
- * Make sure listPtr still refers to a list object. It might have been
- * converted to an int above if the argument objects were shared.
- */
+ * Skip forward to the interesting arguments now we've finished parsing.
+ */
+
+ objc -= 2;
+ objv += 2;
- if (listPtr->typePtr != &tclListType) {
- result = Tcl_ListObjGetElements(interp, listPtr, &listLen,
- &elemPtrs);
- if (result != TCL_OK) {
- return result;
- }
+ /* Final sanity check. Do not exceed limits on max list length. */
+
+ if (objc > LIST_MAX/elementCount) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "max length of a Tcl list (%d elements) exceeded", LIST_MAX));
+ return TCL_ERROR;
}
+ totalElems = objc * elementCount;
/*
- * Extract a range of fields. We modify the interpreter's result object
- * to be a list object containing the specified elements.
+ * Get an empty list object that is allocated large enough to hold each
+ * init value elementCount times.
*/
- numElems = (last - first + 1);
- Tcl_SetListObj(Tcl_GetObjResult(interp), numElems, &(elemPtrs[first]));
+ listPtr = Tcl_NewListObj(totalElems, NULL);
+ listRepPtr = ListRepPtr(listPtr);
+ listRepPtr->elemCount = elementCount*objc;
+ dataArray = &listRepPtr->elements;
+
+ /*
+ * Set the elements. Note that we handle the common degenerate case of a
+ * single value being repeated separately to permit the compiler as much
+ * room as possible to optimize a loop that might be run a very large
+ * number of times.
+ */
+
+ if (objc == 1) {
+ register Tcl_Obj *tmpPtr = objv[0];
+
+ tmpPtr->refCount += elementCount;
+ for (i=0 ; i<elementCount ; i++) {
+ dataArray[i] = tmpPtr;
+ }
+ } else {
+ int j, k = 0;
+
+ for (i=0 ; i<elementCount ; i++) {
+ for (j=0 ; j<objc ; j++) {
+ Tcl_IncrRefCount(objv[j]);
+ dataArray[k++] = objv[j];
+ }
+ }
+ }
+
+ Tcl_SetObjResult(interp, listPtr);
return TCL_OK;
}
@@ -3048,12 +2482,12 @@ Tcl_LrangeObjCmd(notUsed, interp, objc, objv)
*
* Tcl_LreplaceObjCmd --
*
- * This object-based procedure is invoked to process the "lreplace"
- * Tcl command. See the user documentation for details on what it does.
+ * This object-based procedure is invoked to process the "lreplace" Tcl
+ * command. See the user documentation for details on what it does.
*
* Results:
- * A new Tcl list object formed by replacing zero or more elements of
- * a list.
+ * A new Tcl list object formed by replacing zero or more elements of a
+ * list.
*
* Side effects:
* See the user documentation.
@@ -3061,16 +2495,15 @@ Tcl_LrangeObjCmd(notUsed, interp, objc, objv)
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
int
-Tcl_LreplaceObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_LreplaceObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
register Tcl_Obj *listPtr;
- int isDuplicate, first, last, listLen, numToDelete, result;
+ int first, last, listLen, numToDelete, result;
if (objc < 4) {
Tcl_WrongNumArgs(interp, 1, objv,
@@ -3078,42 +2511,41 @@ Tcl_LreplaceObjCmd(dummy, interp, objc, objv)
return TCL_ERROR;
}
- result = Tcl_ListObjLength(interp, objv[1], &listLen);
+ result = TclListObjLength(interp, objv[1], &listLen);
if (result != TCL_OK) {
return result;
}
/*
- * Get the first and last indexes. "end" is interpreted to be the index
- * for the last element, such that using it will cause that element to
- * be included for deletion.
+ * Get the first and last indexes. "end" is interpreted to be the index
+ * for the last element, such that using it will cause that element to be
+ * included for deletion.
*/
- result = TclGetIntForIndex(interp, objv[2], /*end*/ (listLen - 1), &first);
+ result = TclGetIntForIndexM(interp, objv[2], /*end*/ listLen-1, &first);
if (result != TCL_OK) {
return result;
}
- result = TclGetIntForIndex(interp, objv[3], /*end*/ (listLen - 1), &last);
+ result = TclGetIntForIndexM(interp, objv[3], /*end*/ listLen-1, &last);
if (result != TCL_OK) {
return result;
}
- if (first < 0) {
+ if (first < 0) {
first = 0;
}
/*
* Complain if the user asked for a start element that is greater than the
- * list length. This won't ever trigger for the "end*" case as that will
+ * list length. This won't ever trigger for the "end-*" case as that will
* be properly constrained by TclGetIntForIndex because we use listLen-1
* (to allow for replacing the last elem).
*/
if ((first >= listLen) && (listLen > 0)) {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "list doesn't contain element ",
- Tcl_GetString(objv[2]), (int *) NULL);
+ Tcl_AppendResult(interp, "list doesn't contain element ",
+ TclGetString(objv[2]), NULL);
return TCL_ERROR;
}
if (last >= listLen) {
@@ -3126,35 +2558,109 @@ Tcl_LreplaceObjCmd(dummy, interp, objc, objv)
}
/*
- * If the list object is unshared we can modify it directly, otherwise
- * we create a copy to modify: this is "copy on write".
+ * If the list object is unshared we can modify it directly, otherwise we
+ * create a copy to modify: this is "copy on write".
*/
listPtr = objv[1];
- isDuplicate = 0;
if (Tcl_IsShared(listPtr)) {
- listPtr = Tcl_DuplicateObj(listPtr);
- isDuplicate = 1;
+ listPtr = TclListObjCopy(NULL, listPtr);
}
- if (objc > 4) {
- result = Tcl_ListObjReplace(interp, listPtr, first, numToDelete,
- (objc-4), &(objv[4]));
- } else {
- result = Tcl_ListObjReplace(interp, listPtr, first, numToDelete,
- 0, NULL);
+
+ /*
+ * Note that we call Tcl_ListObjReplace even when numToDelete == 0 and
+ * objc == 4. In this case, the list value of listPtr is not changed (no
+ * elements are removed or added), but by making the call we are assured
+ * we end up with a list in canonical form. Resist any temptation to
+ * optimize this case away.
+ */
+
+ Tcl_ListObjReplace(NULL, listPtr, first, numToDelete, objc-4, &(objv[4]));
+
+ /*
+ * Set the interpreter's object result.
+ */
+
+ Tcl_SetObjResult(interp, listPtr);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LreverseObjCmd --
+ *
+ * This procedure is invoked to process the "lreverse" Tcl command. See
+ * the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LreverseObjCmd(
+ ClientData clientData, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument values. */
+{
+ Tcl_Obj **elemv;
+ int elemc, i, j;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "list");
+ return TCL_ERROR;
}
- if (result != TCL_OK) {
- if (isDuplicate) {
- Tcl_DecrRefCount(listPtr); /* free unneeded obj */
- }
- return result;
+ if (TclListObjGetElements(interp, objv[1], &elemc, &elemv) != TCL_OK) {
+ return TCL_ERROR;
}
/*
- * Set the interpreter's object result.
+ * If the list is empty, just return it [Bug 1876793]
*/
- Tcl_SetObjResult(interp, listPtr);
+ if (!elemc) {
+ Tcl_SetObjResult(interp, objv[1]);
+ return TCL_OK;
+ }
+
+ if (Tcl_IsShared(objv[1])
+ || (ListRepPtr(objv[1])->refCount > 1)) { /* Bug 1675044 */
+ Tcl_Obj *resultObj, **dataArray;
+ List *listRepPtr;
+
+ resultObj = Tcl_NewListObj(elemc, NULL);
+ listRepPtr = ListRepPtr(resultObj);
+ listRepPtr->elemCount = elemc;
+ dataArray = &listRepPtr->elements;
+
+ for (i=0,j=elemc-1 ; i<elemc ; i++,j--) {
+ dataArray[j] = elemv[i];
+ Tcl_IncrRefCount(elemv[i]);
+ }
+
+ Tcl_SetObjResult(interp, resultObj);
+ } else {
+
+ /*
+ * Not shared, so swap "in place". This relies on Tcl_LOGE above
+ * returning a pointer to the live array of Tcl_Obj values.
+ */
+
+ for (i=0,j=elemc-1 ; i<j ; i++,j--) {
+ Tcl_Obj *tmp = elemv[i];
+
+ elemv[i] = elemv[j];
+ elemv[j] = tmp;
+ }
+ TclInvalidateStringRep(objv[1]);
+ Tcl_SetObjResult(interp, objv[1]);
+ }
return TCL_OK;
}
@@ -3163,8 +2669,8 @@ Tcl_LreplaceObjCmd(dummy, interp, objc, objv)
*
* Tcl_LsearchObjCmd --
*
- * This procedure is invoked to process the "lsearch" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "lsearch" Tcl command. See
+ * the user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -3176,30 +2682,34 @@ Tcl_LreplaceObjCmd(dummy, interp, objc, objv)
*/
int
-Tcl_LsearchObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
+Tcl_LsearchObjCmd(
+ ClientData clientData, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument values. */
{
char *bytes, *patternBytes;
int i, match, mode, index, result, listc, length, elemLen;
- int dataType, isIncreasing, lower, upper, patInt, objInt;
- int offset, allMatches, inlineReturn, negatedMatch;
+ int dataType, isIncreasing, lower, upper, patInt, objInt, offset;
+ int allMatches, inlineReturn, negatedMatch, returnSubindices, noCase;
double patDouble, objDouble;
- Tcl_Obj *patObj, **listv, *listPtr, *startPtr;
+ SortInfo sortInfo;
+ Tcl_Obj *patObj, **listv, *listPtr, *startPtr, *itemPtr;
+ SortStrCmpFn_t strCmpFn = strcmp;
Tcl_RegExp regexp = NULL;
static CONST char *options[] = {
- "-all", "-ascii", "-decreasing", "-dictionary",
- "-exact", "-glob", "-increasing", "-inline",
- "-integer", "-not", "-real", "-regexp",
- "-sorted", "-start", NULL
+ "-all", "-ascii", "-decreasing", "-dictionary",
+ "-exact", "-glob", "-increasing", "-index",
+ "-inline", "-integer", "-nocase", "-not",
+ "-real", "-regexp", "-sorted", "-start",
+ "-subindices", NULL
};
enum options {
LSEARCH_ALL, LSEARCH_ASCII, LSEARCH_DECREASING, LSEARCH_DICTIONARY,
- LSEARCH_EXACT, LSEARCH_GLOB, LSEARCH_INCREASING, LSEARCH_INLINE,
- LSEARCH_INTEGER, LSEARCH_NOT, LSEARCH_REAL, LSEARCH_REGEXP,
- LSEARCH_SORTED, LSEARCH_START
+ LSEARCH_EXACT, LSEARCH_GLOB, LSEARCH_INCREASING, LSEARCH_INDEX,
+ LSEARCH_INLINE, LSEARCH_INTEGER, LSEARCH_NOCASE, LSEARCH_NOT,
+ LSEARCH_REAL, LSEARCH_REGEXP, LSEARCH_SORTED, LSEARCH_START,
+ LSEARCH_SUBINDICES
};
enum datatypes {
ASCII, DICTIONARY, INTEGER, REAL
@@ -3213,10 +2723,19 @@ Tcl_LsearchObjCmd(clientData, interp, objc, objv)
isIncreasing = 1;
allMatches = 0;
inlineReturn = 0;
+ returnSubindices = 0;
negatedMatch = 0;
listPtr = NULL;
startPtr = NULL;
offset = 0;
+ noCase = 0;
+ sortInfo.compareCmdPtr = NULL;
+ sortInfo.isIncreasing = 1;
+ sortInfo.sortMode = 0;
+ sortInfo.interp = interp;
+ sortInfo.resultCode = TCL_OK;
+ sortInfo.indexv = NULL;
+ sortInfo.indexc = 0;
if (objc < 3) {
Tcl_WrongNumArgs(interp, 1, objv, "?options? list pattern");
@@ -3226,9 +2745,12 @@ Tcl_LsearchObjCmd(clientData, interp, objc, objv)
for (i = 1; i < objc-2; i++) {
if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0, &index)
!= TCL_OK) {
- if (startPtr) {
+ if (startPtr != NULL) {
Tcl_DecrRefCount(startPtr);
}
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
return TCL_ERROR;
}
switch ((enum options) index) {
@@ -3240,6 +2762,7 @@ Tcl_LsearchObjCmd(clientData, interp, objc, objv)
break;
case LSEARCH_DECREASING: /* -decreasing */
isIncreasing = 0;
+ sortInfo.isIncreasing = 0;
break;
case LSEARCH_DICTIONARY: /* -dictionary */
dataType = DICTIONARY;
@@ -3252,6 +2775,7 @@ Tcl_LsearchObjCmd(clientData, interp, objc, objv)
break;
case LSEARCH_INCREASING: /* -increasing */
isIncreasing = 1;
+ sortInfo.isIncreasing = 1;
break;
case LSEARCH_INLINE: /* -inline */
inlineReturn = 1;
@@ -3259,6 +2783,10 @@ Tcl_LsearchObjCmd(clientData, interp, objc, objv)
case LSEARCH_INTEGER: /* -integer */
dataType = INTEGER;
break;
+ case LSEARCH_NOCASE: /* -nocase */
+ strCmpFn = strcasecmp;
+ noCase = 1;
+ break;
case LSEARCH_NOT: /* -not */
negatedMatch = 1;
break;
@@ -3271,88 +2799,183 @@ Tcl_LsearchObjCmd(clientData, interp, objc, objv)
case LSEARCH_SORTED: /* -sorted */
mode = SORTED;
break;
+ case LSEARCH_SUBINDICES: /* -subindices */
+ returnSubindices = 1;
+ break;
case LSEARCH_START: /* -start */
/*
- * If there was a previous -start option, release its saved
- * index because it will either be replaced or there will be
- * an error.
+ * If there was a previous -start option, release its saved index
+ * because it will either be replaced or there will be an error.
*/
- if (startPtr) {
+
+ if (startPtr != NULL) {
Tcl_DecrRefCount(startPtr);
}
if (i > objc-4) {
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
Tcl_AppendResult(interp, "missing starting index", NULL);
return TCL_ERROR;
}
i++;
if (objv[i] == objv[objc - 2]) {
/*
- * Take copy to prevent shimmering problems. Note
- * that it does not matter if the index obj is also a
- * component of the list being searched. We only need
- * to copy where the list and the index are
- * one-and-the-same.
+ * Take copy to prevent shimmering problems. Note that it does
+ * not matter if the index obj is also a component of the list
+ * being searched. We only need to copy where the list and the
+ * index are one-and-the-same.
*/
+
startPtr = Tcl_DuplicateObj(objv[i]);
} else {
startPtr = objv[i];
Tcl_IncrRefCount(startPtr);
}
+ break;
+ case LSEARCH_INDEX: { /* -index */
+ Tcl_Obj **indices;
+ int j;
+
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ if (i > objc-4) {
+ if (startPtr != NULL) {
+ Tcl_DecrRefCount(startPtr);
+ }
+ Tcl_AppendResult(interp,
+ "\"-index\" option must be followed by list index",
+ NULL);
+ return TCL_ERROR;
+ }
+
+ /*
+ * Store the extracted indices for processing by sublist
+ * extraction. Note that we don't do this using objects because
+ * that has shimmering problems.
+ */
+
+ i++;
+ if (TclListObjGetElements(interp, objv[i],
+ &sortInfo.indexc, &indices) != TCL_OK) {
+ if (startPtr != NULL) {
+ Tcl_DecrRefCount(startPtr);
+ }
+ return TCL_ERROR;
+ }
+ switch (sortInfo.indexc) {
+ case 0:
+ sortInfo.indexv = NULL;
+ break;
+ case 1:
+ sortInfo.indexv = &sortInfo.singleIndex;
+ break;
+ default:
+ sortInfo.indexv = (int *)
+ ckalloc(sizeof(int) * sortInfo.indexc);
+ }
+
+ /*
+ * Fill the array by parsing each index. We don't know whether
+ * their scale is sensible yet, but we at least perform the
+ * syntactic check here.
+ */
+
+ for (j=0 ; j<sortInfo.indexc ; j++) {
+ if (TclGetIntForIndexM(interp, indices[j], SORTIDX_END,
+ &sortInfo.indexv[j]) != TCL_OK) {
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+ "\n (-index option item number %d)", j));
+ return TCL_ERROR;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ /*
+ * Subindices only make sense if asked for with -index option set.
+ */
+
+ if (returnSubindices && sortInfo.indexc==0) {
+ if (startPtr != NULL) {
+ Tcl_DecrRefCount(startPtr);
}
+ Tcl_AppendResult(interp,
+ "-subindices cannot be used without -index option", NULL);
+ return TCL_ERROR;
}
if ((enum modes) mode == REGEXP) {
/*
* We can shimmer regexp/list if listv[i] == pattern, so get the
* regexp rep before the list rep. First time round, omit the interp
- * and hope that the compilation will succeed. If it fails, we'll
- * recompile in "expensive" mode with a place to put error messages.
+ * and hope that the compilation will succeed. If it fails, we'll
+ * recompile in "expensive" mode with a place to put error messages.
*/
regexp = Tcl_GetRegExpFromObj(NULL, objv[objc - 1],
- TCL_REG_ADVANCED | TCL_REG_NOSUB);
+ TCL_REG_ADVANCED | TCL_REG_NOSUB |
+ (noCase ? TCL_REG_NOCASE : 0));
if (regexp == NULL) {
- /*
- * Failed to compile the RE. Try again without the TCL_REG_NOSUB
- * flag in case the RE had sub-expressions in it [Bug 1366683].
- * If this fails, an error message will be left in the
- * interpreter.
- */
-
- regexp = Tcl_GetRegExpFromObj(interp, objv[objc - 1],
- TCL_REG_ADVANCED);
+ /*
+ * Failed to compile the RE. Try again without the TCL_REG_NOSUB
+ * flag in case the RE had sub-expressions in it [Bug 1366683]. If
+ * this fails, an error message will be left in the interpreter.
+ */
+
+ regexp = Tcl_GetRegExpFromObj(interp, objv[objc - 1],
+ TCL_REG_ADVANCED | (noCase ? TCL_REG_NOCASE : 0));
}
if (regexp == NULL) {
- if (startPtr) {
+ if (startPtr != NULL) {
Tcl_DecrRefCount(startPtr);
}
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
return TCL_ERROR;
}
}
/*
- * Make sure the list argument is a list object and get its length and
- * a pointer to its array of element pointers.
+ * Make sure the list argument is a list object and get its length and a
+ * pointer to its array of element pointers.
*/
- result = Tcl_ListObjGetElements(interp, objv[objc - 2], &listc, &listv);
+ result = TclListObjGetElements(interp, objv[objc - 2], &listc, &listv);
if (result != TCL_OK) {
- if (startPtr) {
+ if (startPtr != NULL) {
Tcl_DecrRefCount(startPtr);
}
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
return result;
}
/*
* Get the user-specified start offset.
*/
+
if (startPtr) {
- result = TclGetIntForIndex(interp, startPtr, listc-1, &offset);
+ result = TclGetIntForIndexM(interp, startPtr, listc-1, &offset);
Tcl_DecrRefCount(startPtr);
if (result != TCL_OK) {
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
return result;
}
+ if (offset < 0) {
+ offset = 0;
+ }
/*
* If the search started past the end of the list, we just return a
@@ -3360,6 +2983,9 @@ Tcl_LsearchObjCmd(clientData, interp, objc, objv)
*/
if (offset > listc-1) {
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
if (allMatches || inlineReturn) {
Tcl_ResetResult(interp);
} else {
@@ -3367,9 +2993,6 @@ Tcl_LsearchObjCmd(clientData, interp, objc, objv)
}
return TCL_OK;
}
- if (offset < 0) {
- offset = 0;
- }
}
patObj = objv[objc - 1];
@@ -3378,59 +3001,91 @@ Tcl_LsearchObjCmd(clientData, interp, objc, objv)
switch ((enum datatypes) dataType) {
case ASCII:
case DICTIONARY:
- patternBytes = Tcl_GetStringFromObj(patObj, &length);
+ patternBytes = TclGetStringFromObj(patObj, &length);
break;
case INTEGER:
- result = Tcl_GetIntFromObj(interp, patObj, &patInt);
+ result = TclGetIntFromObj(interp, patObj, &patInt);
if (result != TCL_OK) {
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
return result;
}
- Tcl_ListObjGetElements(NULL, objv[objc - 2], &listc, &listv);
+
+ /*
+ * List representation might have been shimmered; restore it. [Bug
+ * 1844789]
+ */
+
+ TclListObjGetElements(NULL, objv[objc - 2], &listc, &listv);
break;
case REAL:
result = Tcl_GetDoubleFromObj(interp, patObj, &patDouble);
if (result != TCL_OK) {
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
return result;
}
- Tcl_ListObjGetElements(NULL, objv[objc - 2], &listc, &listv);
+
+ /*
+ * List representation might have been shimmered; restore it. [Bug
+ * 1844789]
+ */
+
+ TclListObjGetElements(NULL, objv[objc - 2], &listc, &listv);
break;
}
} else {
- patternBytes = Tcl_GetStringFromObj(patObj, &length);
+ patternBytes = TclGetStringFromObj(patObj, &length);
}
/*
- * Set default index value to -1, indicating failure; if we find the
- * item in the course of our search, index will be set to the correct
- * value.
+ * Set default index value to -1, indicating failure; if we find the item
+ * in the course of our search, index will be set to the correct value.
*/
+
index = -1;
match = 0;
if ((enum modes) mode == SORTED && !allMatches && !negatedMatch) {
/*
- * If the data is sorted, we can do a more intelligent search.
- * Note that there is no point in being smart when -all was
- * specified; in that case, we have to look at all items anyway,
- * and there is no sense in doing this when the match sense is
- * inverted.
+ * If the data is sorted, we can do a more intelligent search. Note
+ * that there is no point in being smart when -all was specified; in
+ * that case, we have to look at all items anyway, and there is no
+ * sense in doing this when the match sense is inverted.
*/
+
lower = offset - 1;
upper = listc;
- while (lower + 1 != upper) {
+ while (lower + 1 != upper && sortInfo.resultCode == TCL_OK) {
i = (lower + upper)/2;
+ if (sortInfo.indexc != 0) {
+ itemPtr = SelectObjFromSublist(listv[i], &sortInfo);
+ if (sortInfo.resultCode != TCL_OK) {
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ return sortInfo.resultCode;
+ }
+ } else {
+ itemPtr = listv[i];
+ }
switch ((enum datatypes) dataType) {
case ASCII:
- bytes = Tcl_GetString(listv[i]);
- match = strcmp(patternBytes, bytes);
+ bytes = TclGetString(itemPtr);
+ match = strCmpFn(patternBytes, bytes);
break;
case DICTIONARY:
- bytes = Tcl_GetString(listv[i]);
+ bytes = TclGetString(itemPtr);
match = DictionaryCompare(patternBytes, bytes);
break;
case INTEGER:
- result = Tcl_GetIntFromObj(interp, listv[i], &objInt);
+ result = TclGetIntFromObj(interp, itemPtr, &objInt);
if (result != TCL_OK) {
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
return result;
}
if (patInt == objInt) {
@@ -3442,8 +3097,11 @@ Tcl_LsearchObjCmd(clientData, interp, objc, objv)
}
break;
case REAL:
- result = Tcl_GetDoubleFromObj(interp, listv[i], &objDouble);
+ result = Tcl_GetDoubleFromObj(interp, itemPtr, &objDouble);
if (result != TCL_OK) {
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
return result;
}
if (patDouble == objDouble) {
@@ -3457,17 +3115,19 @@ Tcl_LsearchObjCmd(clientData, interp, objc, objv)
}
if (match == 0) {
/*
- * Normally, binary search is written to stop when it
- * finds a match. If there are duplicates of an element in
- * the list, our first match might not be the first occurance.
- * Consider: 0 0 0 1 1 1 2 2 2
- * To maintain consistancy with standard lsearch semantics,
- * we must find the leftmost occurance of the pattern in the
- * list. Thus we don't just stop searching here. This
+ * Normally, binary search is written to stop when it finds a
+ * match. If there are duplicates of an element in the list,
+ * our first match might not be the first occurance.
+ * Consider: 0 0 0 1 1 1 2 2 2
+ *
+ * To maintain consistancy with standard lsearch semantics, we
+ * must find the leftmost occurance of the pattern in the
+ * list. Thus we don't just stop searching here. This
* variation means that a search always makes log n
- * comparisons (normal binary search might "get lucky" with
- * an early comparison).
+ * comparisons (normal binary search might "get lucky" with an
+ * early comparison).
*/
+
index = i;
upper = i;
} else if (match > 0) {
@@ -3492,83 +3152,138 @@ Tcl_LsearchObjCmd(clientData, interp, objc, objv)
* - our matching sense is negated
* - we're building a list of all matched items
*/
+
if (allMatches) {
- listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
+ listPtr = Tcl_NewListObj(0, NULL);
}
for (i = offset; i < listc; i++) {
match = 0;
+ if (sortInfo.indexc != 0) {
+ itemPtr = SelectObjFromSublist(listv[i], &sortInfo);
+ if (sortInfo.resultCode != TCL_OK) {
+ if (listPtr != NULL) {
+ Tcl_DecrRefCount(listPtr);
+ }
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ return sortInfo.resultCode;
+ }
+ } else {
+ itemPtr = listv[i];
+ }
+
switch ((enum modes) mode) {
case SORTED:
case EXACT:
switch ((enum datatypes) dataType) {
case ASCII:
- bytes = Tcl_GetStringFromObj(listv[i], &elemLen);
+ bytes = TclGetStringFromObj(itemPtr, &elemLen);
if (length == elemLen) {
- match = (memcmp(bytes, patternBytes,
- (size_t) length) == 0);
+ /*
+ * This split allows for more optimal compilation of
+ * memcmp/strcasecmp.
+ */
+
+ if (noCase) {
+ match = (strcasecmp(bytes, patternBytes) == 0);
+ } else {
+ match = (memcmp(bytes, patternBytes,
+ (size_t) length) == 0);
+ }
}
break;
+
case DICTIONARY:
- bytes = Tcl_GetString(listv[i]);
+ bytes = TclGetString(itemPtr);
match = (DictionaryCompare(bytes, patternBytes) == 0);
break;
+
case INTEGER:
- result = Tcl_GetIntFromObj(interp, listv[i], &objInt);
+ result = TclGetIntFromObj(interp, itemPtr, &objInt);
if (result != TCL_OK) {
- if (listPtr) {
+ if (listPtr != NULL) {
Tcl_DecrRefCount(listPtr);
}
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
return result;
}
match = (objInt == patInt);
break;
+
case REAL:
- result = Tcl_GetDoubleFromObj(interp, listv[i],
- &objDouble);
+ result = Tcl_GetDoubleFromObj(interp,itemPtr, &objDouble);
if (result != TCL_OK) {
if (listPtr) {
Tcl_DecrRefCount(listPtr);
}
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
return result;
}
match = (objDouble == patDouble);
break;
}
break;
+
case GLOB:
- match = Tcl_StringMatch(Tcl_GetString(listv[i]),
- patternBytes);
+ match = Tcl_StringCaseMatch(TclGetString(itemPtr),
+ patternBytes, noCase);
break;
+
case REGEXP:
- match = Tcl_RegExpExecObj(interp, regexp, listv[i], 0, 0, 0);
+ match = Tcl_RegExpExecObj(interp, regexp, itemPtr, 0, 0, 0);
if (match < 0) {
Tcl_DecrRefCount(patObj);
- if (listPtr) {
+ if (listPtr != NULL) {
Tcl_DecrRefCount(listPtr);
}
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
return TCL_ERROR;
}
break;
}
+
/*
- * Invert match condition for -not
+ * Invert match condition for -not.
*/
+
if (negatedMatch) {
match = !match;
}
- if (match != 0) {
- if (!allMatches) {
- index = i;
- break;
- } else if (inlineReturn) {
- /*
- * Note that these appends are not expected to fail.
- */
- Tcl_ListObjAppendElement(interp, listPtr, listv[i]);
+ if (!match) {
+ continue;
+ }
+ if (!allMatches) {
+ index = i;
+ break;
+ } else if (inlineReturn) {
+ /*
+ * Note that these appends are not expected to fail.
+ */
+
+ if (returnSubindices && (sortInfo.indexc != 0)) {
+ itemPtr = SelectObjFromSublist(listv[i], &sortInfo);
} else {
- Tcl_ListObjAppendElement(interp, listPtr,
- Tcl_NewIntObj(i));
+ itemPtr = listv[i];
+ }
+ Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
+ } else if (returnSubindices) {
+ int j;
+
+ itemPtr = Tcl_NewIntObj(i);
+ for (j=0 ; j<sortInfo.indexc ; j++) {
+ Tcl_ListObjAppendElement(interp, itemPtr,
+ Tcl_NewIntObj(sortInfo.indexv[j]));
}
+ Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
+ } else {
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewIntObj(i));
}
}
}
@@ -3576,19 +3291,40 @@ Tcl_LsearchObjCmd(clientData, interp, objc, objv)
/*
* Return everything or a single value.
*/
+
if (allMatches) {
Tcl_SetObjResult(interp, listPtr);
} else if (!inlineReturn) {
- Tcl_SetIntObj(Tcl_GetObjResult(interp), index);
+ if (returnSubindices) {
+ int j;
+
+ itemPtr = Tcl_NewIntObj(index);
+ for (j=0 ; j<sortInfo.indexc ; j++) {
+ Tcl_ListObjAppendElement(interp, itemPtr,
+ Tcl_NewIntObj(sortInfo.indexv[j]));
+ }
+ Tcl_SetObjResult(interp, itemPtr);
+ } else {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
+ }
} else if (index < 0) {
/*
- * Is this superfluous? The result should be a blank object
- * by default...
+ * Is this superfluous? The result should be a blank object by
+ * default...
*/
+
Tcl_SetObjResult(interp, Tcl_NewObj());
} else {
Tcl_SetObjResult(interp, listv[index]);
}
+
+ /*
+ * Cleanup the index list array.
+ */
+
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
return TCL_OK;
}
@@ -3597,8 +3333,8 @@ Tcl_LsearchObjCmd(clientData, interp, objc, objv)
*
* Tcl_LsetObjCmd --
*
- * This procedure is invoked to process the "lset" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "lset" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -3610,66 +3346,71 @@ Tcl_LsearchObjCmd(clientData, interp, objc, objv)
*/
int
-Tcl_LsetObjCmd( clientData, interp, objc, objv )
- ClientData clientData; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
+Tcl_LsetObjCmd(
+ ClientData clientData, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument values. */
{
+ Tcl_Obj *listPtr; /* Pointer to the list being altered. */
+ Tcl_Obj *finalValuePtr; /* Value finally assigned to the variable. */
- Tcl_Obj* listPtr; /* Pointer to the list being altered. */
- Tcl_Obj* finalValuePtr; /* Value finally assigned to the variable */
-
- /* Check parameter count */
+ /*
+ * Check parameter count.
+ */
- if ( objc < 3 ) {
- Tcl_WrongNumArgs( interp, 1, objv, "listVar index ?index...? value" );
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "listVar ?index? ?index...? value");
return TCL_ERROR;
}
- /* Look up the list variable's value */
+ /*
+ * Look up the list variable's value.
+ */
- listPtr = Tcl_ObjGetVar2( interp, objv[ 1 ], (Tcl_Obj*) NULL,
- TCL_LEAVE_ERR_MSG );
- if ( listPtr == NULL ) {
+ listPtr = Tcl_ObjGetVar2(interp, objv[1], (Tcl_Obj *) NULL,
+ TCL_LEAVE_ERR_MSG);
+ if (listPtr == NULL) {
return TCL_ERROR;
}
- /*
- * Substitute the value in the value. Return either the value or
- * else an unshared copy of it.
+ /*
+ * Substitute the value in the value. Return either the value or else an
+ * unshared copy of it.
*/
- if ( objc == 4 ) {
- finalValuePtr = TclLsetList( interp, listPtr,
- objv[ 2 ], objv[ 3 ] );
+ if (objc == 4) {
+ finalValuePtr = TclLsetList(interp, listPtr, objv[2], objv[3]);
} else {
- finalValuePtr = TclLsetFlat( interp, listPtr,
- objc-3, objv+2, objv[ objc-1 ] );
+ finalValuePtr = TclLsetFlat(interp, listPtr, objc-3, objv+2,
+ objv[objc-1]);
}
/*
* If substitution has failed, bail out.
*/
- if ( finalValuePtr == NULL ) {
+ if (finalValuePtr == NULL) {
return TCL_ERROR;
}
- /* Finally, update the variable so that traces fire. */
+ /*
+ * Finally, update the variable so that traces fire.
+ */
- listPtr = Tcl_ObjSetVar2( interp, objv[1], NULL, finalValuePtr,
- TCL_LEAVE_ERR_MSG );
- Tcl_DecrRefCount( finalValuePtr );
- if ( listPtr == NULL ) {
+ listPtr = Tcl_ObjSetVar2(interp, objv[1], NULL, finalValuePtr,
+ TCL_LEAVE_ERR_MSG);
+ Tcl_DecrRefCount(finalValuePtr);
+ if (listPtr == NULL) {
return TCL_ERROR;
}
- /* Return the new value of the variable as the interpreter result. */
+ /*
+ * Return the new value of the variable as the interpreter result.
+ */
- Tcl_SetObjResult( interp, listPtr );
+ Tcl_SetObjResult(interp, listPtr);
return TCL_OK;
-
}
/*
@@ -3677,8 +3418,8 @@ Tcl_LsetObjCmd( clientData, interp, objc, objv )
*
* Tcl_LsortObjCmd --
*
- * This procedure is invoked to process the "lsort" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "lsort" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -3690,27 +3431,34 @@ Tcl_LsetObjCmd( clientData, interp, objc, objv )
*/
int
-Tcl_LsortObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument values. */
+Tcl_LsortObjCmd(
+ ClientData clientData, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument values. */
{
- int i, index, unique;
- Tcl_Obj *resultPtr;
- int length;
- Tcl_Obj *cmdPtr, **listObjPtrs;
- SortElement *elementArray;
- SortElement *elementPtr;
- SortInfo sortInfo; /* Information about this sort that
- * needs to be passed to the
- * comparison function */
+ int i, j, index, indices, length, nocase = 0, sortMode, indexc;
+ Tcl_Obj *resultPtr, *cmdPtr, **listObjPtrs, *listObj, *indexPtr;
+ SortElement *elementArray, *elementPtr;
+ SortInfo sortInfo; /* Information about this sort that needs to
+ * be passed to the comparison function. */
static CONST char *switches[] = {
"-ascii", "-command", "-decreasing", "-dictionary", "-increasing",
- "-index", "-integer", "-real", "-unique", (char *) NULL
+ "-index", "-indices", "-integer", "-nocase", "-real", "-unique", NULL
+ };
+ enum Lsort_Switches {
+ LSORT_ASCII, LSORT_COMMAND, LSORT_DECREASING, LSORT_DICTIONARY,
+ LSORT_INCREASING, LSORT_INDEX, LSORT_INDICES, LSORT_INTEGER,
+ LSORT_NOCASE, LSORT_REAL, LSORT_UNIQUE
};
- resultPtr = Tcl_GetObjResult(interp);
+ /*
+ * The subList array below holds pointers to temporary lists built during
+ * the merge sort. Element i of the array holds a list of length 2**i.
+ */
+# define NUM_LISTS 30
+ SortElement *subList[NUM_LISTS+1];
+
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "?options? list");
return TCL_ERROR;
@@ -3722,199 +3470,312 @@ Tcl_LsortObjCmd(clientData, interp, objc, objv)
sortInfo.isIncreasing = 1;
sortInfo.sortMode = SORTMODE_ASCII;
- sortInfo.index = SORTIDX_NONE;
+ sortInfo.indexv = NULL;
+ sortInfo.indexc = 0;
+ sortInfo.unique = 0;
sortInfo.interp = interp;
- sortInfo.resultCode = TCL_OK;
+ sortInfo.resultCode = TCL_OK;
cmdPtr = NULL;
- unique = 0;
+ indices = 0;
for (i = 1; i < objc-1; i++) {
- if (Tcl_GetIndexFromObj(interp, objv[i], switches, "option", 0, &index)
- != TCL_OK) {
+ if (Tcl_GetIndexFromObj(interp, objv[i], switches, "option", 0,
+ &index) != TCL_OK) {
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
return TCL_ERROR;
}
- switch (index) {
- case 0: /* -ascii */
- sortInfo.sortMode = SORTMODE_ASCII;
- break;
- case 1: /* -command */
- if (i == (objc-2)) {
- Tcl_AppendToObj(resultPtr,
- "\"-command\" option must be followed by comparison command",
- -1);
- return TCL_ERROR;
+ switch ((enum Lsort_Switches) index) {
+ case LSORT_ASCII:
+ sortInfo.sortMode = SORTMODE_ASCII;
+ break;
+ case LSORT_COMMAND:
+ if (i == (objc-2)) {
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
}
- sortInfo.sortMode = SORTMODE_COMMAND;
- cmdPtr = objv[i+1];
- i++;
- break;
- case 2: /* -decreasing */
- sortInfo.isIncreasing = 0;
- break;
- case 3: /* -dictionary */
- sortInfo.sortMode = SORTMODE_DICTIONARY;
+ Tcl_AppendResult(interp,
+ "\"-command\" option must be followed "
+ "by comparison command", NULL);
+ return TCL_ERROR;
+ }
+ sortInfo.sortMode = SORTMODE_COMMAND;
+ cmdPtr = objv[i+1];
+ i++;
+ break;
+ case LSORT_DECREASING:
+ sortInfo.isIncreasing = 0;
+ break;
+ case LSORT_DICTIONARY:
+ sortInfo.sortMode = SORTMODE_DICTIONARY;
+ break;
+ case LSORT_INCREASING:
+ sortInfo.isIncreasing = 1;
+ break;
+ case LSORT_INDEX: {
+ Tcl_Obj **indices;
+
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ if (i == (objc-2)) {
+ Tcl_AppendResult(interp, "\"-index\" option must be "
+ "followed by list index", NULL);
+ return TCL_ERROR;
+ }
+
+ /*
+ * Take copy to prevent shimmering problems.
+ */
+
+ if (TclListObjGetElements(interp, objv[i+1], &sortInfo.indexc,
+ &indices) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ switch (sortInfo.indexc) {
+ case 0:
+ sortInfo.indexv = NULL;
break;
- case 4: /* -increasing */
- sortInfo.isIncreasing = 1;
+ case 1:
+ sortInfo.indexv = &sortInfo.singleIndex;
break;
- case 5: /* -index */
- if (i == (objc-2)) {
- Tcl_AppendToObj(resultPtr,
- "\"-index\" option must be followed by list index",
- -1);
- return TCL_ERROR;
- }
- if (TclGetIntForIndex(interp, objv[i+1], SORTIDX_END,
- &sortInfo.index) != TCL_OK) {
+ default:
+ sortInfo.indexv = (int *)
+ ckalloc(sizeof(int) * sortInfo.indexc);
+ }
+
+ /*
+ * Fill the array by parsing each index. We don't know whether
+ * their scale is sensible yet, but we at least perform the
+ * syntactic check here.
+ */
+
+ for (j=0 ; j<sortInfo.indexc ; j++) {
+ if (TclGetIntForIndexM(interp, indices[j], SORTIDX_END,
+ &sortInfo.indexv[j]) != TCL_OK) {
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+ "\n (-index option item number %d)", j));
return TCL_ERROR;
}
- i++;
- break;
- case 6: /* -integer */
- sortInfo.sortMode = SORTMODE_INTEGER;
- break;
- case 7: /* -real */
- sortInfo.sortMode = SORTMODE_REAL;
- break;
- case 8: /* -unique */
- unique = 1;
- break;
+ }
+ i++;
+ break;
}
+ case LSORT_INTEGER:
+ sortInfo.sortMode = SORTMODE_INTEGER;
+ break;
+ case LSORT_NOCASE:
+ nocase = 1;
+ break;
+ case LSORT_REAL:
+ sortInfo.sortMode = SORTMODE_REAL;
+ break;
+ case LSORT_UNIQUE:
+ sortInfo.unique = 1;
+ break;
+ case LSORT_INDICES:
+ indices = 1;
+ break;
+ }
+ }
+ if (nocase && (sortInfo.sortMode == SORTMODE_ASCII)) {
+ sortInfo.sortMode = SORTMODE_ASCII_NC;
}
+
+ listObj = objv[objc-1];
+
if (sortInfo.sortMode == SORTMODE_COMMAND) {
+ Tcl_Obj *newCommandPtr, *newObjPtr;
+
/*
- * The existing command is a list. We want to flatten it, append
- * two dummy arguments on the end, and replace these arguments
- * later.
+ * When sorting using a command, we are reentrant and therefore might
+ * have the representation of the list being sorted shimmered out from
+ * underneath our feet. Take a copy (cheap) to prevent this. [Bug
+ * 1675116]
*/
- Tcl_Obj *newCommandPtr = Tcl_DuplicateObj(cmdPtr);
- Tcl_Obj *newObjPtr = Tcl_NewObj();
+ listObj = TclListObjCopy(interp, listObj);
+ if (listObj == NULL) {
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ return TCL_ERROR;
+ }
+
+ /*
+ * The existing command is a list. We want to flatten it, append two
+ * dummy arguments on the end, and replace these arguments later.
+ */
+ newCommandPtr = Tcl_DuplicateObj(cmdPtr);
+ TclNewObj(newObjPtr);
Tcl_IncrRefCount(newCommandPtr);
if (Tcl_ListObjAppendElement(interp, newCommandPtr, newObjPtr)
!= TCL_OK) {
- Tcl_DecrRefCount(newCommandPtr);
+ TclDecrRefCount(newCommandPtr);
+ TclDecrRefCount(listObj);
Tcl_IncrRefCount(newObjPtr);
- Tcl_DecrRefCount(newObjPtr);
+ TclDecrRefCount(newObjPtr);
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
return TCL_ERROR;
}
Tcl_ListObjAppendElement(interp, newCommandPtr, Tcl_NewObj());
sortInfo.compareCmdPtr = newCommandPtr;
}
- sortInfo.resultCode = Tcl_ListObjGetElements(interp, objv[objc-1],
+ sortInfo.resultCode = TclListObjGetElements(interp, listObj,
&length, &listObjPtrs);
if (sortInfo.resultCode != TCL_OK || length <= 0) {
goto done;
}
- elementArray = (SortElement *) ckalloc(length * sizeof(SortElement));
- for (i=0; i < length; i++){
- elementArray[i].objPtr = listObjPtrs[i];
- elementArray[i].count = 0;
- elementArray[i].nextPtr = &elementArray[i+1];
-
+ sortInfo.numElements = length;
+
+ indexc = sortInfo.indexc;
+ sortMode = sortInfo.sortMode;
+ if ((sortMode == SORTMODE_ASCII_NC)
+ || (sortMode == SORTMODE_DICTIONARY)) {
/*
- * When sorting using a command, we are reentrant and therefore might
- * have the representation of the list being sorted shimmered out from
- * underneath our feet. Increment the reference counts of the elements
- * to sort to prevent this. [Bug 1675116]
+ * For this function's purpose all string-based modes are equivalent
*/
+
+ sortMode = SORTMODE_ASCII;
+ }
- Tcl_IncrRefCount(elementArray[i].objPtr);
+ /*
+ * Initialize the sublists. After the following loop, subList[i] will
+ * contain a sorted sublist of length 2**i. Use one extra subList at the
+ * end, always at NULL, to indicate the end of the lists.
+ */
+
+ for (j=0 ; j<=NUM_LISTS ; j++) {
+ subList[j] = NULL;
}
- elementArray[length-1].nextPtr = NULL;
- elementPtr = MergeSort(elementArray, &sortInfo);
- if (sortInfo.resultCode == TCL_OK) {
- /*
- * Note: must clear the interpreter's result object: it could
- * have been set by the -command script.
- */
- Tcl_ResetResult(interp);
- resultPtr = Tcl_GetObjResult(interp);
- if (unique) {
- for (; elementPtr != NULL; elementPtr = elementPtr->nextPtr){
- if (elementPtr->count == 0) {
- Tcl_ListObjAppendElement(interp, resultPtr,
- elementPtr->objPtr);
- }
+ /*
+ * The following loop creates a SortElement for each list element and
+ * begins sorting it into the sublists as it appears.
+ */
+
+ elementArray = (SortElement *) ckalloc( length * sizeof(SortElement));
+
+ for (i=0; i < length; i++){
+ if (indexc) {
+ /*
+ * If this is an indexed sort, retrieve the corresponding element
+ */
+ indexPtr = SelectObjFromSublist(listObjPtrs[i], &sortInfo);
+ if (sortInfo.resultCode != TCL_OK) {
+ goto done1;
}
} else {
- for (; elementPtr != NULL; elementPtr = elementPtr->nextPtr){
- Tcl_ListObjAppendElement(interp, resultPtr,
- elementPtr->objPtr);
+ indexPtr = listObjPtrs[i];
+ }
+
+ /*
+ * Determine the "value" of this object for sorting purposes
+ */
+
+ if (sortMode == SORTMODE_ASCII) {
+ elementArray[i].index.strValuePtr = TclGetString(indexPtr);
+ } else if (sortMode == SORTMODE_INTEGER) {
+ long a;
+ if (TclGetLongFromObj(sortInfo.interp, indexPtr, &a) != TCL_OK) {
+ sortInfo.resultCode = TCL_ERROR;
+ goto done1;
+ }
+ elementArray[i].index.intValue = a;
+ } else if (sortInfo.sortMode == SORTMODE_REAL) {
+ double a;
+ if (Tcl_GetDoubleFromObj(sortInfo.interp, indexPtr, &a) != TCL_OK) {
+ sortInfo.resultCode = TCL_ERROR;
+ goto done1;
}
+ elementArray[i].index.doubleValue = a;
+ } else {
+ elementArray[i].index.objValuePtr = indexPtr;
}
- }
- for (i=0; i<length; i++) {
- Tcl_DecrRefCount(elementArray[i].objPtr);
- }
- ckfree((char*) elementArray);
- done:
- if (sortInfo.sortMode == SORTMODE_COMMAND) {
- Tcl_DecrRefCount(sortInfo.compareCmdPtr);
- sortInfo.compareCmdPtr = NULL;
+ /*
+ * Determine the representation of this element in the result: either
+ * the objPtr itself, or its index in the original list.
+ */
+
+ elementArray[i].objPtr = (indices ? INT2PTR(i) : listObjPtrs[i]);
+
+ /*
+ * Merge this element in the pre-existing sublists (and merge together
+ * sublists when we have two of the same size).
+ */
+
+ elementArray[i].nextPtr = NULL;
+ elementPtr = &elementArray[i];
+ for (j=0 ; subList[j] ; j++) {
+ elementPtr = MergeLists(subList[j], elementPtr, &sortInfo);
+ subList[j] = NULL;
+ }
+ if (j >= NUM_LISTS) {
+ j = NUM_LISTS-1;
+ }
+ subList[j] = elementPtr;
}
- return sortInfo.resultCode;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * MergeSort -
- *
- * This procedure sorts a linked list of SortElement structures
- * use the merge-sort algorithm.
- *
- * Results:
- * A pointer to the head of the list after sorting is returned.
- *
- * Side effects:
- * None, unless a user-defined comparison command does something
- * weird.
- *
- *----------------------------------------------------------------------
- */
-static SortElement *
-MergeSort(headPtr, infoPtr)
- SortElement *headPtr; /* First element on the list */
- SortInfo *infoPtr; /* Information needed by the
- * comparison operator */
-{
/*
- * The subList array below holds pointers to temporary lists built
- * during the merge sort. Element i of the array holds a list of
- * length 2**i.
+ * Merge all sublists
*/
+
+ elementPtr = subList[0];
+ for (j=1 ; j<NUM_LISTS ; j++) {
+ elementPtr = MergeLists(subList[j], elementPtr, &sortInfo);
+ }
-# define NUM_LISTS 30
- SortElement *subList[NUM_LISTS];
- SortElement *elementPtr;
- int i;
- for(i = 0; i < NUM_LISTS; i++){
- subList[i] = NULL;
- }
- while (headPtr != NULL) {
- elementPtr = headPtr;
- headPtr = headPtr->nextPtr;
- elementPtr->nextPtr = 0;
- for (i = 0; (i < NUM_LISTS) && (subList[i] != NULL); i++){
- elementPtr = MergeLists(subList[i], elementPtr, infoPtr);
- subList[i] = NULL;
- }
- if (i >= NUM_LISTS) {
- i = NUM_LISTS-1;
+ /*
+ * Now store the sorted elements in the result list.
+ */
+
+ if (sortInfo.resultCode == TCL_OK) {
+ List *listRepPtr;
+ Tcl_Obj **newArray, *objPtr;
+ int i;
+
+ resultPtr = Tcl_NewListObj(sortInfo.numElements, NULL);
+ listRepPtr = ListRepPtr(resultPtr);
+ newArray = &listRepPtr->elements;
+ if (indices) {
+ for (i = 0; elementPtr != NULL ; elementPtr = elementPtr->nextPtr){
+ objPtr = Tcl_NewIntObj(PTR2INT(elementPtr->objPtr));
+ newArray[i++] = objPtr;
+ Tcl_IncrRefCount(objPtr);
+ }
+ } else {
+ for (i = 0; elementPtr != NULL ; elementPtr = elementPtr->nextPtr){
+ objPtr = elementPtr->objPtr;
+ newArray[i++] = objPtr;
+ Tcl_IncrRefCount(objPtr);
+ }
}
- subList[i] = elementPtr;
+ listRepPtr->elemCount = i;
+ Tcl_SetObjResult(interp, resultPtr);
}
- elementPtr = NULL;
- for (i = 0; i < NUM_LISTS; i++){
- elementPtr = MergeLists(subList[i], elementPtr, infoPtr);
+
+ done1:
+ ckfree((char *)elementArray);
+
+ done:
+ if (sortInfo.sortMode == SORTMODE_COMMAND) {
+ TclDecrRefCount(sortInfo.compareCmdPtr);
+ TclDecrRefCount(listObj);
+ sortInfo.compareCmdPtr = NULL;
+ }
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
}
- return elementPtr;
+ return sortInfo.resultCode;
}
/*
@@ -3926,65 +3787,91 @@ MergeSort(headPtr, infoPtr)
* into a single sorted list.
*
* Results:
- * The unified list of SortElement structures.
+ * The unified list of SortElement structures.
*
* Side effects:
- * None, unless a user-defined comparison command does something
- * weird.
- *
+ * If infoPtr->unique is set then infoPtr->numElements may be updated.
+ * Possibly others, if a user-defined comparison command does something
+ * weird.
+ *
+ * Note:
+ * If infoPtr->unique is set, the merge assumes that there are no
+ * "repeated" elements in each of the left and right lists. In that case,
+ * if any element of the left list is equivalent to one in the right list
+ * it is omitted from the merged list.
+ * This simplified mechanism works because of the special way
+ * our MergeSort creates the sublists to be merged and will fail to
+ * eliminate all repeats in the general case where they are already
+ * present in either the left or right list. A general code would need to
+ * skip adjacent initial repeats in the left and right lists before
+ * comparing their initial elements, at each step.
*----------------------------------------------------------------------
*/
static SortElement *
-MergeLists(leftPtr, rightPtr, infoPtr)
- SortElement *leftPtr; /* First list to be merged; may be
- * NULL. */
- SortElement *rightPtr; /* Second list to be merged; may be
- * NULL. */
- SortInfo *infoPtr; /* Information needed by the
- * comparison operator. */
+MergeLists(
+ SortElement *leftPtr, /* First list to be merged; may be NULL. */
+ SortElement *rightPtr, /* Second list to be merged; may be NULL. */
+ SortInfo *infoPtr) /* Information needed by the comparison
+ * operator. */
{
- SortElement *headPtr;
- SortElement *tailPtr;
+ SortElement *headPtr, *tailPtr;
int cmp;
if (leftPtr == NULL) {
- return rightPtr;
+ return rightPtr;
}
if (rightPtr == NULL) {
- return leftPtr;
+ return leftPtr;
}
- cmp = SortCompare(leftPtr->objPtr, rightPtr->objPtr, infoPtr);
- if (cmp > 0) {
+ cmp = SortCompare(leftPtr, rightPtr, infoPtr);
+ if (cmp > 0 || (cmp == 0 && infoPtr->unique)) {
+ if (cmp == 0) {
+ infoPtr->numElements--;
+ leftPtr = leftPtr->nextPtr;
+ }
tailPtr = rightPtr;
rightPtr = rightPtr->nextPtr;
} else {
- if (cmp == 0) {
- leftPtr->count++;
- }
tailPtr = leftPtr;
leftPtr = leftPtr->nextPtr;
}
headPtr = tailPtr;
- while ((leftPtr != NULL) && (rightPtr != NULL)) {
- cmp = SortCompare(leftPtr->objPtr, rightPtr->objPtr, infoPtr);
- if (cmp > 0) {
- tailPtr->nextPtr = rightPtr;
- tailPtr = rightPtr;
- rightPtr = rightPtr->nextPtr;
- } else {
- if (cmp == 0) {
- leftPtr->count++;
+ if (!infoPtr->unique) {
+ while ((leftPtr != NULL) && (rightPtr != NULL)) {
+ cmp = SortCompare(leftPtr, rightPtr, infoPtr);
+ if (cmp > 0) {
+ tailPtr->nextPtr = rightPtr;
+ tailPtr = rightPtr;
+ rightPtr = rightPtr->nextPtr;
+ } else {
+ tailPtr->nextPtr = leftPtr;
+ tailPtr = leftPtr;
+ leftPtr = leftPtr->nextPtr;
+ }
+ }
+ } else {
+ while ((leftPtr != NULL) && (rightPtr != NULL)) {
+ cmp = SortCompare(leftPtr, rightPtr, infoPtr);
+ if (cmp >= 0) {
+ if (cmp == 0) {
+ infoPtr->numElements--;
+ leftPtr = leftPtr->nextPtr;
+ }
+ tailPtr->nextPtr = rightPtr;
+ tailPtr = rightPtr;
+ rightPtr = rightPtr->nextPtr;
+ } else {
+ tailPtr->nextPtr = leftPtr;
+ tailPtr = leftPtr;
+ leftPtr = leftPtr->nextPtr;
}
- tailPtr->nextPtr = leftPtr;
- tailPtr = leftPtr;
- leftPtr = leftPtr->nextPtr;
}
}
if (leftPtr != NULL) {
- tailPtr->nextPtr = leftPtr;
+ tailPtr->nextPtr = leftPtr;
} else {
- tailPtr->nextPtr = rightPtr;
+ tailPtr->nextPtr = rightPtr;
}
return headPtr;
}
@@ -3998,163 +3885,98 @@ MergeLists(leftPtr, rightPtr, infoPtr)
* ordering between two elements.
*
* Results:
- * A negative results means the the first element comes before the
- * second, and a positive results means that the second element
- * should come first. A result of zero means the two elements
- * are equal and it doesn't matter which comes first.
+ * A negative results means the the first element comes before the
+ * second, and a positive results means that the second element should
+ * come first. A result of zero means the two elements are equal and it
+ * doesn't matter which comes first.
*
* Side effects:
- * None, unless a user-defined comparison command does something
- * weird.
+ * None, unless a user-defined comparison command does something weird.
*
*----------------------------------------------------------------------
*/
static int
-SortCompare(objPtr1, objPtr2, infoPtr)
- Tcl_Obj *objPtr1, *objPtr2; /* Values to be compared. */
- SortInfo *infoPtr; /* Information passed from the
- * top-level "lsort" command */
+SortCompare(
+ SortElement *elemPtr1, SortElement *elemPtr2,
+ /* Values to be compared. */
+ SortInfo *infoPtr) /* Information passed from the top-level
+ * "lsort" command. */
{
- int order, listLen, index;
- Tcl_Obj *objPtr;
- char buffer[TCL_INTEGER_SPACE];
-
- order = 0;
- if (infoPtr->resultCode != TCL_OK) {
- /*
- * Once an error has occurred, skip any future comparisons
- * so as to preserve the error message in sortInterp->result.
- */
-
- return order;
- }
- if (infoPtr->index != SORTIDX_NONE) {
- /*
- * The "-index" option was specified. Treat each object as a
- * list, extract the requested element from each list, and
- * compare the elements, not the lists. "end"-relative indices
- * are signaled here with large negative values.
- */
-
- if (Tcl_ListObjLength(infoPtr->interp, objPtr1, &listLen) != TCL_OK) {
- infoPtr->resultCode = TCL_ERROR;
- return order;
- }
- if (infoPtr->index < SORTIDX_NONE) {
- index = listLen + infoPtr->index + 1;
- } else {
- index = infoPtr->index;
- }
+ int order = 0;
- if (Tcl_ListObjIndex(infoPtr->interp, objPtr1, index, &objPtr)
- != TCL_OK) {
- infoPtr->resultCode = TCL_ERROR;
- return order;
- }
- if (objPtr == NULL) {
- objPtr = objPtr1;
- missingElement:
- TclFormatInt(buffer, infoPtr->index);
- Tcl_AppendStringsToObj(Tcl_GetObjResult(infoPtr->interp),
- "element ", buffer, " missing from sublist \"",
- Tcl_GetString(objPtr), "\"", (char *) NULL);
- infoPtr->resultCode = TCL_ERROR;
- return order;
- }
- objPtr1 = objPtr;
-
- if (Tcl_ListObjLength(infoPtr->interp, objPtr2, &listLen) != TCL_OK) {
- infoPtr->resultCode = TCL_ERROR;
- return order;
- }
- if (infoPtr->index < SORTIDX_NONE) {
- index = listLen + infoPtr->index + 1;
- } else {
- index = infoPtr->index;
- }
-
- if (Tcl_ListObjIndex(infoPtr->interp, objPtr2, index, &objPtr)
- != TCL_OK) {
- infoPtr->resultCode = TCL_ERROR;
- return order;
- }
- if (objPtr == NULL) {
- objPtr = objPtr2;
- goto missingElement;
- }
- objPtr2 = objPtr;
- }
if (infoPtr->sortMode == SORTMODE_ASCII) {
- order = strcmp(Tcl_GetString(objPtr1), Tcl_GetString(objPtr2));
+ order = strcmp(elemPtr1->index.strValuePtr,
+ elemPtr2->index.strValuePtr);
+ } else if (infoPtr->sortMode == SORTMODE_ASCII_NC) {
+ order = strcasecmp(elemPtr1->index.strValuePtr,
+ elemPtr2->index.strValuePtr);
} else if (infoPtr->sortMode == SORTMODE_DICTIONARY) {
- order = DictionaryCompare(
- Tcl_GetString(objPtr1), Tcl_GetString(objPtr2));
+ order = DictionaryCompare(elemPtr1->index.strValuePtr,
+ elemPtr2->index.strValuePtr);
} else if (infoPtr->sortMode == SORTMODE_INTEGER) {
long a, b;
- if ((Tcl_GetLongFromObj(infoPtr->interp, objPtr1, &a) != TCL_OK)
- || (Tcl_GetLongFromObj(infoPtr->interp, objPtr2, &b)
- != TCL_OK)) {
- infoPtr->resultCode = TCL_ERROR;
- return order;
- }
- if (a > b) {
- order = 1;
- } else if (b > a) {
- order = -1;
- }
+ a = elemPtr1->index.intValue;
+ b = elemPtr2->index.intValue;
+ order = ((a >= b) - (a <= b));
} else if (infoPtr->sortMode == SORTMODE_REAL) {
double a, b;
- if ((Tcl_GetDoubleFromObj(infoPtr->interp, objPtr1, &a) != TCL_OK)
- || (Tcl_GetDoubleFromObj(infoPtr->interp, objPtr2, &b)
- != TCL_OK)) {
- infoPtr->resultCode = TCL_ERROR;
- return order;
- }
- if (a > b) {
- order = 1;
- } else if (b > a) {
- order = -1;
- }
+ a = elemPtr1->index.doubleValue;
+ b = elemPtr2->index.doubleValue;
+ order = ((a >= b) - (a <= b));
} else {
Tcl_Obj **objv, *paramObjv[2];
int objc;
+ Tcl_Obj *objPtr1, *objPtr2;
+
+ if (infoPtr->resultCode != TCL_OK) {
+ /*
+ * Once an error has occurred, skip any future comparisons so as
+ * to preserve the error message in sortInterp->result.
+ */
+
+ return 0;
+ }
+
+ objPtr1 = elemPtr1->index.objValuePtr;
+ objPtr2 = elemPtr2->index.objValuePtr;
+
paramObjv[0] = objPtr1;
paramObjv[1] = objPtr2;
- /*
- * We made space in the command list for the two things to
- * compare. Replace them and evaluate the result.
+ /*
+ * We made space in the command list for the two things to compare.
+ * Replace them and evaluate the result.
*/
- Tcl_ListObjLength(infoPtr->interp, infoPtr->compareCmdPtr, &objc);
+ TclListObjLength(infoPtr->interp, infoPtr->compareCmdPtr, &objc);
Tcl_ListObjReplace(infoPtr->interp, infoPtr->compareCmdPtr, objc - 2,
2, 2, paramObjv);
- Tcl_ListObjGetElements(infoPtr->interp, infoPtr->compareCmdPtr,
+ TclListObjGetElements(infoPtr->interp, infoPtr->compareCmdPtr,
&objc, &objv);
infoPtr->resultCode = Tcl_EvalObjv(infoPtr->interp, objc, objv, 0);
-
- if (infoPtr->resultCode != TCL_OK) {
+
+ if (infoPtr->resultCode != TCL_OK) {
Tcl_AddErrorInfo(infoPtr->interp,
"\n (-compare command)");
- return order;
+ return 0;
}
/*
* Parse the result of the command.
*/
- if (Tcl_GetIntFromObj(infoPtr->interp,
+ if (TclGetIntFromObj(infoPtr->interp,
Tcl_GetObjResult(infoPtr->interp), &order) != TCL_OK) {
Tcl_ResetResult(infoPtr->interp);
- Tcl_AppendToObj(Tcl_GetObjResult(infoPtr->interp),
- "-compare command returned non-integer result", -1);
+ Tcl_AppendResult(infoPtr->interp,
+ "-compare command returned non-integer result", NULL);
infoPtr->resultCode = TCL_ERROR;
- return order;
+ return 0;
}
}
if (!infoPtr->isIncreasing) {
@@ -4168,18 +3990,18 @@ SortCompare(objPtr1, objPtr2, infoPtr)
*
* DictionaryCompare
*
- * This function compares two strings as if they were being used in
- * an index or card catalog. The case of alphabetic characters is
- * ignored, except to break ties. Thus "B" comes before "b" but
- * after "a". Also, integers embedded in the strings compare in
- * numerical order. In other words, "x10y" comes after "x9y", not
- * before it as it would when using strcmp().
+ * This function compares two strings as if they were being used in an
+ * index or card catalog. The case of alphabetic characters is ignored,
+ * except to break ties. Thus "B" comes before "b" but after "a". Also,
+ * integers embedded in the strings compare in numerical order. In other
+ * words, "x10y" comes after "x9y", not * before it as it would when
+ * using strcmp().
*
* Results:
- * A negative result means that the first element comes before the
- * second, and a positive result means that the second element
- * should come first. A result of zero means the two elements
- * are equal and it doesn't matter which comes first.
+ * A negative result means that the first element comes before the
+ * second, and a positive result means that the second element should
+ * come first. A result of zero means the two elements are equal and it
+ * doesn't matter which comes first.
*
* Side effects:
* None.
@@ -4188,22 +4010,21 @@ SortCompare(objPtr1, objPtr2, infoPtr)
*/
static int
-DictionaryCompare(left, right)
- char *left, *right; /* The strings to compare */
+DictionaryCompare(
+ char *left, char *right) /* The strings to compare. */
{
Tcl_UniChar uniLeft, uniRight, uniLeftLower, uniRightLower;
int diff, zeros;
int secondaryDiff = 0;
while (1) {
- if (isdigit(UCHAR(*right)) /* INTL: digit */
- && isdigit(UCHAR(*left))) { /* INTL: digit */
+ if (isdigit(UCHAR(*right)) /* INTL: digit */
+ && isdigit(UCHAR(*left))) { /* INTL: digit */
/*
- * There are decimal numbers embedded in the two
- * strings. Compare them as numbers, rather than
- * strings. If one number has more leading zeros than
- * the other, the number with more leading zeros sorts
- * later, but only as a secondary choice.
+ * There are decimal numbers embedded in the two strings. Compare
+ * them as numbers, rather than strings. If one number has more
+ * leading zeros than the other, the number with more leading
+ * zeros sorts later, but only as a secondary choice.
*/
zeros = 0;
@@ -4220,10 +4041,10 @@ DictionaryCompare(left, right)
}
/*
- * The code below compares the numbers in the two
- * strings without ever converting them to integers. It
- * does this by first comparing the lengths of the
- * numbers and then comparing the digit values.
+ * The code below compares the numbers in the two strings without
+ * ever converting them to integers. It does this by first
+ * comparing the lengths of the numbers and then comparing the
+ * digit values.
*/
diff = 0;
@@ -4233,13 +4054,13 @@ DictionaryCompare(left, right)
}
right++;
left++;
- if (!isdigit(UCHAR(*right))) { /* INTL: digit */
- if (isdigit(UCHAR(*left))) { /* INTL: digit */
+ if (!isdigit(UCHAR(*right))) { /* INTL: digit */
+ if (isdigit(UCHAR(*left))) { /* INTL: digit */
return 1;
} else {
/*
- * The two numbers have the same length. See
- * if their values are different.
+ * The two numbers have the same length. See if their
+ * values are different.
*/
if (diff != 0) {
@@ -4247,7 +4068,7 @@ DictionaryCompare(left, right)
}
break;
}
- } else if (!isdigit(UCHAR(*left))) { /* INTL: digit */
+ } else if (!isdigit(UCHAR(*left))) { /* INTL: digit */
return -1;
}
}
@@ -4255,7 +4076,7 @@ DictionaryCompare(left, right)
}
/*
- * Convert character to Unicode for comparison purposes. If either
+ * Convert character to Unicode for comparison purposes. If either
* string is at the terminating null, do a byte-wise comparison and
* bail out immediately.
*/
@@ -4263,12 +4084,14 @@ DictionaryCompare(left, right)
if ((*left != '\0') && (*right != '\0')) {
left += Tcl_UtfToUniChar(left, &uniLeft);
right += Tcl_UtfToUniChar(right, &uniRight);
+
/*
* Convert both chars to lower for the comparison, because
- * dictionary sorts are case insensitve. Covert to lower, not
+ * dictionary sorts are case insensitve. Covert to lower, not
* upper, so chars between Z and a will sort before A (where most
- * other interesting punctuations occur)
+ * other interesting punctuations occur).
*/
+
uniLeftLower = Tcl_UniCharToLower(uniLeft);
uniRightLower = Tcl_UniCharToLower(uniRight);
} else {
@@ -4276,18 +4099,18 @@ DictionaryCompare(left, right)
break;
}
- diff = uniLeftLower - uniRightLower;
- if (diff) {
+ diff = uniLeftLower - uniRightLower;
+ if (diff) {
return diff;
- } else if (secondaryDiff == 0) {
- if (Tcl_UniCharIsUpper(uniLeft) &&
- Tcl_UniCharIsLower(uniRight)) {
+ }
+ if (secondaryDiff == 0) {
+ if (Tcl_UniCharIsUpper(uniLeft) && Tcl_UniCharIsLower(uniRight)) {
secondaryDiff = -1;
} else if (Tcl_UniCharIsUpper(uniRight)
&& Tcl_UniCharIsLower(uniLeft)) {
secondaryDiff = 1;
}
- }
+ }
}
if (diff == 0) {
diff = secondaryDiff;
@@ -4296,10 +4119,90 @@ DictionaryCompare(left, right)
}
/*
+ *----------------------------------------------------------------------
+ *
+ * SelectObjFromSublist --
+ *
+ * This procedure is invoked from lsearch and SortCompare. It is used for
+ * implementing the -index option, for the lsort and lsearch commands.
+ *
+ * Results:
+ * Returns NULL if a failure occurs, and sets the result in the infoPtr.
+ * Otherwise returns the Tcl_Obj* to the item.
+ *
+ * Side effects:
+ * None.
+ *
+ * Note:
+ * No reference counting is done, as the result is only used internally
+ * and never passed directly to user code.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+SelectObjFromSublist(
+ Tcl_Obj *objPtr, /* Obj to select sublist from. */
+ SortInfo *infoPtr) /* Information passed from the top-level
+ * "lsearch" or "lsort" command. */
+{
+ int i;
+
+ /*
+ * Quick check for case when no "-index" option is there.
+ */
+
+ if (infoPtr->indexc == 0) {
+ return objPtr;
+ }
+
+ /*
+ * Iterate over the indices, traversing through the nested sublists as we
+ * go.
+ */
+
+ for (i=0 ; i<infoPtr->indexc ; i++) {
+ int listLen, index;
+ Tcl_Obj *currentObj;
+
+ if (TclListObjLength(infoPtr->interp, objPtr, &listLen) != TCL_OK) {
+ infoPtr->resultCode = TCL_ERROR;
+ return NULL;
+ }
+ index = infoPtr->indexv[i];
+
+ /*
+ * Adjust for end-based indexing.
+ */
+
+ if (index < SORTIDX_NONE) {
+ index += listLen + 1;
+ }
+
+ if (Tcl_ListObjIndex(infoPtr->interp, objPtr, index,
+ &currentObj) != TCL_OK) {
+ infoPtr->resultCode = TCL_ERROR;
+ return NULL;
+ }
+ if (currentObj == NULL) {
+ char buffer[TCL_INTEGER_SPACE];
+
+ TclFormatInt(buffer, index);
+ Tcl_AppendResult(infoPtr->interp, "element ", buffer,
+ " missing from sublist \"", TclGetString(objPtr), "\"",
+ NULL);
+ infoPtr->resultCode = TCL_ERROR;
+ return NULL;
+ }
+ objPtr = currentObj;
+ }
+ return objPtr;
+}
+
+/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/
-
diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c
index fb15062..aed0022 100644
--- a/generic/tclCmdMZ.c
+++ b/generic/tclCmdMZ.c
@@ -1,153 +1,34 @@
-/*
+/*
* tclCmdMZ.c --
*
- * This file contains the top-level command routines for most of
- * the Tcl built-in commands whose names begin with the letters
- * M to Z. It contains only commands in the generic core (i.e.
- * those that don't depend much upon UNIX facilities).
+ * This file contains the top-level command routines for most of the Tcl
+ * built-in commands whose names begin with the letters M to Z. It
+ * contains only commands in the generic core (i.e. those that don't
+ * depend much upon UNIX facilities).
*
* 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 Donal K. Fellows.
*
- * 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.
*/
#include "tclInt.h"
-#include "tclPort.h"
#include "tclRegexp.h"
-#include "tclCompile.h"
-
-/*
- * Structures used to hold information about variable traces:
- */
-
-typedef struct {
- int flags; /* Operations for which Tcl command is
- * to be invoked. */
- size_t length; /* Number of non-NULL chars. in command. */
- char command[4]; /* Space for Tcl command to invoke. Actual
- * size will be as large as necessary to
- * hold command. This field must be the
- * last in the structure, so that it can
- * be larger than 4 bytes. */
-} TraceVarInfo;
-
-typedef struct {
- VarTrace trace;
- TraceVarInfo tvar;
-} CompoundVarTrace;
-
-/*
- * Structure used to hold information about command traces:
- */
-
-typedef struct {
- int flags; /* Operations for which Tcl command is
- * to be invoked. */
- size_t length; /* Number of non-NULL chars. in command. */
- Tcl_Trace stepTrace; /* Used for execution traces, when tracing
- * inside the given command */
- int startLevel; /* Used for bookkeeping with step execution
- * traces, store the level at which the step
- * trace was invoked */
- char *startCmd; /* Used for bookkeeping with step execution
- * traces, store the command name which invoked
- * step trace */
- int curFlags; /* Trace flags for the current command */
- int curCode; /* Return code for the current command */
- int refCount; /* Used to ensure this structure is
- * not deleted too early. Keeps track
- * of how many pieces of code have
- * a pointer to this structure. */
- char command[4]; /* Space for Tcl command to invoke. Actual
- * size will be as large as necessary to
- * hold command. This field must be the
- * last in the structure, so that it can
- * be larger than 4 bytes. */
-} TraceCommandInfo;
-
-/*
- * Used by command execution traces. Note that we assume in the code
- * that the first two defines are exactly 4 times the
- * 'TCL_TRACE_ENTER_EXEC' and 'TCL_TRACE_LEAVE_EXEC' constants.
- *
- * TCL_TRACE_ENTER_DURING_EXEC - Trace each command inside the command
- * currently being traced, before execution.
- * TCL_TRACE_LEAVE_DURING_EXEC - Trace each command inside the command
- * currently being traced, after execution.
- * TCL_TRACE_ANY_EXEC - OR'd combination of all EXEC flags.
- * TCL_TRACE_EXEC_IN_PROGRESS - The callback procedure on this trace
- * is currently executing. Therefore we
- * don't let further traces execute.
- * TCL_TRACE_EXEC_DIRECT - This execution trace is triggered directly
- * by the command being traced, not because
- * of an internal trace.
- * The flags 'TCL_TRACE_DESTROYED' and 'TCL_INTERP_DESTROYED' may also
- * be used in command execution traces.
- */
-#define TCL_TRACE_ENTER_DURING_EXEC 4
-#define TCL_TRACE_LEAVE_DURING_EXEC 8
-#define TCL_TRACE_ANY_EXEC 15
-#define TCL_TRACE_EXEC_IN_PROGRESS 0x10
-#define TCL_TRACE_EXEC_DIRECT 0x20
-
-/*
- * Forward declarations for procedures defined in this file:
- */
-
-typedef int (Tcl_TraceTypeObjCmd) _ANSI_ARGS_((Tcl_Interp *interp,
- int optionIndex, int objc, Tcl_Obj *CONST objv[]));
-
-Tcl_TraceTypeObjCmd TclTraceVariableObjCmd;
-Tcl_TraceTypeObjCmd TclTraceCommandObjCmd;
-Tcl_TraceTypeObjCmd TclTraceExecutionObjCmd;
-/*
- * Each subcommand has a number of 'types' to which it can apply.
- * Currently 'execution', 'command' and 'variable' are the only
- * types supported. These three arrays MUST be kept in sync!
- * In the future we may provide an API to add to the list of
- * supported trace types.
- */
-static CONST char *traceTypeOptions[] = {
- "execution", "command", "variable", (char*) NULL
-};
-static Tcl_TraceTypeObjCmd* traceSubCmds[] = {
- TclTraceExecutionObjCmd,
- TclTraceCommandObjCmd,
- TclTraceVariableObjCmd,
-};
-
-/*
- * Declarations for local procedures to this file:
- */
-static int CallTraceProcedure _ANSI_ARGS_((Tcl_Interp *interp,
- Trace *tracePtr, Command *cmdPtr,
- CONST char *command, int numChars,
- int objc, Tcl_Obj *CONST objv[]));
-static char * TraceVarProc _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, CONST char *name1,
- CONST char *name2, int flags));
-static void TraceCommandProc _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, CONST char *oldName,
- CONST char *newName, int flags));
-static Tcl_CmdObjTraceProc TraceExecutionProc;
-
-#ifdef TCL_TIP280
-static void ListLines _ANSI_ARGS_((Tcl_Obj* listObj, int line,
- int n, int* lines,
- Tcl_Obj* const* elems));
-#endif
+static int UniCharIsAscii(int character);
+static int UniCharIsHexDigit(int character);
+
/*
*----------------------------------------------------------------------
*
* Tcl_PwdObjCmd --
*
- * This procedure is invoked to process the "pwd" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "pwd" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -158,13 +39,12 @@ static void ListLines _ANSI_ARGS_((Tcl_Obj* listObj, int line,
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
int
-Tcl_PwdObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_PwdObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Tcl_Obj *retVal;
@@ -187,8 +67,8 @@ Tcl_PwdObjCmd(dummy, interp, objc, objv)
*
* Tcl_RegexpObjCmd --
*
- * This procedure is invoked to process the "regexp" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "regexp" Tcl command. See
+ * the user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -199,23 +79,22 @@ Tcl_PwdObjCmd(dummy, interp, objc, objv)
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
int
-Tcl_RegexpObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_RegexpObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
int i, indices, match, about, offset, all, doinline, numMatchesSaved;
- int cflags, eflags, stringLength;
+ int cflags, eflags, stringLength, matchLength;
Tcl_RegExp regExpr;
- Tcl_Obj *objPtr, *resultPtr;
+ Tcl_Obj *objPtr, *startIndex = NULL, *resultPtr = NULL;
Tcl_RegExpInfo info;
static CONST char *options[] = {
"-all", "-about", "-indices", "-inline",
"-expanded", "-line", "-linestop", "-lineanchor",
- "-nocase", "-start", "--", (char *) NULL
+ "-nocase", "-start", "--", NULL
};
enum options {
REGEXP_ALL, REGEXP_ABOUT, REGEXP_INDICES, REGEXP_INLINE,
@@ -223,165 +102,180 @@ Tcl_RegexpObjCmd(dummy, interp, objc, objv)
REGEXP_NOCASE, REGEXP_START, REGEXP_LAST
};
- indices = 0;
- about = 0;
- cflags = TCL_REG_ADVANCED;
- eflags = 0;
- offset = 0;
- all = 0;
- doinline = 0;
-
+ indices = 0;
+ about = 0;
+ cflags = TCL_REG_ADVANCED;
+ eflags = 0;
+ offset = 0;
+ all = 0;
+ doinline = 0;
+
for (i = 1; i < objc; i++) {
char *name;
int index;
- name = Tcl_GetString(objv[i]);
+ name = TclGetString(objv[i]);
if (name[0] != '-') {
break;
}
if (Tcl_GetIndexFromObj(interp, objv[i], options, "switch", TCL_EXACT,
&index) != TCL_OK) {
- return TCL_ERROR;
+ goto optionError;
}
switch ((enum options) index) {
- case REGEXP_ALL: {
- all = 1;
- break;
- }
- case REGEXP_INDICES: {
- indices = 1;
- break;
- }
- case REGEXP_INLINE: {
- doinline = 1;
- break;
- }
- case REGEXP_NOCASE: {
- cflags |= TCL_REG_NOCASE;
- break;
- }
- case REGEXP_ABOUT: {
- about = 1;
- break;
- }
- case REGEXP_EXPANDED: {
- cflags |= TCL_REG_EXPANDED;
- break;
- }
- case REGEXP_LINE: {
- cflags |= TCL_REG_NEWLINE;
- break;
- }
- case REGEXP_LINESTOP: {
- cflags |= TCL_REG_NLSTOP;
- break;
+ case REGEXP_ALL:
+ all = 1;
+ break;
+ case REGEXP_INDICES:
+ indices = 1;
+ break;
+ case REGEXP_INLINE:
+ doinline = 1;
+ break;
+ case REGEXP_NOCASE:
+ cflags |= TCL_REG_NOCASE;
+ break;
+ case REGEXP_ABOUT:
+ about = 1;
+ break;
+ case REGEXP_EXPANDED:
+ cflags |= TCL_REG_EXPANDED;
+ break;
+ case REGEXP_LINE:
+ cflags |= TCL_REG_NEWLINE;
+ break;
+ case REGEXP_LINESTOP:
+ cflags |= TCL_REG_NLSTOP;
+ break;
+ case REGEXP_LINEANCHOR:
+ cflags |= TCL_REG_NLANCH;
+ break;
+ case REGEXP_START: {
+ int temp;
+ if (++i >= objc) {
+ goto endOfForLoop;
}
- case REGEXP_LINEANCHOR: {
- cflags |= TCL_REG_NLANCH;
- break;
+ if (TclGetIntForIndexM(interp, objv[i], 0, &temp) != TCL_OK) {
+ goto optionError;
}
- case REGEXP_START: {
- if (++i >= objc) {
- goto endOfForLoop;
- }
- if (Tcl_GetIntFromObj(interp, objv[i], &offset) != TCL_OK) {
- return TCL_ERROR;
- }
- if (offset < 0) {
- offset = 0;
- }
- break;
- }
- case REGEXP_LAST: {
- i++;
- goto endOfForLoop;
+ if (startIndex) {
+ Tcl_DecrRefCount(startIndex);
}
+ startIndex = objv[i];
+ Tcl_IncrRefCount(startIndex);
+ break;
+ }
+ case REGEXP_LAST:
+ i++;
+ goto endOfForLoop;
}
}
- endOfForLoop:
+ endOfForLoop:
if ((objc - i) < (2 - about)) {
- Tcl_WrongNumArgs(interp, 1, objv,
- "?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?");
- return TCL_ERROR;
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?");
+ goto optionError;
}
objc -= i;
objv += i;
+ /*
+ * Check if the user requested -inline, but specified match variables; a
+ * no-no.
+ */
+
if (doinline && ((objc - 2) != 0)) {
- /*
- * User requested -inline, but specified match variables - a no-no.
- */
- Tcl_AppendResult(interp, "regexp match variables not allowed",
- " when using -inline", (char *) NULL);
- return TCL_ERROR;
+ Tcl_AppendResult(interp, "regexp match variables not allowed"
+ " when using -inline", NULL);
+ goto optionError;
}
/*
* Handle the odd about case separately.
*/
+
if (about) {
regExpr = Tcl_GetRegExpFromObj(interp, objv[0], cflags);
if ((regExpr == NULL) || (TclRegAbout(interp, regExpr) < 0)) {
+ optionError:
+ if (startIndex) {
+ Tcl_DecrRefCount(startIndex);
+ }
return TCL_ERROR;
}
return TCL_OK;
}
/*
- * Get the length of the string that we are matching against so
- * we can do the termination test for -all matches. Do this before
- * getting the regexp to avoid shimmering problems.
+ * Get the length of the string that we are matching against so we can do
+ * the termination test for -all matches. Do this before getting the
+ * regexp to avoid shimmering problems.
*/
+
objPtr = objv[1];
stringLength = Tcl_GetCharLength(objPtr);
+ if (startIndex) {
+ TclGetIntForIndexM(NULL, startIndex, stringLength, &offset);
+ Tcl_DecrRefCount(startIndex);
+ if (offset < 0) {
+ offset = 0;
+ }
+ }
+
regExpr = Tcl_GetRegExpFromObj(interp, objv[0], cflags);
if (regExpr == NULL) {
return TCL_ERROR;
}
- if (offset > 0) {
- /*
- * Add flag if using offset (string is part of a larger string),
- * so that "^" won't match.
- */
- eflags |= TCL_REG_NOTBOL;
- }
-
objc -= 2;
objv += 2;
- resultPtr = Tcl_GetObjResult(interp);
if (doinline) {
/*
* Save all the subexpressions, as we will return them as a list
*/
+
numMatchesSaved = -1;
} else {
/*
- * Save only enough subexpressions for matches we want to keep,
- * expect in the case of -all, where we need to keep at least
- * one to know where to move the offset.
+ * Save only enough subexpressions for matches we want to keep, expect
+ * in the case of -all, where we need to keep at least one to know
+ * where to move the offset.
*/
+
numMatchesSaved = (objc == 0) ? all : objc;
}
/*
- * The following loop is to handle multiple matches within the
- * same source string; each iteration handles one match. If "-all"
- * hasn't been specified then the loop body only gets executed once.
- * We terminate the loop when the starting offset is past the end of the
- * string.
+ * The following loop is to handle multiple matches within the same source
+ * string; each iteration handles one match. If "-all" hasn't been
+ * specified then the loop body only gets executed once. We terminate the
+ * loop when the starting offset is past the end of the string.
*/
while (1) {
- match = Tcl_RegExpExecObj(interp, regExpr, objPtr,
- offset /* offset */, numMatchesSaved, eflags
- | ((offset > 0 && offset < stringLength &&
- (Tcl_GetUniChar(objPtr,offset-1) != (Tcl_UniChar)'\n'))
- ? TCL_REG_NOTBOL : 0));
+ /*
+ * Pass either 0 or TCL_REG_NOTBOL in the eflags. Passing
+ * TCL_REG_NOTBOL indicates that the character at offset should not be
+ * considered the start of the line. If for example the pattern {^} is
+ * passed and -start is positive, then the pattern will not match the
+ * start of the string unless the previous character is a newline.
+ */
+ 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;
+ }
+
+ match = Tcl_RegExpExecObj(interp, regExpr, objPtr, offset,
+ numMatchesSaved, eflags);
if (match < 0) {
return TCL_ERROR;
}
@@ -391,16 +285,16 @@ Tcl_RegexpObjCmd(dummy, interp, objc, objv)
* We want to set the value of the intepreter result only when
* this is the first time through the loop.
*/
+
if (all <= 1) {
/*
- * If inlining, set the interpreter's object result to an
- * empty list, otherwise set it to an integer object w/
- * value 0.
+ * If inlining, the interpreter's object result remains an
+ * empty list, otherwise set it to an integer object w/ value
+ * 0.
*/
- if (doinline) {
- Tcl_SetListObj(resultPtr, 0, NULL);
- } else {
- Tcl_SetIntObj(resultPtr, 0);
+
+ if (!doinline) {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
}
return TCL_OK;
}
@@ -408,17 +302,21 @@ Tcl_RegexpObjCmd(dummy, interp, objc, objv)
}
/*
- * If additional variable names have been specified, return
- * index information in those variables.
+ * If additional variable names have been specified, return index
+ * information in those variables.
*/
Tcl_RegExpGetInfo(regExpr, &info);
if (doinline) {
/*
- * It's the number of substitutions, plus one for the matchVar
- * at index 0
+ * It's the number of substitutions, plus one for the matchVar at
+ * index 0
*/
+
objc = info.nsubs + 1;
+ if (all <= 1) {
+ resultPtr = Tcl_NewObj();
+ }
}
for (i = 0; i < objc; i++) {
Tcl_Obj *newPtr;
@@ -428,12 +326,13 @@ Tcl_RegexpObjCmd(dummy, interp, objc, objv)
Tcl_Obj *objs[2];
/*
- * Only adjust the match area if there was a match for
- * that area. (Scriptics Bug 4391/SF Bug #219232)
+ * Only adjust the match area if there was a match for that
+ * area. (Scriptics Bug 4391/SF Bug #219232)
*/
+
if (i <= info.nsubs && info.matches[i].start >= 0) {
start = offset + info.matches[i].start;
- end = offset + info.matches[i].end;
+ end = offset + info.matches[i].end;
/*
* Adjust index so it refers to the last character in the
@@ -445,7 +344,7 @@ Tcl_RegexpObjCmd(dummy, interp, objc, objv)
}
} else {
start = -1;
- end = -1;
+ end = -1;
}
objs[0] = Tcl_NewLongObj(start);
@@ -465,6 +364,7 @@ Tcl_RegexpObjCmd(dummy, interp, objc, objv)
if (Tcl_ListObjAppendElement(interp, resultPtr, newPtr)
!= TCL_OK) {
Tcl_DecrRefCount(newPtr);
+ Tcl_DecrRefCount(resultPtr);
return TCL_ERROR;
}
} else {
@@ -472,8 +372,7 @@ Tcl_RegexpObjCmd(dummy, interp, objc, objv)
valuePtr = Tcl_ObjSetVar2(interp, objv[i], NULL, newPtr, 0);
if (valuePtr == NULL) {
Tcl_AppendResult(interp, "couldn't set variable \"",
- Tcl_GetString(objv[i]), "\"", (char *) NULL);
- Tcl_DecrRefCount(newPtr);
+ TclGetString(objv[i]), "\"", NULL);
return TCL_ERROR;
}
}
@@ -482,37 +381,44 @@ Tcl_RegexpObjCmd(dummy, interp, objc, objv)
if (all == 0) {
break;
}
+
/*
- * Adjust the offset to the character just after the last one
- * in the matchVar and increment all to count how many times
- * we are making a match. We always increment the offset by at least
- * one to prevent endless looping (as in the case:
- * regexp -all {a*} a). Otherwise, when we match the NULL string at
- * the end of the input string, we will loop indefinately (because the
- * length of the match is 0, so offset never changes).
+ * Adjust the offset to the character just after the last one in the
+ * matchVar and increment all to count how many times we are making a
+ * match. We always increment the offset by at least one to prevent
+ * endless looping (as in the case: regexp -all {a*} a). Otherwise,
+ * when we match the NULL string at the end of the input string, we
+ * will loop indefinately (because the length of the match is 0, so
+ * offset never changes).
*/
- if (info.matches[0].end == 0) {
+
+ matchLength = info.matches[0].end - info.matches[0].start;
+ offset += info.matches[0].end;
+
+ /*
+ * A match of length zero could happen for {^} {$} or {.*} and in
+ * these cases we always want to bump the index up one.
+ */
+
+ if (matchLength == 0) {
offset++;
}
- offset += info.matches[0].end;
all++;
- eflags |= TCL_REG_NOTBOL;
if (offset >= stringLength) {
break;
}
}
/*
- * Set the interpreter's object result to an integer object
- * with value 1 if -all wasn't specified, otherwise it's all-1
- * (the number of times through the while - 1).
- * Get the resultPtr again as the Tcl_ObjSetVar2 above may have
- * cause the result to change. [Patch #558324] (watson).
+ * Set the interpreter's object result to an integer object with value 1
+ * if -all wasn't specified, otherwise it's all-1 (the number of times
+ * through the while - 1).
*/
- if (!doinline) {
- resultPtr = Tcl_GetObjResult(interp);
- Tcl_SetIntObj(resultPtr, (all ? all-1 : 1));
+ if (doinline) {
+ Tcl_SetObjResult(interp, resultPtr);
+ } else {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(all ? all-1 : 1));
}
return TCL_OK;
}
@@ -522,8 +428,8 @@ Tcl_RegexpObjCmd(dummy, interp, objc, objv)
*
* Tcl_RegsubObjCmd --
*
- * This procedure is invoked to process the "regsub" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "regsub" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -534,19 +440,18 @@ Tcl_RegexpObjCmd(dummy, interp, objc, objv)
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
int
-Tcl_RegsubObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_RegsubObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
int idx, result, cflags, all, wlen, wsublen, numMatches, offset;
int start, end, subStart, subEnd, match;
Tcl_RegExp regExpr;
Tcl_RegExpInfo info;
- Tcl_Obj *resultPtr, *subPtr, *objPtr;
+ Tcl_Obj *resultPtr, *subPtr, *objPtr, *startIndex = NULL;
Tcl_UniChar ch, *wsrc, *wfirstChar, *wstring, *wsubspec, *wend;
static CONST char *options[] = {
@@ -568,95 +473,107 @@ Tcl_RegsubObjCmd(dummy, interp, objc, objv)
for (idx = 1; idx < objc; idx++) {
char *name;
int index;
-
- name = Tcl_GetString(objv[idx]);
+
+ name = TclGetString(objv[idx]);
if (name[0] != '-') {
break;
}
if (Tcl_GetIndexFromObj(interp, objv[idx], options, "switch",
TCL_EXACT, &index) != TCL_OK) {
- return TCL_ERROR;
+ goto optionError;
}
switch ((enum options) index) {
- case REGSUB_ALL: {
- all = 1;
- break;
- }
- case REGSUB_NOCASE: {
- cflags |= TCL_REG_NOCASE;
- break;
- }
- case REGSUB_EXPANDED: {
- cflags |= TCL_REG_EXPANDED;
- break;
- }
- case REGSUB_LINE: {
- cflags |= TCL_REG_NEWLINE;
- break;
- }
- case REGSUB_LINESTOP: {
- cflags |= TCL_REG_NLSTOP;
- break;
- }
- case REGSUB_LINEANCHOR: {
- cflags |= TCL_REG_NLANCH;
- break;
+ case REGSUB_ALL:
+ all = 1;
+ break;
+ case REGSUB_NOCASE:
+ cflags |= TCL_REG_NOCASE;
+ break;
+ case REGSUB_EXPANDED:
+ cflags |= TCL_REG_EXPANDED;
+ break;
+ case REGSUB_LINE:
+ cflags |= TCL_REG_NEWLINE;
+ break;
+ case REGSUB_LINESTOP:
+ cflags |= TCL_REG_NLSTOP;
+ break;
+ case REGSUB_LINEANCHOR:
+ cflags |= TCL_REG_NLANCH;
+ break;
+ case REGSUB_START: {
+ int temp;
+ if (++idx >= objc) {
+ goto endOfForLoop;
}
- case REGSUB_START: {
- if (++idx >= objc) {
- goto endOfForLoop;
- }
- if (Tcl_GetIntFromObj(interp, objv[idx], &offset) != TCL_OK) {
- return TCL_ERROR;
- }
- if (offset < 0) {
- offset = 0;
- }
- break;
+ if (TclGetIntForIndexM(interp, objv[idx], 0, &temp) != TCL_OK) {
+ goto optionError;
}
- case REGSUB_LAST: {
- idx++;
- goto endOfForLoop;
+ if (startIndex) {
+ Tcl_DecrRefCount(startIndex);
}
+ startIndex = objv[idx];
+ Tcl_IncrRefCount(startIndex);
+ break;
+ }
+ case REGSUB_LAST:
+ idx++;
+ goto endOfForLoop;
}
}
- endOfForLoop:
+
+ endOfForLoop:
if (objc-idx < 3 || objc-idx > 4) {
Tcl_WrongNumArgs(interp, 1, objv,
"?switches? exp string subSpec ?varName?");
+ optionError:
+ if (startIndex) {
+ Tcl_DecrRefCount(startIndex);
+ }
return TCL_ERROR;
}
objc -= idx;
objv += idx;
+ if (startIndex) {
+ int stringLength = Tcl_GetCharLength(objv[1]);
+
+ TclGetIntForIndexM(NULL, startIndex, stringLength, &offset);
+ Tcl_DecrRefCount(startIndex);
+ if (offset < 0) {
+ offset = 0;
+ }
+ }
+
if (all && (offset == 0)
- && (strpbrk(Tcl_GetString(objv[2]), "&\\") == NULL)
- && (strpbrk(Tcl_GetString(objv[0]), "*+?{}()[].\\|^$") == NULL)) {
+ && (strpbrk(TclGetString(objv[2]), "&\\") == NULL)
+ && (strpbrk(TclGetString(objv[0]), "*+?{}()[].\\|^$") == NULL)) {
/*
- * This is a simple one pair string map situation. We make use of
- * a slightly modified version of the one pair STR_MAP code.
+ * This is a simple one pair string map situation. We make use of a
+ * slightly modified version of the one pair STR_MAP code.
*/
+
int slen, nocase;
- int (*strCmpFn)_ANSI_ARGS_((CONST Tcl_UniChar *, CONST Tcl_UniChar *,
- unsigned long));
+ int (*strCmpFn)(CONST Tcl_UniChar*,CONST Tcl_UniChar*,unsigned long);
Tcl_UniChar *p, wsrclc;
numMatches = 0;
- nocase = (cflags & TCL_REG_NOCASE);
- strCmpFn = nocase ? Tcl_UniCharNcasecmp : Tcl_UniCharNcmp;
+ nocase = (cflags & TCL_REG_NOCASE);
+ strCmpFn = nocase ? Tcl_UniCharNcasecmp : Tcl_UniCharNcmp;
- wsrc = Tcl_GetUnicodeFromObj(objv[0], &slen);
- wstring = Tcl_GetUnicodeFromObj(objv[1], &wlen);
+ wsrc = Tcl_GetUnicodeFromObj(objv[0], &slen);
+ wstring = Tcl_GetUnicodeFromObj(objv[1], &wlen);
wsubspec = Tcl_GetUnicodeFromObj(objv[2], &wsublen);
- wend = wstring + wlen - (slen ? slen - 1 : 0);
- result = TCL_OK;
+ wend = wstring + wlen - (slen ? slen - 1 : 0);
+ result = TCL_OK;
if (slen == 0) {
/*
- * regsub behavior for "" matches between each character.
- * 'string map' skips the "" case.
+ * regsub behavior for "" matches between each character. 'string
+ * map' skips the "" case.
*/
+
if (wstring < wend) {
resultPtr = Tcl_NewUnicodeObj(wstring, 0);
Tcl_IncrRefCount(resultPtr);
@@ -670,10 +587,9 @@ Tcl_RegsubObjCmd(dummy, interp, objc, objv)
} else {
wsrclc = Tcl_UniCharToLower(*wsrc);
for (p = wfirstChar = wstring; wstring < wend; wstring++) {
- if (((*wstring == *wsrc) ||
- (nocase && (Tcl_UniCharToLower(*wstring) ==
- wsrclc))) &&
- ((slen == 1) || (strCmpFn(wstring, wsrc,
+ if ((*wstring == *wsrc ||
+ (nocase && Tcl_UniCharToLower(*wstring)==wsrclc)) &&
+ (slen==1 || (strCmpFn(wstring, wsrc,
(unsigned long) slen) == 0))) {
if (numMatches == 0) {
resultPtr = Tcl_NewUnicodeObj(wstring, 0);
@@ -707,9 +623,9 @@ Tcl_RegsubObjCmd(dummy, interp, objc, objv)
}
/*
- * Make sure to avoid problems where the objects are shared. This
- * can cause RegExpObj <> UnicodeObj shimmering that causes data
- * corruption. [Bug #461322]
+ * Make sure to avoid problems where the objects are shared. This can
+ * cause RegExpObj <> UnicodeObj shimmering that causes data corruption.
+ * [Bug #461322]
*/
if (objv[1] == objv[0]) {
@@ -728,27 +644,27 @@ Tcl_RegsubObjCmd(dummy, interp, objc, objv)
result = TCL_OK;
/*
- * The following loop is to handle multiple matches within the
- * same source string; each iteration handles one match and its
- * corresponding substitution. If "-all" hasn't been specified
- * then the loop body only gets executed once. We must use
- * 'offset <= wlen' in particular for the case where the regexp
- * pattern can match the empty string - this is useful when
- * doing, say, 'regsub -- ^ $str ...' when $str might be empty.
+ * The following loop is to handle multiple matches within the same source
+ * string; each iteration handles one match and its corresponding
+ * substitution. If "-all" hasn't been specified then the loop body only
+ * gets executed once. We must use 'offset <= wlen' in particular for the
+ * case where the regexp pattern can match the empty string - this is
+ * useful when doing, say, 'regsub -- ^ $str ...' when $str might be
+ * empty.
*/
numMatches = 0;
for ( ; offset <= wlen; ) {
/*
- * The flags argument is set if string is part of a larger string,
- * so that "^" won't match.
+ * The flags argument is set if string is part of a larger string, so
+ * that "^" won't match.
*/
match = Tcl_RegExpExecObj(interp, regExpr, objPtr, offset,
10 /* matches */, ((offset > 0 &&
- (wstring[offset-1] != (Tcl_UniChar)'\n'))
- ? TCL_REG_NOTBOL : 0));
+ (wstring[offset-1] != (Tcl_UniChar)'\n'))
+ ? TCL_REG_NOTBOL : 0));
if (match < 0) {
result = TCL_ERROR;
@@ -762,9 +678,10 @@ Tcl_RegsubObjCmd(dummy, interp, objc, objv)
Tcl_IncrRefCount(resultPtr);
if (offset > 0) {
/*
- * Copy the initial portion of the string in if an offset
- * was specified.
+ * Copy the initial portion of the string in if an offset was
+ * specified.
*/
+
Tcl_AppendUnicodeToObj(resultPtr, wstring, offset);
}
}
@@ -782,7 +699,7 @@ Tcl_RegsubObjCmd(dummy, interp, objc, objv)
/*
* Append the subSpec argument to the variable, making appropriate
- * substitutions. This code is a bit hairy because of the backslash
+ * substitutions. This code is a bit hairy because of the backslash
* conventions and because the code saves up ranges of characters in
* subSpec to reduce the number of calls to Tcl_SetVar.
*/
@@ -810,10 +727,12 @@ Tcl_RegsubObjCmd(dummy, interp, objc, objv)
} else {
continue;
}
+
if (wfirstChar != wsrc) {
Tcl_AppendUnicodeToObj(resultPtr, wfirstChar,
wsrc - wfirstChar);
}
+
if (idx <= info.nsubs) {
subStart = info.matches[idx].start;
subEnd = info.matches[idx].end;
@@ -822,18 +741,21 @@ Tcl_RegsubObjCmd(dummy, interp, objc, objv)
wstring + offset + subStart, subEnd - subStart);
}
}
+
if (*wsrc == '\\') {
wsrc++;
}
wfirstChar = wsrc + 1;
}
+
if (wfirstChar != wsrc) {
Tcl_AppendUnicodeToObj(resultPtr, wfirstChar, wsrc - wfirstChar);
}
+
if (end == 0) {
/*
- * Always consume at least one character of the input string
- * in order to prevent infinite loops.
+ * Always consume at least one character of the input string in
+ * order to prevent infinite loops.
*/
if (offset < wlen) {
@@ -844,10 +766,10 @@ Tcl_RegsubObjCmd(dummy, interp, objc, objv)
offset += end;
if (start == end) {
/*
- * We matched an empty string, which means we must go
- * forward one more step so we don't match again at the
- * same spot.
+ * We matched an empty string, which means we must go forward
+ * one more step so we don't match again at the same spot.
*/
+
if (offset < wlen) {
Tcl_AppendUnicodeToObj(resultPtr, wstring + offset, 1);
}
@@ -863,12 +785,14 @@ Tcl_RegsubObjCmd(dummy, interp, objc, objv)
* Copy the portion of the source string after the last match to the
* result variable.
*/
- regsubDone:
+
+ regsubDone:
if (numMatches == 0) {
/*
- * On zero matches, just ignore the offset, since it shouldn't
- * matter to us in this case, and the user may have skewed it.
+ * On zero matches, just ignore the offset, since it shouldn't matter
+ * to us in this case, and the user may have skewed it.
*/
+
resultPtr = objv[1];
Tcl_IncrRefCount(resultPtr);
} else if (offset < wlen) {
@@ -877,27 +801,34 @@ Tcl_RegsubObjCmd(dummy, interp, objc, objv)
if (objc == 4) {
if (Tcl_ObjSetVar2(interp, objv[3], NULL, resultPtr, 0) == NULL) {
Tcl_AppendResult(interp, "couldn't set variable \"",
- Tcl_GetString(objv[3]), "\"", (char *) NULL);
+ TclGetString(objv[3]), "\"", NULL);
result = TCL_ERROR;
} else {
/*
* Set the interpreter's object result to an integer object
- * holding the number of matches.
+ * holding the number of matches.
*/
- Tcl_SetIntObj(Tcl_GetObjResult(interp), numMatches);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(numMatches));
}
} else {
/*
* No varname supplied, so just return the modified string.
*/
+
Tcl_SetObjResult(interp, resultPtr);
}
- done:
- if (objPtr && (objv[1] == objv[0])) { Tcl_DecrRefCount(objPtr); }
- if (subPtr && (objv[2] == objv[0])) { Tcl_DecrRefCount(subPtr); }
- if (resultPtr) { Tcl_DecrRefCount(resultPtr); }
+ done:
+ if (objPtr && (objv[1] == objv[0])) {
+ Tcl_DecrRefCount(objPtr);
+ }
+ if (subPtr && (objv[2] == objv[0])) {
+ Tcl_DecrRefCount(subPtr);
+ }
+ if (resultPtr) {
+ Tcl_DecrRefCount(resultPtr);
+ }
return result;
}
@@ -906,8 +837,8 @@ Tcl_RegsubObjCmd(dummy, interp, objc, objv)
*
* Tcl_RenameObjCmd --
*
- * This procedure is invoked to process the "rename" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "rename" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl object result.
@@ -918,23 +849,22 @@ Tcl_RegsubObjCmd(dummy, interp, objc, objv)
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
int
-Tcl_RenameObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Arbitrary value passed to the command. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_RenameObjCmd(
+ ClientData dummy, /* Arbitrary value passed to the command. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
char *oldName, *newName;
-
+
if (objc != 3) {
Tcl_WrongNumArgs(interp, 1, objv, "oldName newName");
return TCL_ERROR;
}
- oldName = Tcl_GetString(objv[1]);
- newName = Tcl_GetString(objv[2]);
+ oldName = TclGetString(objv[1]);
+ newName = TclGetString(objv[2]);
return TclRenameCommand(interp, oldName, newName);
}
@@ -955,83 +885,34 @@ Tcl_RenameObjCmd(dummy, interp, objc, objv)
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
int
-Tcl_ReturnObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_ReturnObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- Interp *iPtr = (Interp *) interp;
- int optionLen, argLen, code, result;
-
- if (iPtr->errorInfo != NULL) {
- ckfree(iPtr->errorInfo);
- iPtr->errorInfo = NULL;
- }
- if (iPtr->errorCode != NULL) {
- ckfree(iPtr->errorCode);
- iPtr->errorCode = NULL;
- }
- code = TCL_OK;
-
- for (objv++, objc--; objc > 1; objv += 2, objc -= 2) {
- char *option = Tcl_GetStringFromObj(objv[0], &optionLen);
- char *arg = Tcl_GetStringFromObj(objv[1], &argLen);
-
- if (strcmp(option, "-code") == 0) {
- register int c = arg[0];
- if ((c == 'o') && (strcmp(arg, "ok") == 0)) {
- code = TCL_OK;
- } else if ((c == 'e') && (strcmp(arg, "error") == 0)) {
- code = TCL_ERROR;
- } else if ((c == 'r') && (strcmp(arg, "return") == 0)) {
- code = TCL_RETURN;
- } else if ((c == 'b') && (strcmp(arg, "break") == 0)) {
- code = TCL_BREAK;
- } else if ((c == 'c') && (strcmp(arg, "continue") == 0)) {
- code = TCL_CONTINUE;
- } else {
- result = Tcl_GetIntFromObj((Tcl_Interp *) NULL, objv[1],
- &code);
- if (result != TCL_OK) {
- Tcl_ResetResult(interp);
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "bad completion code \"",
- Tcl_GetString(objv[1]),
- "\": must be ok, error, return, break, ",
- "continue, or an integer", (char *) NULL);
- return result;
- }
- }
- } else if (strcmp(option, "-errorinfo") == 0) {
- iPtr->errorInfo =
- (char *) ckalloc((unsigned) (strlen(arg) + 1));
- strcpy(iPtr->errorInfo, arg);
- } else if (strcmp(option, "-errorcode") == 0) {
- iPtr->errorCode =
- (char *) ckalloc((unsigned) (strlen(arg) + 1));
- strcpy(iPtr->errorCode, arg);
- } else {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "bad option \"", option,
- "\": must be -code, -errorcode, or -errorinfo",
- (char *) NULL);
- return TCL_ERROR;
- }
+ int code, level;
+ Tcl_Obj *returnOpts;
+
+ /*
+ * General syntax: [return ?-option value ...? ?result?]
+ * An even number of words means an explicit result argument is present.
+ */
+
+ int explicitResult = (0 == (objc % 2));
+ int numOptionWords = objc - 1 - explicitResult;
+
+ if (TCL_ERROR == TclMergeReturnOptions(interp, numOptionWords, objv+1,
+ &returnOpts, &code, &level)) {
+ return TCL_ERROR;
}
-
- if (objc == 1) {
- /*
- * Set the interpreter's object result. An inline version of
- * Tcl_SetObjResult.
- */
- Tcl_SetObjResult(interp, objv[0]);
+ code = TclProcessReturn(interp, code, level, returnOpts);
+ if (explicitResult) {
+ Tcl_SetObjResult(interp, objv[objc-1]);
}
- iPtr->returnCode = code;
- return TCL_RETURN;
+ return code;
}
/*
@@ -1039,8 +920,8 @@ Tcl_ReturnObjCmd(dummy, interp, objc, objv)
*
* Tcl_SourceObjCmd --
*
- * This procedure is invoked to process the "source" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "source" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl object result.
@@ -1051,20 +932,37 @@ Tcl_ReturnObjCmd(dummy, interp, objc, objv)
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
int
-Tcl_SourceObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_SourceObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "fileName");
+ CONST char *encodingName = NULL;
+ Tcl_Obj *fileName;
+
+ if (objc != 2 && objc !=4) {
+ Tcl_WrongNumArgs(interp, 1, objv, "?-encoding name? fileName");
return TCL_ERROR;
}
- return Tcl_FSEvalFile(interp, objv[1]);
+ fileName = objv[objc-1];
+
+ if (objc == 4) {
+ static CONST char *options[] = {
+ "-encoding", NULL
+ };
+ int index;
+
+ if (TCL_ERROR == Tcl_GetIndexFromObj(interp, objv[1], options,
+ "option", TCL_EXACT, &index)) {
+ return TCL_ERROR;
+ }
+ encodingName = TclGetString(objv[2]);
+ }
+
+ return Tcl_FSEvalFileEx(interp, fileName, encodingName);
}
/*
@@ -1072,8 +970,8 @@ Tcl_SourceObjCmd(dummy, interp, objc, objv)
*
* Tcl_SplitObjCmd --
*
- * This procedure is invoked to process the "split" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "split" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -1084,17 +982,16 @@ Tcl_SourceObjCmd(dummy, interp, objc, objv)
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
int
-Tcl_SplitObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_SplitObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
Tcl_UniChar ch;
int len;
- char *splitChars, *string, *end;
+ char *splitChars, *stringPtr, *end;
int splitCharLen, stringLen;
Tcl_Obj *listPtr, *objPtr;
@@ -1102,16 +999,16 @@ Tcl_SplitObjCmd(dummy, interp, objc, objv)
splitChars = " \n\t\r";
splitCharLen = 4;
} else if (objc == 3) {
- splitChars = Tcl_GetStringFromObj(objv[2], &splitCharLen);
+ splitChars = TclGetStringFromObj(objv[2], &splitCharLen);
} else {
Tcl_WrongNumArgs(interp, 1, objv, "string ?splitChars?");
return TCL_ERROR;
}
- string = Tcl_GetStringFromObj(objv[1], &stringLen);
- end = string + stringLen;
- listPtr = Tcl_GetObjResult(interp);
-
+ stringPtr = TclGetStringFromObj(objv[1], &stringLen);
+ end = stringPtr + stringLen;
+ listPtr = Tcl_NewObj();
+
if (stringLen == 0) {
/*
* Do nothing.
@@ -1124,87 +1021,92 @@ Tcl_SplitObjCmd(dummy, interp, objc, objv)
/*
* Handle the special case of splitting on every character.
*
- * Uses a hash table to ensure that each kind of character has
- * only one Tcl_Obj instance (multiply-referenced) in the
- * final list. This is a *major* win when splitting on a long
- * string (especially in the megabyte range!) - DKF
+ * Uses a hash table to ensure that each kind of character has only
+ * one Tcl_Obj instance (multiply-referenced) in the final list. This
+ * is a *major* win when splitting on a long string (especially in the
+ * megabyte range!) - DKF
*/
Tcl_InitHashTable(&charReuseTable, TCL_ONE_WORD_KEYS);
- for ( ; string < end; string += len) {
- len = TclUtfToUniChar(string, &ch);
- /* Assume Tcl_UniChar is an integral type... */
- hPtr = Tcl_CreateHashEntry(&charReuseTable, (char*)0 + ch, &isNew);
+
+ for ( ; stringPtr < end; stringPtr += len) {
+ len = TclUtfToUniChar(stringPtr, &ch);
+
+ /*
+ * Assume Tcl_UniChar is an integral type...
+ */
+
+ hPtr = Tcl_CreateHashEntry(&charReuseTable, (char*)0+ch, &isNew);
if (isNew) {
- objPtr = Tcl_NewStringObj(string, len);
- /* Don't need to fiddle with refcount... */
+ TclNewStringObj(objPtr, stringPtr, len);
+
+ /*
+ * Don't need to fiddle with refcount...
+ */
+
Tcl_SetHashValue(hPtr, (ClientData) objPtr);
} else {
- objPtr = (Tcl_Obj*) Tcl_GetHashValue(hPtr);
+ objPtr = (Tcl_Obj *) Tcl_GetHashValue(hPtr);
}
Tcl_ListObjAppendElement(NULL, listPtr, objPtr);
}
Tcl_DeleteHashTable(&charReuseTable);
+
} else if (splitCharLen == 1) {
char *p;
/*
- * Handle the special case of splitting on a single character.
- * This is only true for the one-char ASCII case, as one unicode
- * char is > 1 byte in length.
+ * Handle the special case of splitting on a single character. This is
+ * only true for the one-char ASCII case, as one unicode char is > 1
+ * byte in length.
*/
- while (*string && (p = strchr(string, (int) *splitChars)) != NULL) {
- objPtr = Tcl_NewStringObj(string, p - string);
+ while (*stringPtr && (p=strchr(stringPtr,(int)*splitChars)) != NULL) {
+ objPtr = Tcl_NewStringObj(stringPtr, p - stringPtr);
Tcl_ListObjAppendElement(NULL, listPtr, objPtr);
- string = p + 1;
+ stringPtr = p + 1;
}
- objPtr = Tcl_NewStringObj(string, end - string);
+ TclNewStringObj(objPtr, stringPtr, end - stringPtr);
Tcl_ListObjAppendElement(NULL, listPtr, objPtr);
} else {
char *element, *p, *splitEnd;
int splitLen;
Tcl_UniChar splitChar;
-
+
/*
- * Normal case: split on any of a given set of characters.
- * Discard instances of the split characters.
+ * Normal case: split on any of a given set of characters. Discard
+ * instances of the split characters.
*/
splitEnd = splitChars + splitCharLen;
- for (element = string; string < end; string += len) {
- len = TclUtfToUniChar(string, &ch);
+ for (element = stringPtr; stringPtr < end; stringPtr += len) {
+ len = TclUtfToUniChar(stringPtr, &ch);
for (p = splitChars; p < splitEnd; p += splitLen) {
splitLen = TclUtfToUniChar(p, &splitChar);
if (ch == splitChar) {
- objPtr = Tcl_NewStringObj(element, string - element);
+ TclNewStringObj(objPtr, element, stringPtr - element);
Tcl_ListObjAppendElement(NULL, listPtr, objPtr);
- element = string + len;
+ element = stringPtr + len;
break;
}
}
}
- objPtr = Tcl_NewStringObj(element, string - element);
+
+ TclNewStringObj(objPtr, element, stringPtr - element);
Tcl_ListObjAppendElement(NULL, listPtr, objPtr);
}
+ Tcl_SetObjResult(interp, listPtr);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
- * Tcl_StringObjCmd --
- *
- * This procedure is invoked to process the "string" Tcl command.
- * See the user documentation for details on what it does. Note
- * that this command only functions correctly on properly formed
- * Tcl UTF strings.
+ * StringFirstCmd --
*
- * Note that the primary methods here (equal, compare, match, ...)
- * have bytecode equivalents. You will find the code for those in
- * tclExecute.c. The code here will only be used in the non-bc
- * case (like in an 'eval').
+ * This procedure is invoked to process the "string first" Tcl command.
+ * See the user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -1215,1248 +1117,882 @@ Tcl_SplitObjCmd(dummy, interp, objc, objv)
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
-int
-Tcl_StringObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+static int
+StringFirstCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- int index, left, right;
- Tcl_Obj *resultPtr;
- char *string1, *string2;
- int length1, length2;
- static CONST char *options[] = {
- "bytelength", "compare", "equal", "first",
- "index", "is", "last", "length",
- "map", "match", "range", "repeat",
- "replace", "tolower", "toupper", "totitle",
- "trim", "trimleft", "trimright",
- "wordend", "wordstart", (char *) NULL
- };
- enum options {
- STR_BYTELENGTH, STR_COMPARE, STR_EQUAL, STR_FIRST,
- STR_INDEX, STR_IS, STR_LAST, STR_LENGTH,
- STR_MAP, STR_MATCH, STR_RANGE, STR_REPEAT,
- STR_REPLACE, STR_TOLOWER, STR_TOUPPER, STR_TOTITLE,
- STR_TRIM, STR_TRIMLEFT, STR_TRIMRIGHT,
- STR_WORDEND, STR_WORDSTART
- };
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
- return TCL_ERROR;
- }
-
- if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0,
- &index) != TCL_OK) {
+ Tcl_UniChar *ustring1, *ustring2;
+ int match, start, length1, length2;
+
+ if (objc < 3 || objc > 4) {
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "needleString haystackString ?startIndex?");
return TCL_ERROR;
}
- resultPtr = Tcl_GetObjResult(interp);
- switch ((enum options) index) {
- case STR_EQUAL:
- case STR_COMPARE: {
- /*
- * Remember to keep code here in some sync with the
- * byte-compiled versions in tclExecute.c (INST_STR_EQ,
- * INST_STR_NEQ and INST_STR_CMP as well as the expr string
- * comparison in INST_EQ/INST_NEQ/INST_LT/...).
- */
- int i, match, length, nocase = 0, reqlength = -1;
- int (*strCmpFn)();
-
- if (objc < 4 || objc > 7) {
- str_cmp_args:
- Tcl_WrongNumArgs(interp, 2, objv,
- "?-nocase? ?-length int? string1 string2");
- return TCL_ERROR;
- }
-
- for (i = 2; i < objc-2; i++) {
- string2 = Tcl_GetStringFromObj(objv[i], &length2);
- if ((length2 > 1)
- && strncmp(string2, "-nocase", (size_t)length2) == 0) {
- nocase = 1;
- } else if ((length2 > 1)
- && strncmp(string2, "-length", (size_t)length2) == 0) {
- if (i+1 >= objc-2) {
- goto str_cmp_args;
- }
- if (Tcl_GetIntFromObj(interp, objv[++i],
- &reqlength) != TCL_OK) {
- return TCL_ERROR;
- }
- } else {
- Tcl_AppendStringsToObj(resultPtr, "bad option \"",
- string2, "\": must be -nocase or -length",
- (char *) NULL);
- return TCL_ERROR;
- }
- }
+ /*
+ * We are searching string2 for the sequence string1.
+ */
- /*
- * From now on, we only access the two objects at the end
- * of the argument array.
- */
- objv += objc-2;
+ match = -1;
+ start = 0;
+ length2 = -1;
- if ((reqlength == 0) || (objv[0] == objv[1])) {
- /*
- * Alway match at 0 chars of if it is the same obj.
- */
+ ustring1 = Tcl_GetUnicodeFromObj(objv[1], &length1);
+ ustring2 = Tcl_GetUnicodeFromObj(objv[2], &length2);
- Tcl_SetBooleanObj(resultPtr,
- ((enum options) index == STR_EQUAL));
- break;
- } else if (!nocase && objv[0]->typePtr == &tclByteArrayType &&
- objv[1]->typePtr == &tclByteArrayType) {
- /*
- * Use binary versions of comparisons since that won't
- * cause undue type conversions and it is much faster.
- * Only do this if we're case-sensitive (which is all
- * that really makes sense with byte arrays anyway, and
- * we have no memcasecmp() for some reason... :^)
- */
- string1 = (char*) Tcl_GetByteArrayFromObj(objv[0], &length1);
- string2 = (char*) Tcl_GetByteArrayFromObj(objv[1], &length2);
- strCmpFn = memcmp;
- } else if ((objv[0]->typePtr == &tclStringType)
- && (objv[1]->typePtr == &tclStringType)) {
- /*
- * Do a unicode-specific comparison if both of the args
- * are of String type. In benchmark testing this proved
- * the most efficient check between the unicode and
- * string comparison operations.
- */
- string1 = (char*) Tcl_GetUnicodeFromObj(objv[0], &length1);
- string2 = (char*) Tcl_GetUnicodeFromObj(objv[1], &length2);
- strCmpFn = nocase ? Tcl_UniCharNcasecmp : Tcl_UniCharNcmp;
- } else {
- /*
- * As a catch-all we will work with UTF-8. We cannot use
- * memcmp() as that is unsafe with any string containing
- * NULL (\xC0\x80 in Tcl's utf rep). We can use the more
- * efficient TclpUtfNcmp2 if we are case-sensitive and no
- * specific length was requested.
- */
- string1 = (char*) Tcl_GetStringFromObj(objv[0], &length1);
- string2 = (char*) Tcl_GetStringFromObj(objv[1], &length2);
- if ((reqlength < 0) && !nocase) {
- strCmpFn = TclpUtfNcmp2;
- } else {
- length1 = Tcl_NumUtfChars(string1, length1);
- length2 = Tcl_NumUtfChars(string2, length2);
- strCmpFn = nocase ? Tcl_UtfNcasecmp : Tcl_UtfNcmp;
- }
- }
-
- if (((enum options) index == STR_EQUAL)
- && (reqlength < 0) && (length1 != length2)) {
- match = 1; /* this will be reversed below */
- } else {
- length = (length1 < length2) ? length1 : length2;
- if (reqlength > 0 && reqlength < length) {
- length = reqlength;
- } else if (reqlength < 0) {
- /*
- * The requested length is negative, so we ignore it by
- * setting it to length + 1 so we correct the match var.
- */
- reqlength = length + 1;
- }
- match = strCmpFn(string1, string2, (unsigned) length);
- if ((match == 0) && (reqlength > length)) {
- match = length1 - length2;
- }
- }
+ if (objc == 4) {
+ /*
+ * If a startIndex is specified, we will need to fast forward to that
+ * point in the string before we think about a match.
+ */
- if ((enum options) index == STR_EQUAL) {
- Tcl_SetBooleanObj(resultPtr, (match) ? 0 : 1);
- } else {
- Tcl_SetIntObj(resultPtr, ((match > 0) ? 1 :
- (match < 0) ? -1 : 0));
- }
- break;
+ if (TclGetIntForIndexM(interp, objv[3], length2-1, &start) != TCL_OK){
+ return TCL_ERROR;
}
- case STR_FIRST: {
- Tcl_UniChar *ustring1, *ustring2;
- int match, start;
- if (objc < 4 || objc > 5) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "subString string ?startIndex?");
- return TCL_ERROR;
- }
+ /*
+ * Reread to prevent shimmering problems.
+ */
+
+ ustring1 = Tcl_GetUnicodeFromObj(objv[1], &length1);
+ ustring2 = Tcl_GetUnicodeFromObj(objv[2], &length2);
+ if (start >= length2) {
+ goto str_first_done;
+ } else if (start > 0) {
+ ustring2 += start;
+ length2 -= start;
+ } else if (start < 0) {
/*
- * We are searching string2 for the sequence string1.
+ * Invalid start index mapped to string start; Bug #423581
*/
- match = -1;
start = 0;
- length2 = -1;
-
- ustring1 = Tcl_GetUnicodeFromObj(objv[2], &length1);
- ustring2 = Tcl_GetUnicodeFromObj(objv[3], &length2);
+ }
+ }
- if (objc == 5) {
- /*
- * If a startIndex is specified, we will need to fast
- * forward to that point in the string before we think
- * about a match
- */
- if (TclGetIntForIndex(interp, objv[4], length2 - 1,
- &start) != TCL_OK) {
- return TCL_ERROR;
- }
- if (start >= length2) {
- goto str_first_done;
- } else if (start > 0) {
- ustring2 += start;
- length2 -= start;
- } else if (start < 0) {
- /*
- * Invalid start index mapped to string start;
- * Bug #423581
- */
- start = 0;
- }
- }
+ /*
+ * If the length of the needle is more than the length of the haystack, it
+ * cannot be contained in there so we can avoid searching. [Bug 2960021]
+ */
- if (length1 > 0) {
- register Tcl_UniChar *p, *end;
+ if (length1 > 0 && length1 <= length2) {
+ register Tcl_UniChar *p, *end;
- end = ustring2 + length2 - length1 + 1;
- for (p = ustring2; p < end; p++) {
- /*
- * Scan forward to find the first character.
- */
- if ((*p == *ustring1) &&
- (TclUniCharNcmp(ustring1, p,
- (unsigned long) length1) == 0)) {
- match = p - ustring2;
- break;
- }
- }
- }
+ end = ustring2 + length2 - length1 + 1;
+ for (p = ustring2; p < end; p++) {
/*
- * Compute the character index of the matching string by
- * counting the number of characters before the match.
+ * Scan forward to find the first character.
*/
- if ((match != -1) && (objc == 5)) {
- match += start;
- }
- str_first_done:
- Tcl_SetIntObj(resultPtr, match);
- break;
- }
- case STR_INDEX: {
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "string charIndex");
- return TCL_ERROR;
+ if ((*p == *ustring1) && (TclUniCharNcmp(ustring1, p,
+ (unsigned long) length1) == 0)) {
+ match = p - ustring2;
+ break;
}
+ }
+ }
- /*
- * If we have a ByteArray object, avoid indexing in the
- * Utf string since the byte array contains one byte per
- * character. Otherwise, use the Unicode string rep to
- * get the index'th char.
- */
+ /*
+ * Compute the character index of the matching string by counting the
+ * number of characters before the match.
+ */
- if (objv[2]->typePtr == &tclByteArrayType) {
- string1 = (char *) Tcl_GetByteArrayFromObj(objv[2], &length1);
+ if ((match != -1) && (objc == 4)) {
+ match += start;
+ }
- if (TclGetIntForIndex(interp, objv[3], length1 - 1,
- &index) != TCL_OK) {
- return TCL_ERROR;
- }
- if ((index >= 0) && (index < length1)) {
- Tcl_SetByteArrayObj(resultPtr,
- (unsigned char *)(&string1[index]), 1);
- }
- } else {
- /*
- * Get Unicode char length to calulate what 'end' means.
- */
- length1 = Tcl_GetCharLength(objv[2]);
+ str_first_done:
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(match));
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringLastCmd --
+ *
+ * This procedure is invoked to process the "string last" Tcl command.
+ * See the user documentation for details on what it does.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
- if (TclGetIntForIndex(interp, objv[3], length1 - 1,
- &index) != TCL_OK) {
- return TCL_ERROR;
- }
- if ((index >= 0) && (index < length1)) {
- char buf[TCL_UTF_MAX];
- Tcl_UniChar ch;
+static int
+StringLastCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ Tcl_UniChar *ustring1, *ustring2, *p;
+ int match, start, length1, length2;
- ch = Tcl_GetUniChar(objv[2], index);
- length1 = Tcl_UniCharToUtf(ch, buf);
- Tcl_SetStringObj(resultPtr, buf, length1);
- }
- }
- break;
- }
- case STR_IS: {
- char *end;
- Tcl_UniChar ch;
+ if (objc < 3 || objc > 4) {
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "needleString haystackString ?startIndex?");
+ return TCL_ERROR;
+ }
- /*
- * The UniChar comparison function
- */
+ /*
+ * We are searching string2 for the sequence string1.
+ */
- int (*chcomp)_ANSI_ARGS_((int)) = NULL;
- int i, failat = 0, result = 1, strict = 0;
- Tcl_Obj *objPtr, *failVarObj = NULL;
-
- static CONST char *isOptions[] = {
- "alnum", "alpha", "ascii", "control",
- "boolean", "digit", "double", "false",
- "graph", "integer", "lower", "print",
- "punct", "space", "true", "upper",
- "wordchar", "xdigit", (char *) NULL
- };
- enum isOptions {
- 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_LOWER, STR_IS_PRINT,
- STR_IS_PUNCT, STR_IS_SPACE, STR_IS_TRUE, STR_IS_UPPER,
- STR_IS_WORD, STR_IS_XDIGIT
- };
-
- if (objc < 4 || objc > 7) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "class ?-strict? ?-failindex var? str");
- return TCL_ERROR;
- }
- if (Tcl_GetIndexFromObj(interp, objv[2], isOptions, "class", 0,
- &index) != TCL_OK) {
- return TCL_ERROR;
- }
- if (objc != 4) {
- for (i = 3; i < objc-1; i++) {
- string2 = Tcl_GetStringFromObj(objv[i], &length2);
- if ((length2 > 1) &&
- strncmp(string2, "-strict", (size_t) length2) == 0) {
- strict = 1;
- } else if ((length2 > 1) &&
- strncmp(string2, "-failindex",
- (size_t) length2) == 0) {
- if (i+1 >= objc-1) {
- Tcl_WrongNumArgs(interp, 3, objv,
- "?-strict? ?-failindex var? str");
- return TCL_ERROR;
- }
- failVarObj = objv[++i];
- } else {
- Tcl_AppendStringsToObj(resultPtr, "bad option \"",
- string2, "\": must be -strict or -failindex",
- (char *) NULL);
- return TCL_ERROR;
- }
- }
- }
+ match = -1;
+ start = 0;
+ length2 = -1;
- /*
- * We get the objPtr so that we can short-cut for some classes
- * by checking the object type (int and double), but we need
- * the string otherwise, because we don't want any conversion
- * of type occuring (as, for example, Tcl_Get*FromObj would do
- */
- objPtr = objv[objc-1];
- string1 = Tcl_GetStringFromObj(objPtr, &length1);
- if (length1 == 0) {
- if (strict) {
- result = 0;
- }
- goto str_is_done;
- }
- end = string1 + length1;
+ ustring1 = Tcl_GetUnicodeFromObj(objv[1], &length1);
+ ustring2 = Tcl_GetUnicodeFromObj(objv[2], &length2);
- /*
- * When entering here, result == 1 and failat == 0
- */
- switch ((enum isOptions) index) {
- case STR_IS_ALNUM:
- chcomp = Tcl_UniCharIsAlnum;
- break;
- case STR_IS_ALPHA:
- chcomp = Tcl_UniCharIsAlpha;
- break;
- case STR_IS_ASCII:
- for (; string1 < end; string1++, failat++) {
- /*
- * This is a valid check in unicode, because all
- * bytes < 0xC0 are single byte chars (but isascii
- * limits that def'n to 0x80).
- */
- if (*((unsigned char *)string1) >= 0x80) {
- result = 0;
- break;
- }
- }
- break;
- case STR_IS_BOOL:
- case STR_IS_TRUE:
- case STR_IS_FALSE:
- /* Optimizers, beware Bug 1187123 ! */
- if ((Tcl_GetBoolean(NULL, string1, &i)
- == TCL_ERROR) ||
- (((enum isOptions) index == STR_IS_TRUE) &&
- i == 0) ||
- (((enum isOptions) index == STR_IS_FALSE) &&
- i != 0)) {
- result = 0;
- }
- break;
- case STR_IS_CONTROL:
- chcomp = Tcl_UniCharIsControl;
- break;
- case STR_IS_DIGIT:
- chcomp = Tcl_UniCharIsDigit;
- break;
- case STR_IS_DOUBLE: {
- char *stop;
+ if (objc == 4) {
+ /*
+ * If a startIndex is specified, we will need to restrict the string
+ * range to that char index in the string
+ */
- if ((objPtr->typePtr == &tclDoubleType) ||
- (objPtr->typePtr == &tclIntType)) {
- break;
- }
- /*
- * This is adapted from Tcl_GetDouble
- *
- * The danger in this function is that
- * "12345678901234567890" is an acceptable 'double',
- * but will later be interp'd as an int by something
- * like [expr]. Therefore, we check to see if it looks
- * like an int, and if so we do a range check on it.
- * If strtoul gets to the end, we know we either
- * received an acceptable int, or over/underflow
- */
- if (TclLooksLikeInt(string1, length1)) {
- errno = 0;
-#ifdef TCL_WIDE_INT_IS_LONG
- strtoul(string1, &stop, 0); /* INTL: Tcl source. */
-#else
- strtoull(string1, &stop, 0); /* INTL: Tcl source. */
-#endif
- if (stop == end) {
- if (errno == ERANGE) {
- result = 0;
- failat = -1;
- }
- break;
- }
- }
- errno = 0;
- strtod(string1, &stop); /* INTL: Tcl source. */
- if (errno == ERANGE) {
- /*
- * if (errno == ERANGE), then it was an over/underflow
- * problem, but in this method, we only want to know
- * yes or no, so bad flow returns 0 (false) and sets
- * the failVarObj to the string length.
- */
- result = 0;
- failat = -1;
- } else if (stop == string1) {
- /*
- * In this case, nothing like a number was found
- */
- result = 0;
- failat = 0;
- } else {
- /*
- * Assume we sucked up one char per byte
- * and then we go onto SPACE, since we are
- * allowed trailing whitespace
- */
- failat = stop - string1;
- string1 = stop;
- chcomp = Tcl_UniCharIsSpace;
- }
- break;
- }
- case STR_IS_GRAPH:
- chcomp = Tcl_UniCharIsGraph;
- break;
- case STR_IS_INT: {
- char *stop;
- long int l = 0;
+ if (TclGetIntForIndexM(interp, objv[3], length2-1, &start) != TCL_OK){
+ return TCL_ERROR;
+ }
- if (TCL_OK == Tcl_GetIntFromObj(NULL, objPtr, &i)) {
- break;
- }
- /*
- * Like STR_IS_DOUBLE, but we use strtoul.
- * Since Tcl_GetIntFromObj already failed,
- * we set result to 0.
- */
- result = 0;
- errno = 0;
- l = strtol(string1, &stop, 0); /* INTL: Tcl source. */
- if ((errno == ERANGE) || (l > INT_MAX) || (l < INT_MIN)) {
- /*
- * if (errno == ERANGE), then it was an over/underflow
- * problem, but in this method, we only want to know
- * yes or no, so bad flow returns 0 (false) and sets
- * the failVarObj to the string length.
- */
- failat = -1;
+ /*
+ * Reread to prevent shimmering problems.
+ */
- } else if (stop == string1) {
- /*
- * In this case, nothing like a number was found
- */
- failat = 0;
- } else {
- /*
- * Assume we sucked up one char per byte
- * and then we go onto SPACE, since we are
- * allowed trailing whitespace
- */
- failat = stop - string1;
- string1 = stop;
- chcomp = Tcl_UniCharIsSpace;
- }
- break;
- }
- case STR_IS_LOWER:
- chcomp = Tcl_UniCharIsLower;
- break;
- case STR_IS_PRINT:
- chcomp = Tcl_UniCharIsPrint;
- break;
- case STR_IS_PUNCT:
- chcomp = Tcl_UniCharIsPunct;
- break;
- case STR_IS_SPACE:
- chcomp = Tcl_UniCharIsSpace;
- break;
- case STR_IS_UPPER:
- chcomp = Tcl_UniCharIsUpper;
- break;
- case STR_IS_WORD:
- chcomp = Tcl_UniCharIsWordChar;
- break;
- case STR_IS_XDIGIT: {
- for (; string1 < end; string1++, failat++) {
- /* INTL: We assume unicode is bad for this class */
- if ((*((unsigned char *)string1) >= 0xC0) ||
- !isxdigit(*(unsigned char *)string1)) {
- result = 0;
- break;
- }
- }
- break;
- }
- }
- if (chcomp != NULL) {
- for (; string1 < end; string1 += length2, failat++) {
- length2 = TclUtfToUniChar(string1, &ch);
- if (!chcomp(ch)) {
- result = 0;
- break;
- }
- }
- }
- str_is_done:
- /*
- * Only set the failVarObj when we will return 0
- * and we have indicated a valid fail index (>= 0)
- */
- if ((result == 0) && (failVarObj != NULL)) {
- Tcl_Obj *resPtr, *tmpPtr = Tcl_NewIntObj(failat);
-
- Tcl_IncrRefCount(tmpPtr);
- resPtr = Tcl_ObjSetVar2(interp, failVarObj, NULL, tmpPtr,
- TCL_LEAVE_ERR_MSG);
- Tcl_DecrRefCount(tmpPtr);
- if (resPtr == NULL) {
- return TCL_ERROR;
- }
- }
- Tcl_SetBooleanObj(resultPtr, result);
- break;
+ ustring1 = Tcl_GetUnicodeFromObj(objv[1], &length1);
+ ustring2 = Tcl_GetUnicodeFromObj(objv[2], &length2);
+
+ if (start < 0) {
+ goto str_last_done;
+ } else if (start < length2) {
+ p = ustring2 + start + 1 - length1;
+ } else {
+ p = ustring2 + length2 - length1;
}
- case STR_LAST: {
- Tcl_UniChar *ustring1, *ustring2, *p;
- int match, start;
+ } else {
+ p = ustring2 + length2 - length1;
+ }
- if (objc < 4 || objc > 5) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "subString string ?startIndex?");
- return TCL_ERROR;
- }
+ /*
+ * If the length of the needle is more than the length of the haystack, it
+ * cannot be contained in there so we can avoid searching. [Bug 2960021]
+ */
+ if (length1 > 0 && length1 <= length2) {
+ for (; p >= ustring2; p--) {
/*
- * We are searching string2 for the sequence string1.
+ * Scan backwards to find the first character.
*/
- match = -1;
- start = 0;
- length2 = -1;
+ if ((*p == *ustring1) && !memcmp(ustring1, p,
+ sizeof(Tcl_UniChar) * (size_t)length1)) {
+ match = p - ustring2;
+ break;
+ }
+ }
+ }
- ustring1 = Tcl_GetUnicodeFromObj(objv[2], &length1);
- ustring2 = Tcl_GetUnicodeFromObj(objv[3], &length2);
+ str_last_done:
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(match));
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringIndexCmd --
+ *
+ * This procedure is invoked to process the "string index" Tcl command.
+ * See the user documentation for details on what it does. Note that this
+ * command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
- if (objc == 5) {
- /*
- * If a startIndex is specified, we will need to restrict
- * the string range to that char index in the string
- */
- if (TclGetIntForIndex(interp, objv[4], length2 - 1,
- &start) != TCL_OK) {
- return TCL_ERROR;
- }
- if (start < 0) {
- goto str_last_done;
- } else if (start < length2) {
- p = ustring2 + start + 1 - length1;
- } else {
- p = ustring2 + length2 - length1;
- }
- } else {
- p = ustring2 + length2 - length1;
- }
+static int
+StringIndexCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ int length, index;
- if (length1 > 0) {
- for (; p >= ustring2; p--) {
- /*
- * Scan backwards to find the first character.
- */
- if ((*p == *ustring1) &&
- (memcmp((char *) ustring1, (char *) p, (size_t)
- (length1 * sizeof(Tcl_UniChar))) == 0)) {
- match = p - ustring2;
- break;
- }
- }
- }
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "string charIndex");
+ return TCL_ERROR;
+ }
- str_last_done:
- Tcl_SetIntObj(resultPtr, match);
- break;
+ /*
+ * If we have a ByteArray object, avoid indexing in the Utf string since
+ * the byte array contains one byte per character. Otherwise, use the
+ * Unicode string rep to get the index'th char.
+ */
+
+ if (objv[1]->typePtr == &tclByteArrayType) {
+ const unsigned char *string =
+ Tcl_GetByteArrayFromObj(objv[1], &length);
+
+ if (TclGetIntForIndexM(interp, objv[2], length-1, &index) != TCL_OK){
+ return TCL_ERROR;
}
- case STR_BYTELENGTH:
- case STR_LENGTH: {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "string");
- return TCL_ERROR;
- }
+ string = Tcl_GetByteArrayFromObj(objv[1], &length);
+ if ((index >= 0) && (index < length)) {
+ Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(string + index, 1));
+ }
+ } else {
+ /*
+ * Get Unicode char length to calulate what 'end' means.
+ */
- if ((enum options) index == STR_BYTELENGTH) {
- (void) Tcl_GetStringFromObj(objv[2], &length1);
- } else {
- /*
- * If we have a ByteArray object, avoid recomputing the
- * string since the byte array contains one byte per
- * character. Otherwise, use the Unicode string rep to
- * calculate the length.
- */
+ length = Tcl_GetCharLength(objv[1]);
- if (objv[2]->typePtr == &tclByteArrayType) {
- (void) Tcl_GetByteArrayFromObj(objv[2], &length1);
- } else {
- length1 = Tcl_GetCharLength(objv[2]);
- }
- }
- Tcl_SetIntObj(resultPtr, length1);
- break;
+ if (TclGetIntForIndexM(interp, objv[2], length-1, &index) != TCL_OK){
+ return TCL_ERROR;
}
- case STR_MAP: {
- int mapElemc, nocase = 0, copySource = 0;
- Tcl_Obj **mapElemv, *sourceObj;
- Tcl_UniChar *ustring1, *ustring2, *p, *end;
- int (*strCmpFn)_ANSI_ARGS_((CONST Tcl_UniChar*,
- CONST Tcl_UniChar*, unsigned long));
-
- if (objc < 4 || objc > 5) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-nocase? charMap string");
- return TCL_ERROR;
- }
+ if ((index >= 0) && (index < length)) {
+ char buf[TCL_UTF_MAX];
+ Tcl_UniChar ch;
- if (objc == 5) {
- string2 = Tcl_GetStringFromObj(objv[2], &length2);
- if ((length2 > 1) &&
- strncmp(string2, "-nocase", (size_t) length2) == 0) {
- nocase = 1;
- } else {
- Tcl_AppendStringsToObj(resultPtr, "bad option \"",
- string2, "\": must be -nocase",
- (char *) NULL);
- return TCL_ERROR;
- }
- }
+ ch = Tcl_GetUniChar(objv[1], index);
+ length = Tcl_UniCharToUtf(ch, buf);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, length));
+ }
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringIsCmd --
+ *
+ * This procedure is invoked to process the "string is" Tcl command. See
+ * the user documentation for details on what it does. Note that this
+ * command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
- if (Tcl_ListObjGetElements(interp, objv[objc-2], &mapElemc,
- &mapElemv) != TCL_OK) {
- return TCL_ERROR;
- }
- if (mapElemc == 0) {
- /*
- * empty charMap, just return whatever string was given
- */
- Tcl_SetObjResult(interp, objv[objc-1]);
- return TCL_OK;
- } else if (mapElemc & 1) {
- /*
- * The charMap must be an even number of key/value items
- */
- Tcl_SetStringObj(resultPtr, "char map list unbalanced", -1);
- return TCL_ERROR;
- }
+static int
+StringIsCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ const char *string1, *end, *stop;
+ Tcl_UniChar ch;
+ int (*chcomp)(int) = NULL; /* The UniChar comparison function. */
+ int i, failat = 0, result = 1, strict = 0, index, length1, length2;
+ Tcl_Obj *objPtr, *failVarObj = NULL;
+ Tcl_WideInt w;
+
+ static const char *isClasses[] = {
+ "alnum", "alpha", "ascii", "control",
+ "boolean", "digit", "double", "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
+ };
+ static const char *isOptions[] = {
+ "-strict", "-failindex", NULL
+ };
+ enum isOptions {
+ OPT_STRICT, OPT_FAILIDX
+ };
- /*
- * Take a copy of the source string object if it is the
- * same as the map string to cut out nasty sharing
- * crashes. [Bug 1018562]
- */
- if (objv[objc-2] == objv[objc-1]) {
- sourceObj = Tcl_DuplicateObj(objv[objc-1]);
- copySource = 1;
- } else {
- sourceObj = objv[objc-1];
+ if (objc < 3 || objc > 6) {
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "class ?-strict? ?-failindex var? str");
+ return TCL_ERROR;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[1], isClasses, "class", 0,
+ &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (objc != 3) {
+ for (i = 2; i < objc-1; i++) {
+ int idx2;
+
+ if (Tcl_GetIndexFromObj(interp, objv[i], isOptions, "option", 0,
+ &idx2) != TCL_OK) {
+ return TCL_ERROR;
}
- ustring1 = Tcl_GetUnicodeFromObj(sourceObj, &length1);
- if (length1 == 0) {
- /*
- * Empty input string, just stop now
- */
- if (copySource) {
- Tcl_DecrRefCount(sourceObj);
+ switch ((enum isOptions) idx2) {
+ case OPT_STRICT:
+ strict = 1;
+ break;
+ case OPT_FAILIDX:
+ if (i+1 >= objc-1) {
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "?-strict? ?-failindex var? str");
+ return TCL_ERROR;
}
+ failVarObj = objv[++i];
break;
}
- end = ustring1 + length1;
+ }
+ }
+
+ /*
+ * We get the objPtr so that we can short-cut for some classes by checking
+ * the object type (int and double), but we need the string otherwise,
+ * because we don't want any conversion of type occuring (as, for example,
+ * Tcl_Get*FromObj would do).
+ */
- strCmpFn = nocase ? Tcl_UniCharNcasecmp : Tcl_UniCharNcmp;
+ objPtr = objv[objc-1];
- /*
- * Force result to be Unicode
- */
- Tcl_SetUnicodeObj(resultPtr, ustring1, 0);
+ /*
+ * When entering here, result == 1 and failat == 0.
+ */
- if (mapElemc == 2) {
- /*
- * Special case for one map pair which avoids the extra
- * for loop and extra calls to get Unicode data. The
- * algorithm is otherwise identical to the multi-pair case.
- * This will be >30% faster on larger strings.
- */
- int mapLen;
- Tcl_UniChar *mapString, u2lc;
-
- ustring2 = Tcl_GetUnicodeFromObj(mapElemv[0], &length2);
- p = ustring1;
- if ((length2 > length1) || (length2 == 0)) {
- /* match string is either longer than input or empty */
- ustring1 = end;
- } else {
- mapString = Tcl_GetUnicodeFromObj(mapElemv[1], &mapLen);
- u2lc = (nocase ? Tcl_UniCharToLower(*ustring2) : 0);
- for (; ustring1 < end; ustring1++) {
- if (((*ustring1 == *ustring2) ||
- (nocase && (Tcl_UniCharToLower(*ustring1) ==
- u2lc))) &&
- ((length2 == 1) || strCmpFn(ustring1, ustring2,
- (unsigned long) length2) == 0)) {
- if (p != ustring1) {
- Tcl_AppendUnicodeToObj(resultPtr, p,
- ustring1 - p);
- p = ustring1 + length2;
- } else {
- p += length2;
- }
- ustring1 = p - 1;
-
- Tcl_AppendUnicodeToObj(resultPtr, mapString,
- mapLen);
- }
- }
- }
+ switch ((enum isClasses) index) {
+ case STR_IS_ALNUM:
+ chcomp = Tcl_UniCharIsAlnum;
+ break;
+ case STR_IS_ALPHA:
+ chcomp = Tcl_UniCharIsAlpha;
+ break;
+ case STR_IS_ASCII:
+ chcomp = UniCharIsAscii;
+ break;
+ case STR_IS_BOOL:
+ case STR_IS_TRUE:
+ case STR_IS_FALSE:
+ if (TCL_OK != Tcl_ConvertToType(NULL, objPtr, &tclBooleanType)) {
+ if (strict) {
+ result = 0;
} else {
- Tcl_UniChar **mapStrings, *u2lc = NULL;
- int *mapLens;
- /*
- * Precompute pointers to the unicode string and length.
- * This saves us repeated function calls later,
- * significantly speeding up the algorithm. We only need
- * the lowercase first char in the nocase case.
- */
- mapStrings = (Tcl_UniChar **) ckalloc((mapElemc * 2)
- * sizeof(Tcl_UniChar *));
- mapLens = (int *) ckalloc((mapElemc * 2) * sizeof(int));
- if (nocase) {
- u2lc = (Tcl_UniChar *)
- ckalloc((mapElemc) * sizeof(Tcl_UniChar));
- }
- for (index = 0; index < mapElemc; index++) {
- mapStrings[index] = Tcl_GetUnicodeFromObj(mapElemv[index],
- &(mapLens[index]));
- if (nocase && ((index % 2) == 0)) {
- u2lc[index/2] = Tcl_UniCharToLower(*mapStrings[index]);
- }
- }
- for (p = ustring1; ustring1 < end; ustring1++) {
- for (index = 0; index < mapElemc; index += 2) {
- /*
- * Get the key string to match on.
- */
- ustring2 = mapStrings[index];
- length2 = mapLens[index];
- if ((length2 > 0) && ((*ustring1 == *ustring2) ||
- (nocase && (Tcl_UniCharToLower(*ustring1) ==
- u2lc[index/2]))) &&
- /* restrict max compare length */
- ((end - ustring1) >= length2) &&
- ((length2 == 1) || strCmpFn(ustring2, ustring1,
- (unsigned long) length2) == 0)) {
- if (p != ustring1) {
- /*
- * Put the skipped chars onto the result first
- */
- Tcl_AppendUnicodeToObj(resultPtr, p,
- ustring1 - p);
- p = ustring1 + length2;
- } else {
- p += length2;
- }
- /*
- * Adjust len to be full length of matched string
- */
- ustring1 = p - 1;
-
- /*
- * Append the map value to the unicode string
- */
- Tcl_AppendUnicodeToObj(resultPtr,
- mapStrings[index+1], mapLens[index+1]);
- break;
- }
- }
- }
- ckfree((char *) mapStrings);
- ckfree((char *) mapLens);
- if (nocase) {
- ckfree((char *) u2lc);
- }
- }
- if (p != ustring1) {
- /*
- * Put the rest of the unmapped chars onto result
- */
- Tcl_AppendUnicodeToObj(resultPtr, p, ustring1 - p);
- }
- if (copySource) {
- Tcl_DecrRefCount(sourceObj);
- }
+ string1 = TclGetStringFromObj(objPtr, &length1);
+ result = length1 == 0;
+ }
+ } else if (((index == STR_IS_TRUE) &&
+ objPtr->internalRep.longValue == 0)
+ || ((index == STR_IS_FALSE) &&
+ objPtr->internalRep.longValue != 0)) {
+ result = 0;
+ }
+ break;
+ case STR_IS_CONTROL:
+ chcomp = Tcl_UniCharIsControl;
+ break;
+ case STR_IS_DIGIT:
+ chcomp = Tcl_UniCharIsDigit;
+ break;
+ case STR_IS_DOUBLE: {
+ /* TODO */
+ if ((objPtr->typePtr == &tclDoubleType) ||
+ (objPtr->typePtr == &tclIntType) ||
+#ifndef NO_WIDE_TYPE
+ (objPtr->typePtr == &tclWideIntType) ||
+#endif
+ (objPtr->typePtr == &tclBignumType)) {
break;
}
- case STR_MATCH: {
- Tcl_UniChar *ustring1, *ustring2;
- int nocase = 0;
-
- if (objc < 4 || objc > 5) {
- Tcl_WrongNumArgs(interp, 2, objv, "?-nocase? pattern string");
- return TCL_ERROR;
+ string1 = TclGetStringFromObj(objPtr, &length1);
+ if (length1 == 0) {
+ if (strict) {
+ result = 0;
}
-
- if (objc == 5) {
- string2 = Tcl_GetStringFromObj(objv[2], &length2);
- if ((length2 > 1) &&
- strncmp(string2, "-nocase", (size_t) length2) == 0) {
- nocase = 1;
- } else {
- Tcl_AppendStringsToObj(resultPtr, "bad option \"",
- string2, "\": must be -nocase",
- (char *) NULL);
- return TCL_ERROR;
- }
+ goto str_is_done;
+ }
+ end = string1 + length1;
+ if (TclParseNumber(NULL, objPtr, NULL, NULL, -1,
+ (const char **) &stop, 0) != TCL_OK) {
+ result = 0;
+ failat = 0;
+ } else {
+ failat = stop - string1;
+ if (stop < end) {
+ result = 0;
+ TclFreeIntRep(objPtr);
+ objPtr->typePtr = NULL;
}
- ustring1 = Tcl_GetUnicodeFromObj(objv[objc-1], &length1);
- ustring2 = Tcl_GetUnicodeFromObj(objv[objc-2], &length2);
- Tcl_SetBooleanObj(resultPtr, TclUniCharMatch(ustring1, length1,
- ustring2, length2, nocase));
+ }
+ break;
+ }
+ case STR_IS_GRAPH:
+ chcomp = Tcl_UniCharIsGraph;
+ break;
+ case STR_IS_INT:
+ if (TCL_OK == TclGetIntFromObj(NULL, objPtr, &i)) {
+ break;
+ }
+ goto failedIntParse;
+ case STR_IS_WIDE:
+ if (TCL_OK == Tcl_GetWideIntFromObj(NULL, objPtr, &w)) {
break;
}
- case STR_RANGE: {
- int first, last;
- if (objc != 5) {
- Tcl_WrongNumArgs(interp, 2, objv, "string first last");
- return TCL_ERROR;
+ failedIntParse:
+ string1 = TclGetStringFromObj(objPtr, &length1);
+ if (length1 == 0) {
+ if (strict) {
+ result = 0;
}
-
+ goto str_is_done;
+ }
+ result = 0;
+ if (failVarObj == NULL) {
/*
- * If we have a ByteArray object, avoid indexing in the
- * Utf string since the byte array contains one byte per
- * character. Otherwise, use the Unicode string rep to
- * get the range.
+ * Don't bother computing the failure point if we're not going to
+ * return it.
*/
- if (objv[2]->typePtr == &tclByteArrayType) {
- string1 = (char *)Tcl_GetByteArrayFromObj(objv[2], &length1);
- length1--;
+ break;
+ }
+ 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, but rejected by
+ * Tcl_Get(Wide)IntFromObj() so we must have overflowed the
+ * target type, and our convention is to return failure at
+ * index -1 in that situation.
+ */
+
+ failat = -1;
} else {
/*
- * Get the length in actual characters.
+ * 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.
*/
- string1 = NULL;
- length1 = Tcl_GetCharLength(objv[2]) - 1;
- }
- if ((TclGetIntForIndex(interp, objv[3], length1, &first) != TCL_OK)
- || (TclGetIntForIndex(interp, objv[4], length1,
- &last) != TCL_OK)) {
- return TCL_ERROR;
+ failat = stop - string1;
+ TclFreeIntRep(objPtr);
+ objPtr->typePtr = NULL;
}
+ } else {
+ /*
+ * No prefix is a valid integer. Fail at beginning.
+ */
- if (first < 0) {
- first = 0;
- }
- if (last >= length1) {
- last = length1;
- }
- if (last >= first) {
- if (string1 != NULL) {
- int numBytes = last - first + 1;
- resultPtr = Tcl_NewByteArrayObj(
- (unsigned char *) &string1[first], numBytes);
- Tcl_SetObjResult(interp, resultPtr);
- } else {
- Tcl_SetObjResult(interp,
- Tcl_GetRange(objv[2], first, last));
- }
- }
+ failat = 0;
+ }
+ break;
+ case STR_IS_LIST:
+ /*
+ * We ignore the strictness here, since empty strings are always
+ * well-formed lists.
+ */
+
+ if (TCL_OK == TclListObjLength(NULL, objPtr, &length2)) {
break;
}
- case STR_REPEAT: {
- int count;
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "string count");
- return TCL_ERROR;
- }
+ if (failVarObj != NULL) {
+ /*
+ * Need to figure out where the list parsing failed, which is
+ * fairly expensive. This is adapted from the core of
+ * SetListFromAny().
+ */
- if (Tcl_GetIntFromObj(interp, objv[3], &count) != TCL_OK) {
- return TCL_ERROR;
- }
+ const char *elemStart, *nextElem;
+ int lenRemain, elemSize;
+ register const char *p;
+
+ string1 = TclGetStringFromObj(objPtr, &length1);
+ end = string1 + length1;
+ failat = -1;
+ for (p=string1, lenRemain=length1; lenRemain > 0;
+ p=nextElem, lenRemain=end-nextElem) {
+ if (TCL_ERROR == TclFindElement(NULL, p, lenRemain,
+ &elemStart, &nextElem, &elemSize, NULL)) {
+ Tcl_Obj *tmpStr;
- if (count == 1) {
- Tcl_SetObjResult(interp, objv[2]);
- } else if (count > 1) {
- string1 = Tcl_GetStringFromObj(objv[2], &length1);
- if (length1 > 0) {
- /*
- * Only build up a string that has data. Instead of
- * building it up with repeated appends, we just allocate
- * the necessary space once and copy the string value in.
- * Check for overflow with back-division. [Bug #714106]
- */
- length2 = length1 * count;
- if ((length2 / count) != length1) {
- char buf[TCL_INTEGER_SPACE+1];
- sprintf(buf, "%d", INT_MAX);
- Tcl_AppendStringsToObj(resultPtr,
- "string size overflow, must be less than ",
- buf, (char *) NULL);
- return TCL_ERROR;
- }
/*
- * Include space for the NULL
+ * This is the simplest way of getting the number of
+ * characters parsed. Note that this is not the same as
+ * the number of bytes when parsing strings with non-ASCII
+ * characters in them.
+ *
+ * Skip leading spaces first. This is only really an issue
+ * if it is the first "element" that has the failure.
*/
- string2 = (char *) ckalloc((size_t) length2+1);
- for (index = 0; index < count; index++) {
- memcpy(string2 + (length1 * index), string1,
- (size_t) length1);
+
+ while (TclIsSpaceProc(*p)) {
+ p++;
}
- string2[length2] = '\0';
- /*
- * We have to directly assign this instead of using
- * Tcl_SetStringObj (and indirectly TclInitStringRep)
- * because that makes another copy of the data.
- */
- resultPtr = Tcl_NewObj();
- resultPtr->bytes = string2;
- resultPtr->length = length2;
- Tcl_SetObjResult(interp, resultPtr);
+ TclNewStringObj(tmpStr, string1, p-string1);
+ failat = Tcl_GetCharLength(tmpStr);
+ TclDecrRefCount(tmpStr);
+ break;
}
}
- break;
}
- case STR_REPLACE: {
- Tcl_UniChar *ustring1;
- int first, last;
-
- if (objc < 5 || objc > 6) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "string first last ?string?");
- return TCL_ERROR;
+ result = 0;
+ break;
+ case STR_IS_LOWER:
+ chcomp = Tcl_UniCharIsLower;
+ break;
+ case STR_IS_PRINT:
+ chcomp = Tcl_UniCharIsPrint;
+ break;
+ case STR_IS_PUNCT:
+ chcomp = Tcl_UniCharIsPunct;
+ break;
+ case STR_IS_SPACE:
+ chcomp = Tcl_UniCharIsSpace;
+ break;
+ case STR_IS_UPPER:
+ chcomp = Tcl_UniCharIsUpper;
+ break;
+ case STR_IS_WORD:
+ chcomp = Tcl_UniCharIsWordChar;
+ break;
+ case STR_IS_XDIGIT:
+ chcomp = UniCharIsHexDigit;
+ break;
+ }
+
+ if (chcomp != NULL) {
+ string1 = TclGetStringFromObj(objPtr, &length1);
+ if (length1 == 0) {
+ if (strict) {
+ result = 0;
+ }
+ goto str_is_done;
+ }
+ end = string1 + length1;
+ for (; string1 < end; string1 += length2, failat++) {
+ length2 = TclUtfToUniChar(string1, &ch);
+ if (!chcomp(ch)) {
+ result = 0;
+ break;
}
+ }
+ }
- ustring1 = Tcl_GetUnicodeFromObj(objv[2], &length1);
- length1--;
+ /*
+ * Only set the failVarObj when we will return 0 and we have indicated a
+ * valid fail index (>= 0).
+ */
- if ((TclGetIntForIndex(interp, objv[3], length1, &first) != TCL_OK)
- || (TclGetIntForIndex(interp, objv[4], length1,
- &last) != TCL_OK)) {
- return TCL_ERROR;
- }
+ str_is_done:
+ if ((result == 0) && (failVarObj != NULL) &&
+ Tcl_ObjSetVar2(interp, failVarObj, NULL, Tcl_NewIntObj(failat),
+ TCL_LEAVE_ERR_MSG) == NULL) {
+ return TCL_ERROR;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(result));
+ return TCL_OK;
+}
- if ((last < first) || (last < 0) || (first > length1)) {
- Tcl_SetObjResult(interp, objv[2]);
- } else {
- if (first < 0) {
- first = 0;
- }
+static int
+UniCharIsAscii(
+ int character)
+{
+ return (character >= 0) && (character < 0x80);
+}
- Tcl_SetUnicodeObj(resultPtr, ustring1, first);
- if (objc == 6) {
- Tcl_AppendObjToObj(resultPtr, objv[5]);
- }
- if (last < length1) {
- Tcl_AppendUnicodeToObj(resultPtr, ustring1 + last + 1,
- length1 - last);
- }
- }
- break;
- }
- case STR_TOLOWER:
- case STR_TOUPPER:
- case STR_TOTITLE:
- if (objc < 3 || objc > 5) {
- Tcl_WrongNumArgs(interp, 2, objv, "string ?first? ?last?");
- return TCL_ERROR;
- }
+static int
+UniCharIsHexDigit(
+ int character)
+{
+ return (character >= 0) && (character < 0x80) && isxdigit(character);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringMapCmd --
+ *
+ * This procedure is invoked to process the "string map" Tcl command. See
+ * the user documentation for details on what it does. Note that this
+ * command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
- string1 = Tcl_GetStringFromObj(objv[2], &length1);
+static int
+StringMapCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ int length1, length2, mapElemc, index;
+ int nocase = 0, mapWithDict = 0, copySource = 0;
+ Tcl_Obj **mapElemv, *sourceObj, *resultPtr;
+ Tcl_UniChar *ustring1, *ustring2, *p, *end;
+ int (*strCmpFn)(const Tcl_UniChar*, const Tcl_UniChar*, unsigned long);
+
+ if (objc < 3 || objc > 4) {
+ Tcl_WrongNumArgs(interp, 1, objv, "?-nocase? charMap string");
+ return TCL_ERROR;
+ }
- if (objc == 3) {
- /*
- * Since the result object is not a shared object, it is
- * safe to copy the string into the result and do the
- * conversion in place. The conversion may change the length
- * of the string, so reset the length after conversion.
- */
+ if (objc == 4) {
+ const char *string = TclGetStringFromObj(objv[1], &length2);
- Tcl_SetStringObj(resultPtr, string1, length1);
- if ((enum options) index == STR_TOLOWER) {
- length1 = Tcl_UtfToLower(Tcl_GetString(resultPtr));
- } else if ((enum options) index == STR_TOUPPER) {
- length1 = Tcl_UtfToUpper(Tcl_GetString(resultPtr));
- } else {
- length1 = Tcl_UtfToTitle(Tcl_GetString(resultPtr));
- }
- Tcl_SetObjLength(resultPtr, length1);
- } else {
- int first, last;
- CONST char *start, *end;
+ if ((length2 > 1) &&
+ strncmp(string, "-nocase", (size_t) length2) == 0) {
+ nocase = 1;
+ } else {
+ Tcl_AppendResult(interp, "bad option \"", string,
+ "\": must be -nocase", NULL);
+ return TCL_ERROR;
+ }
+ }
- length1 = Tcl_NumUtfChars(string1, length1) - 1;
- if (TclGetIntForIndex(interp, objv[3], length1,
- &first) != TCL_OK) {
- return TCL_ERROR;
- }
- if (first < 0) {
- first = 0;
- }
- last = first;
- if ((objc == 5) && (TclGetIntForIndex(interp, objv[4], length1,
- &last) != TCL_OK)) {
- return TCL_ERROR;
- }
- if (last >= length1) {
- last = length1;
- }
- if (last < first) {
- Tcl_SetObjResult(interp, objv[2]);
- break;
- }
- start = Tcl_UtfAtIndex(string1, first);
- end = Tcl_UtfAtIndex(start, last - first + 1);
- length2 = end-start;
- string2 = ckalloc((size_t) length2+1);
- memcpy(string2, start, (size_t) length2);
- string2[length2] = '\0';
- if ((enum options) index == STR_TOLOWER) {
- length2 = Tcl_UtfToLower(string2);
- } else if ((enum options) index == STR_TOUPPER) {
- length2 = Tcl_UtfToUpper(string2);
- } else {
- length2 = Tcl_UtfToTitle(string2);
- }
- Tcl_SetStringObj(resultPtr, string1, start - string1);
- Tcl_AppendToObj(resultPtr, string2, length2);
- Tcl_AppendToObj(resultPtr, end, -1);
- ckfree(string2);
- }
- break;
+ /*
+ * This test is tricky, but has to be that way or you get other strange
+ * inconsistencies (see test string-10.20 for illustration why!)
+ */
- case STR_TRIM: {
- Tcl_UniChar ch, trim;
- register CONST char *p, *end;
- char *check, *checkEnd;
- int offset;
-
- left = 1;
- right = 1;
-
- dotrim:
- if (objc == 4) {
- string2 = Tcl_GetStringFromObj(objv[3], &length2);
- } else if (objc == 3) {
- string2 = " \t\n\r";
- length2 = strlen(string2);
- } else {
- Tcl_WrongNumArgs(interp, 2, objv, "string ?chars?");
- return TCL_ERROR;
- }
- string1 = Tcl_GetStringFromObj(objv[2], &length1);
- checkEnd = string2 + length2;
+ if (objv[objc-2]->typePtr == &tclDictType && objv[objc-2]->bytes == NULL){
+ int i, done;
+ Tcl_DictSearch search;
- if (left) {
- end = string1 + length1;
- /*
- * The outer loop iterates over the string. The inner
- * loop iterates over the trim characters. The loops
- * terminate as soon as a non-trim character is discovered
- * and string1 is left pointing at the first non-trim
- * character.
- */
+ /*
+ * We know the type exactly, so all dict operations will succeed for
+ * sure. This shortens this code quite a bit.
+ */
- for (p = string1; p < end; p += offset) {
- offset = TclUtfToUniChar(p, &ch);
-
- for (check = string2; ; ) {
- if (check >= checkEnd) {
- p = end;
- break;
- }
- check += TclUtfToUniChar(check, &trim);
- if (ch == trim) {
- length1 -= offset;
- string1 += offset;
- break;
- }
- }
- }
- }
- if (right) {
- end = string1;
+ Tcl_DictObjSize(interp, objv[objc-2], &mapElemc);
+ if (mapElemc == 0) {
+ /*
+ * Empty charMap, just return whatever string was given.
+ */
- /*
- * The outer loop iterates over the string. The inner
- * loop iterates over the trim characters. The loops
- * terminate as soon as a non-trim character is discovered
- * and length1 marks the last non-trim character.
- */
+ Tcl_SetObjResult(interp, objv[objc-1]);
+ return TCL_OK;
+ }
- for (p = string1 + length1; p > end; ) {
- p = Tcl_UtfPrev(p, string1);
- offset = TclUtfToUniChar(p, &ch);
- for (check = string2; ; ) {
- if (check >= checkEnd) {
- p = end;
- break;
- }
- check += TclUtfToUniChar(check, &trim);
- if (ch == trim) {
- length1 -= offset;
- break;
- }
- }
- }
- }
- Tcl_SetStringObj(resultPtr, string1, length1);
- break;
+ mapElemc *= 2;
+ mapWithDict = 1;
+
+ /*
+ * Copy the dictionary out into an array; that's the easiest way to
+ * adapt this code...
+ */
+
+ mapElemv = (Tcl_Obj **)
+ TclStackAlloc(interp, sizeof(Tcl_Obj *) * mapElemc);
+ Tcl_DictObjFirst(interp, objv[objc-2], &search, mapElemv+0,
+ mapElemv+1, &done);
+ for (i=2 ; i<mapElemc ; i+=2) {
+ Tcl_DictObjNext(&search, mapElemv+i, mapElemv+i+1, &done);
}
- case STR_TRIMLEFT: {
- left = 1;
- right = 0;
- goto dotrim;
+ Tcl_DictObjDone(&search);
+ } else {
+ if (TclListObjGetElements(interp, objv[objc-2], &mapElemc,
+ &mapElemv) != TCL_OK) {
+ return TCL_ERROR;
}
- case STR_TRIMRIGHT: {
- left = 0;
- right = 1;
- goto dotrim;
+ if (mapElemc == 0) {
+ /*
+ * empty charMap, just return whatever string was given.
+ */
+
+ Tcl_SetObjResult(interp, objv[objc-1]);
+ return TCL_OK;
+ } else if (mapElemc & 1) {
+ /*
+ * The charMap must be an even number of key/value items.
+ */
+
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj("char map list unbalanced", -1));
+ return TCL_ERROR;
}
- case STR_WORDEND: {
- int cur;
- Tcl_UniChar ch;
- CONST char *p, *end;
- int numChars;
-
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "string index");
- return TCL_ERROR;
- }
+ }
- string1 = Tcl_GetStringFromObj(objv[2], &length1);
- numChars = Tcl_NumUtfChars(string1, length1);
- if (TclGetIntForIndex(interp, objv[3], numChars-1,
- &index) != TCL_OK) {
- return TCL_ERROR;
- }
- if (index < 0) {
- index = 0;
- }
- if (index < numChars) {
- p = Tcl_UtfAtIndex(string1, index);
- end = string1+length1;
- for (cur = index; p < end; cur++) {
- p += TclUtfToUniChar(p, &ch);
- if (!Tcl_UniCharIsWordChar(ch)) {
- break;
+ /*
+ * Take a copy of the source string object if it is the same as the map
+ * string to cut out nasty sharing crashes. [Bug 1018562]
+ */
+
+ if (objv[objc-2] == objv[objc-1]) {
+ sourceObj = Tcl_DuplicateObj(objv[objc-1]);
+ copySource = 1;
+ } else {
+ sourceObj = objv[objc-1];
+ }
+ ustring1 = Tcl_GetUnicodeFromObj(sourceObj, &length1);
+ if (length1 == 0) {
+ /*
+ * Empty input string, just stop now.
+ */
+
+ goto done;
+ }
+ end = ustring1 + length1;
+
+ strCmpFn = (nocase ? Tcl_UniCharNcasecmp : Tcl_UniCharNcmp);
+
+ /*
+ * Force result to be Unicode
+ */
+
+ resultPtr = Tcl_NewUnicodeObj(ustring1, 0);
+
+ if (mapElemc == 2) {
+ /*
+ * Special case for one map pair which avoids the extra for loop and
+ * extra calls to get Unicode data. The algorithm is otherwise
+ * identical to the multi-pair case. This will be >30% faster on
+ * larger strings.
+ */
+
+ int mapLen;
+ Tcl_UniChar *mapString, u2lc;
+
+ ustring2 = Tcl_GetUnicodeFromObj(mapElemv[0], &length2);
+ p = ustring1;
+ if ((length2 > length1) || (length2 == 0)) {
+ /*
+ * Match string is either longer than input or empty.
+ */
+
+ ustring1 = end;
+ } else {
+ mapString = Tcl_GetUnicodeFromObj(mapElemv[1], &mapLen);
+ u2lc = (nocase ? Tcl_UniCharToLower(*ustring2) : 0);
+ for (; ustring1 < end; ustring1++) {
+ if (((*ustring1 == *ustring2) ||
+ (nocase&&Tcl_UniCharToLower(*ustring1)==u2lc)) &&
+ (length2==1 || strCmpFn(ustring1, ustring2,
+ (unsigned long) length2) == 0)) {
+ if (p != ustring1) {
+ Tcl_AppendUnicodeToObj(resultPtr, p, ustring1-p);
+ p = ustring1 + length2;
+ } else {
+ p += length2;
}
+ ustring1 = p - 1;
+
+ Tcl_AppendUnicodeToObj(resultPtr, mapString, mapLen);
}
- if (cur == index) {
- cur++;
- }
- } else {
- cur = numChars;
}
- Tcl_SetIntObj(resultPtr, cur);
- break;
}
- case STR_WORDSTART: {
- int cur;
- Tcl_UniChar ch;
- CONST char *p;
- int numChars;
-
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "string index");
- return TCL_ERROR;
- }
+ } else {
+ Tcl_UniChar **mapStrings, *u2lc = NULL;
+ int *mapLens;
- string1 = Tcl_GetStringFromObj(objv[2], &length1);
- numChars = Tcl_NumUtfChars(string1, length1);
- if (TclGetIntForIndex(interp, objv[3], numChars-1,
- &index) != TCL_OK) {
- return TCL_ERROR;
- }
- if (index >= numChars) {
- index = numChars - 1;
+ /*
+ * Precompute pointers to the unicode string and length. This saves us
+ * repeated function calls later, significantly speeding up the
+ * algorithm. We only need the lowercase first char in the nocase
+ * case.
+ */
+
+ mapStrings = (Tcl_UniChar **) TclStackAlloc(interp,
+ mapElemc * 2 * sizeof(Tcl_UniChar *));
+ mapLens = (int *) TclStackAlloc(interp, mapElemc * 2 * sizeof(int));
+ if (nocase) {
+ u2lc = (Tcl_UniChar *) TclStackAlloc(interp,
+ mapElemc * sizeof(Tcl_UniChar));
+ }
+ for (index = 0; index < mapElemc; index++) {
+ mapStrings[index] = Tcl_GetUnicodeFromObj(mapElemv[index],
+ mapLens+index);
+ if (nocase && ((index % 2) == 0)) {
+ u2lc[index/2] = Tcl_UniCharToLower(*mapStrings[index]);
}
- cur = 0;
- if (index > 0) {
- p = Tcl_UtfAtIndex(string1, index);
- for (cur = index; cur >= 0; cur--) {
- TclUtfToUniChar(p, &ch);
- if (!Tcl_UniCharIsWordChar(ch)) {
- break;
+ }
+ for (p = ustring1; ustring1 < end; ustring1++) {
+ for (index = 0; index < mapElemc; index += 2) {
+ /*
+ * Get the key string to match on.
+ */
+
+ ustring2 = mapStrings[index];
+ length2 = mapLens[index];
+ if ((length2 > 0) && ((*ustring1 == *ustring2) || (nocase &&
+ (Tcl_UniCharToLower(*ustring1) == u2lc[index/2]))) &&
+ /* Restrict max compare length. */
+ (end-ustring1 >= length2) && ((length2 == 1) ||
+ !strCmpFn(ustring2, ustring1, (unsigned) length2))) {
+ if (p != ustring1) {
+ /*
+ * Put the skipped chars onto the result first.
+ */
+
+ Tcl_AppendUnicodeToObj(resultPtr, p, ustring1-p);
+ p = ustring1 + length2;
+ } else {
+ p += length2;
}
- p = Tcl_UtfPrev(p, string1);
- }
- if (cur != index) {
- cur += 1;
+
+ /*
+ * Adjust len to be full length of matched string.
+ */
+
+ ustring1 = p - 1;
+
+ /*
+ * Append the map value to the unicode string.
+ */
+
+ Tcl_AppendUnicodeToObj(resultPtr,
+ mapStrings[index+1], mapLens[index+1]);
+ break;
}
}
- Tcl_SetIntObj(resultPtr, cur);
- break;
}
+ if (nocase) {
+ TclStackFree(interp, u2lc);
+ }
+ TclStackFree(interp, mapLens);
+ TclStackFree(interp, mapStrings);
+ }
+ if (p != ustring1) {
+ /*
+ * Put the rest of the unmapped chars onto result.
+ */
+
+ Tcl_AppendUnicodeToObj(resultPtr, p, ustring1 - p);
+ }
+ Tcl_SetObjResult(interp, resultPtr);
+ done:
+ if (mapWithDict) {
+ TclStackFree(interp, mapElemv);
+ }
+ if (copySource) {
+ Tcl_DecrRefCount(sourceObj);
}
return TCL_OK;
}
@@ -2464,11 +2000,11 @@ Tcl_StringObjCmd(dummy, interp, objc, objv)
/*
*----------------------------------------------------------------------
*
- * Tcl_SubstObjCmd --
+ * StringMatchCmd --
*
- * This procedure is invoked to process the "subst" Tcl command.
- * See the user documentation for details on what it does. This
- * command relies on Tcl_SubstObj() for its implementation.
+ * This procedure is invoked to process the "string match" Tcl command.
+ * See the user documentation for details on what it does. Note that this
+ * command only functions correctly on properly formed Tcl UTF strings.
*
* Results:
* A standard Tcl result.
@@ -2479,94 +2015,49 @@ Tcl_StringObjCmd(dummy, interp, objc, objv)
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
-int
-Tcl_SubstObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+static int
+StringMatchCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- static CONST char *substOptions[] = {
- "-nobackslashes", "-nocommands", "-novariables", (char *) NULL
- };
- enum substOptions {
- SUBST_NOBACKSLASHES, SUBST_NOCOMMANDS, SUBST_NOVARS
- };
- Tcl_Obj *resultPtr;
- int optionIndex, flags, i;
+ int nocase = 0;
- /*
- * Parse command-line options.
- */
-
- flags = TCL_SUBST_ALL;
- for (i = 1; i < (objc-1); i++) {
- if (Tcl_GetIndexFromObj(interp, objv[i], substOptions,
- "switch", 0, &optionIndex) != TCL_OK) {
-
- return TCL_ERROR;
- }
- switch (optionIndex) {
- case SUBST_NOBACKSLASHES: {
- flags &= ~TCL_SUBST_BACKSLASHES;
- break;
- }
- case SUBST_NOCOMMANDS: {
- flags &= ~TCL_SUBST_COMMANDS;
- break;
- }
- case SUBST_NOVARS: {
- flags &= ~TCL_SUBST_VARIABLES;
- break;
- }
- default: {
- panic("Tcl_SubstObjCmd: bad option index to SubstOptions");
- }
- }
- }
- if (i != (objc-1)) {
- Tcl_WrongNumArgs(interp, 1, objv,
- "?-nobackslashes? ?-nocommands? ?-novariables? string");
+ if (objc < 3 || objc > 4) {
+ Tcl_WrongNumArgs(interp, 1, objv, "?-nocase? pattern string");
return TCL_ERROR;
}
- /*
- * Perform the substitution.
- */
- resultPtr = Tcl_SubstObj(interp, objv[i], flags);
+ if (objc == 4) {
+ int length;
+ const char *string = TclGetStringFromObj(objv[1], &length);
- if (resultPtr == NULL) {
- return TCL_ERROR;
+ if ((length > 1) &&
+ strncmp(string, "-nocase", (size_t) length) == 0) {
+ nocase = TCL_MATCH_NOCASE;
+ } else {
+ Tcl_AppendResult(interp, "bad option \"", string,
+ "\": must be -nocase", NULL);
+ return TCL_ERROR;
+ }
}
- Tcl_SetObjResult(interp, resultPtr);
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
+ TclStringMatchObj(objv[objc-1], objv[objc-2], nocase)));
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
- * Tcl_SubstObj --
- *
- * This function performs the substitutions specified on the
- * given string as described in the user documentation for the
- * "subst" Tcl command. This code is heavily based on an
- * implementation by Andrew Payne. Note that if a command
- * substitution returns TCL_CONTINUE or TCL_RETURN from its
- * evaluation and is not completely well-formed, the results are
- * not defined (or at least hard to characterise.) This fault
- * will be fixed at some point, but the cost of the only sane
- * fix (well-formedness check first) is such that you need to
- * "precompile and cache" to stop everyone from being hit with
- * the consequences every time through. Note that the current
- * behaviour is not a security hole; it just restarts parsing
- * the string following the substitution in a mildly surprising
- * place, and it is a very bad idea to count on this remaining
- * the same in future...
+ * StringRangeCmd --
+ *
+ * This procedure is invoked to process the "string range" Tcl command.
+ * See the user documentation for details on what it does. Note that this
+ * command only functions correctly on properly formed Tcl UTF strings.
*
* Results:
- * A Tcl_Obj* containing the substituted string, or NULL to
- * indicate that an error occurred.
+ * A standard Tcl result.
*
* Side effects:
* See the user documentation.
@@ -2574,144 +2065,77 @@ Tcl_SubstObjCmd(dummy, interp, objc, objv)
*----------------------------------------------------------------------
*/
-Tcl_Obj *
-Tcl_SubstObj(interp, objPtr, flags)
- Tcl_Interp *interp;
- Tcl_Obj *objPtr;
- int flags;
+static int
+StringRangeCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- Tcl_Obj *resultObj;
- char *p, *old;
- int length;
+ const unsigned char *string;
+ int length, first, last;
- old = p = Tcl_GetStringFromObj(objPtr, &length);
- resultObj = Tcl_NewStringObj("", 0);
- while (length) {
- switch (*p) {
- case '\\':
- if (flags & TCL_SUBST_BACKSLASHES) {
- char buf[TCL_UTF_MAX];
- int count;
-
- if (p != old) {
- Tcl_AppendToObj(resultObj, old, p-old);
- }
- Tcl_AppendToObj(resultObj, buf,
- TclParseBackslash(p, length, &count, buf));
- p += count; length -= count;
- old = p;
- } else {
- p++; length--;
- }
- break;
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 1, objv, "string first last");
+ return TCL_ERROR;
+ }
- case '$':
- if (flags & TCL_SUBST_VARIABLES) {
- Tcl_Parse parse;
- int code;
+ /*
+ * If we have a ByteArray object, avoid indexing in the Utf string since
+ * the byte array contains one byte per character. Otherwise, use the
+ * Unicode string rep to get the range.
+ */
- /*
- * Code is simpler overall if we (effectively) inline
- * Tcl_ParseVar, particularly as that allows us to use
- * a non-string interface when we come to appending
- * the variable contents to the result object. There
- * are a few other optimisations that doing this
- * enables (like being able to continue the run of
- * unsubstituted characters straight through if a '$'
- * does not precede a variable name.)
- */
- if (Tcl_ParseVarName(interp, p, length, &parse, 0) != TCL_OK) {
- goto errorResult;
- }
- if (parse.numTokens == 1) {
- /*
- * There isn't a variable name after all: the $ is
- * just a $.
- */
- p++; length--;
- break;
- }
- if (p != old) {
- Tcl_AppendToObj(resultObj, old, p-old);
- }
- p += parse.tokenPtr->size;
- length -= parse.tokenPtr->size;
- code = Tcl_EvalTokensStandard(interp, parse.tokenPtr,
- parse.numTokens);
- if (code == TCL_ERROR) {
- goto errorResult;
- }
- if (code == TCL_BREAK) {
- Tcl_ResetResult(interp);
- return resultObj;
- }
- if (code != TCL_CONTINUE) {
- Tcl_AppendObjToObj(resultObj, Tcl_GetObjResult(interp));
- }
- Tcl_ResetResult(interp);
- old = p;
- } else {
- p++; length--;
- }
- break;
+ if (objv[1]->typePtr == &tclByteArrayType) {
+ string = Tcl_GetByteArrayFromObj(objv[1], &length);
+ length--;
+ } else {
+ /*
+ * Get the length in actual characters.
+ */
- case '[':
- if (flags & TCL_SUBST_COMMANDS) {
- Interp *iPtr = (Interp *) interp;
- int code;
+ string = NULL;
+ length = Tcl_GetCharLength(objv[1]) - 1;
+ }
- if (p != old) {
- Tcl_AppendToObj(resultObj, old, p-old);
- }
- iPtr->evalFlags = TCL_BRACKET_TERM;
- iPtr->numLevels++;
- code = TclInterpReady(interp);
- if (code == TCL_OK) {
- code = Tcl_EvalEx(interp, p+1, length-1, 0);
- }
- iPtr->numLevels--;
- switch (code) {
- case TCL_ERROR:
- goto errorResult;
- case TCL_BREAK:
- Tcl_ResetResult(interp);
- return resultObj;
- default:
- Tcl_AppendObjToObj(resultObj, Tcl_GetObjResult(interp));
- case TCL_CONTINUE:
- Tcl_ResetResult(interp);
- old = p = (p+1 + iPtr->termOffset + 1);
- length -= (iPtr->termOffset + 2);
- }
- } else {
- p++; length--;
- }
- break;
- default:
- p++; length--;
- break;
- }
+ if (TclGetIntForIndexM(interp, objv[2], length, &first) != TCL_OK ||
+ TclGetIntForIndexM(interp, objv[3], length, &last) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ if (first < 0) {
+ first = 0;
}
- if (p != old) {
- Tcl_AppendToObj(resultObj, old, p-old);
+ if (last >= length) {
+ last = length;
}
- return resultObj;
+ if (last >= first) {
+ if (string != NULL) {
+ /*
+ * Reread the string to prevent shimmering nasties.
+ */
- errorResult:
- Tcl_DecrRefCount(resultObj);
- return NULL;
+ string = Tcl_GetByteArrayFromObj(objv[1], &length);
+ Tcl_SetObjResult(interp,
+ Tcl_NewByteArrayObj(string+first, last - first + 1));
+ } else {
+ Tcl_SetObjResult(interp, Tcl_GetRange(objv[1], first, last));
+ }
+ }
+ return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
- * Tcl_SwitchObjCmd --
+ * StringReptCmd --
*
- * This object-based procedure is invoked to process the "switch" Tcl
- * command. See the user documentation for details on what it does.
+ * This procedure is invoked to process the "string repeat" Tcl command.
+ * See the user documentation for details on what it does. Note that this
+ * command only functions correctly on properly formed Tcl UTF strings.
*
* Results:
- * A standard Tcl object result.
+ * A standard Tcl result.
*
* Side effects:
* See the user documentation.
@@ -2719,263 +2143,159 @@ Tcl_SubstObj(interp, objPtr, flags)
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
-int
-Tcl_SwitchObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+static int
+StringReptCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- int i, j, index, mode, matched, result, splitObjs;
- char *string, *pattern;
- Tcl_Obj *stringObj;
- Tcl_Obj *CONST *savedObjv = objv;
-#ifdef TCL_TIP280
- Interp* iPtr = (Interp*) interp;
- int pc = 0;
- int bidx = 0; /* Index of body argument */
- Tcl_Obj* blist = NULL; /* List obj which is the body */
- CmdFrame ctx; /* Copy of the topmost cmdframe,
- * to allow us to mess with the
- * line information */
-#endif
- static CONST char *options[] = {
- "-exact", "-glob", "-regexp", "--",
- NULL
- };
- enum options {
- OPT_EXACT, OPT_GLOB, OPT_REGEXP, OPT_LAST
- };
+ const char *string1;
+ char *string2;
+ int count, index, length1, length2;
+ Tcl_Obj *resultPtr;
- mode = OPT_EXACT;
- for (i = 1; i < objc; i++) {
- string = Tcl_GetString(objv[i]);
- if (string[0] != '-') {
- break;
- }
- if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0,
- &index) != TCL_OK) {
- return TCL_ERROR;
- }
- if (index == OPT_LAST) {
- i++;
- break;
- }
- mode = index;
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "string count");
+ return TCL_ERROR;
}
- if (objc - i < 2) {
- Tcl_WrongNumArgs(interp, 1, objv,
- "?switches? string pattern body ... ?default body?");
+ if (TclGetIntFromObj(interp, objv[2], &count) != TCL_OK) {
return TCL_ERROR;
}
- stringObj = objv[i];
- objc -= i + 1;
- objv += i + 1;
-#ifdef TCL_TIP280
- bidx = i+1; /* First after the match string */
-#endif
-
/*
- * If all of the pattern/command pairs are lumped into a single
- * argument, split them out again.
- *
- * TIP #280: Determine the lines the words in the list start at, based on
- * the same data for the list word itself. The cmdFramePtr line information
- * is manipulated directly.
+ * Check for cases that allow us to skip copying stuff.
*/
- splitObjs = 0;
- if (objc == 1) {
- Tcl_Obj **listv;
-#ifdef TCL_TIP280
- blist = objv[0];
-#endif
- if (Tcl_ListObjGetElements(interp, objv[0], &objc, &listv) != TCL_OK) {
- return TCL_ERROR;
- }
+ if (count == 1) {
+ Tcl_SetObjResult(interp, objv[1]);
+ goto done;
+ } else if (count < 1) {
+ goto done;
+ }
+ string1 = TclGetStringFromObj(objv[1], &length1);
+ if (length1 <= 0) {
+ goto done;
+ }
- /*
- * Ensure that the list is non-empty.
- */
+ /*
+ * Only build up a string that has data. Instead of building it up with
+ * repeated appends, we just allocate the necessary space once and copy
+ * the string value in.
+ *
+ * We have to worry about overflow [Bugs 714106, 2561746].
+ * At this point we know 1 <= length1 <= INT_MAX and 2 <= count <= INT_MAX.
+ * We need to keep 2 <= length2 <= INT_MAX.
+ */
- if (objc < 1) {
- Tcl_WrongNumArgs(interp, 1, savedObjv,
- "?switches? string {pattern body ... ?default body?}");
- return TCL_ERROR;
- }
- objv = listv;
- splitObjs = 1;
+ if (count > (INT_MAX / length1)) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "result exceeds max size for a Tcl value (%d bytes)", INT_MAX));
+ return TCL_ERROR;
}
+ length2 = length1 * count;
/*
- * Complain if there is an odd number of words in the list of
- * patterns and bodies.
+ * Include space for the NUL.
*/
- if (objc % 2) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "extra switch pattern with no body", NULL);
-
+ string2 = attemptckalloc((unsigned) length2 + 1);
+ if (string2 == NULL) {
/*
- * Check if this can be due to a badly placed comment
- * in the switch block.
- *
- * The following is an heuristic to detect the infamous
- * "comment in switch" error: just check if a pattern
- * begins with '#'.
+ * Alloc failed. Note that in this case we try to do an error message
+ * since this is a case that's most likely when the alloc is large and
+ * that's easy to do with this API. Note that if we fail allocating a
+ * short string, this will likely keel over too (and fatally).
*/
- if (splitObjs) {
- for (i=0 ; i<objc ; i+=2) {
- if (Tcl_GetString(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);
- break;
- }
- }
- }
-
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "string size overflow, out of memory allocating %u bytes",
+ length2 + 1));
return TCL_ERROR;
}
+ for (index = 0; index < count; index++) {
+ memcpy(string2 + (length1 * index), string1, (size_t) length1);
+ }
+ string2[length2] = '\0';
/*
- * Complain if the last body is a continuation. Note that this
- * check assumes that the list is non-empty!
+ * We have to directly assign this instead of using Tcl_SetStringObj (and
+ * indirectly TclInitStringRep) because that makes another copy of the
+ * data.
*/
- if (strcmp(Tcl_GetString(objv[objc-1]), "-") == 0) {
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "no body specified for pattern \"",
- Tcl_GetString(objv[objc-2]), "\"", NULL);
- return TCL_ERROR;
- }
-
- for (i = 0; i < objc; i += 2) {
- /*
- * See if the pattern matches the string.
- */
-
- pattern = Tcl_GetString(objv[i]);
-
- matched = 0;
- if ((i == objc - 2)
- && (*pattern == 'd')
- && (strcmp(pattern, "default") == 0)) {
- matched = 1;
- } else {
- switch (mode) {
- case OPT_EXACT:
- matched = (strcmp(Tcl_GetString(stringObj), pattern) == 0);
- break;
- case OPT_GLOB:
- matched = Tcl_StringMatch(Tcl_GetString(stringObj),
- pattern);
- break;
- case OPT_REGEXP:
- matched = Tcl_RegExpMatchObj(interp, stringObj, objv[i]);
- if (matched < 0) {
- return TCL_ERROR;
- }
- break;
- }
- }
- if (matched == 0) {
- continue;
- }
+ TclNewObj(resultPtr);
+ resultPtr->bytes = string2;
+ resultPtr->length = length2;
+ Tcl_SetObjResult(interp, resultPtr);
- /*
- * We've got a match. Find a body to execute, skipping bodies
- * that are "-".
- *
- * TIP#280: Now is also the time to determine a line number for the
- * single-word case.
- */
+ done:
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringRplcCmd --
+ *
+ * This procedure is invoked to process the "string replace" Tcl command.
+ * See the user documentation for details on what it does. Note that this
+ * command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
-#ifdef TCL_TIP280
- ctx = *iPtr->cmdFramePtr;
+static int
+StringRplcCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ Tcl_UniChar *ustring;
+ int first, last, length;
- if (splitObjs) {
- /* We have to perform the GetSrc and other type dependent handling
- * of the frame here because we are munging with the line numbers,
- * something the other commands like if, etc. are not doing. Them
- * are fine with simply passing the CmdFrame through and having
- * the special handling done in 'info frame', or the bc compiler
- */
+ if (objc < 4 || objc > 5) {
+ Tcl_WrongNumArgs(interp, 1, objv, "string first last ?string?");
+ return TCL_ERROR;
+ }
- if (ctx.type == TCL_LOCATION_BC) {
- /* Note: Type BC => ctx.data.eval.path is not used.
- * ctx.data.tebc.codePtr is used instead.
- */
- TclGetSrcInfoForPc (&ctx);
- pc = 1;
- /* The line information in the cmdFrame is now a copy we do
- * not own */
- }
+ ustring = Tcl_GetUnicodeFromObj(objv[1], &length);
+ length--;
- if (ctx.type == TCL_LOCATION_SOURCE) {
- int bline = ctx.line [bidx];
- if (bline >= 0) {
- ctx.line = (int*) ckalloc (objc * sizeof(int));
- ctx.nline = objc;
+ if (TclGetIntForIndexM(interp, objv[2], length, &first) != TCL_OK ||
+ TclGetIntForIndexM(interp, objv[3], length, &last) != TCL_OK){
+ return TCL_ERROR;
+ }
- ListLines (blist, bline, objc, ctx.line, objv);
- } else {
- int k;
- /* Dynamic code word ... All elements are relative to themselves */
+ if ((last < first) || (last < 0) || (first > length)) {
+ Tcl_SetObjResult(interp, objv[1]);
+ } else {
+ Tcl_Obj *resultPtr;
- ctx.line = (int*) ckalloc (objc * sizeof(int));
- ctx.nline = objc;
- for (k=0; k < objc; k++) {ctx.line[k] = -1;}
- }
- } else {
- int k;
- /* Anything else ... No information, or dynamic ... */
+ ustring = Tcl_GetUnicodeFromObj(objv[1], &length);
+ length--;
- ctx.line = (int*) ckalloc (objc * sizeof(int));
- ctx.nline = objc;
- for (k=0; k < objc; k++) {ctx.line[k] = -1;}
- }
+ if (first < 0) {
+ first = 0;
}
-#endif
- for (j = i + 1; ; j += 2) {
- if (j >= objc) {
- /*
- * This shouldn't happen since we've checked that the
- * last body is not a continuation...
- */
- panic("fall-out when searching for body to match pattern");
- }
- if (strcmp(Tcl_GetString(objv[j]), "-") != 0) {
- break;
- }
+ resultPtr = Tcl_NewUnicodeObj(ustring, first);
+ if (objc == 5) {
+ Tcl_AppendObjToObj(resultPtr, objv[4]);
}
-#ifndef TCL_TIP280
- result = Tcl_EvalObjEx(interp, objv[j], 0);
-#else
- /* TIP #280. Make invoking context available to switch branch */
- result = TclEvalObjEx(interp, objv[j], 0, &ctx, splitObjs ? j : bidx+j);
- if (splitObjs) {
- ckfree ((char*) ctx.line);
- if (pc && (ctx.type == TCL_LOCATION_SOURCE)) {
- /* Death of SrcInfo reference */
- Tcl_DecrRefCount (ctx.data.eval.path);
- }
- }
-#endif
- if (result == TCL_ERROR) {
- char msg[100 + TCL_INTEGER_SPACE];
-
- sprintf(msg, "\n (\"%.50s\" arm line %d)", pattern,
- interp->errorLine);
- Tcl_AddObjErrorInfo(interp, msg, -1);
+ if (last < length) {
+ Tcl_AppendUnicodeToObj(resultPtr, ustring + last + 1,
+ length - last);
}
- return result;
+ Tcl_SetObjResult(interp, resultPtr);
}
return TCL_OK;
}
@@ -2983,13 +2303,14 @@ Tcl_SwitchObjCmd(dummy, interp, objc, objv)
/*
*----------------------------------------------------------------------
*
- * Tcl_TimeObjCmd --
+ * StringRevCmd --
*
- * This object-based procedure is invoked to process the "time" Tcl
- * command. See the user documentation for details on what it does.
+ * This procedure is invoked to process the "string reverse" Tcl command.
+ * See the user documentation for details on what it does. Note that this
+ * command only functions correctly on properly formed Tcl UTF strings.
*
* Results:
- * A standard Tcl object result.
+ * A standard Tcl result.
*
* Side effects:
* See the user documentation.
@@ -2997,1938 +2318,1618 @@ Tcl_SwitchObjCmd(dummy, interp, objc, objv)
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
-int
-Tcl_TimeObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+static int
+StringRevCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- register Tcl_Obj *objPtr;
- Tcl_Obj *objs[4];
- register int i, result;
- int count;
- double totalMicroSec;
- Tcl_Time start, stop;
-
- if (objc == 2) {
- count = 1;
- } else if (objc == 3) {
- result = Tcl_GetIntFromObj(interp, objv[2], &count);
- if (result != TCL_OK) {
- return result;
- }
- } else {
- Tcl_WrongNumArgs(interp, 1, objv, "command ?count?");
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "string");
return TCL_ERROR;
}
-
- objPtr = objv[1];
- i = count;
- Tcl_GetTime(&start);
- while (i-- > 0) {
- result = Tcl_EvalObjEx(interp, objPtr, 0);
- if (result != TCL_OK) {
- return result;
- }
- }
- Tcl_GetTime(&stop);
-
- totalMicroSec = ( ( (double) ( stop.sec - start.sec ) ) * 1.0e6
- + ( stop.usec - start.usec ) );
- if (count <= 1) {
- /* Use int obj since we know time is not fractional [Bug 1202178] */
- objs[0] = Tcl_NewIntObj((count <= 0) ? 0 : (int) totalMicroSec);
- } else {
- objs[0] = Tcl_NewDoubleObj(totalMicroSec/count);
- }
- objs[1] = Tcl_NewStringObj("microseconds", -1);
- objs[2] = Tcl_NewStringObj("per", -1);
- objs[3] = Tcl_NewStringObj("iteration", -1);
- Tcl_SetObjResult(interp, Tcl_NewListObj(4, objs));
+
+ Tcl_SetObjResult(interp, TclStringObjReverse(objv[1]));
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
- * Tcl_TraceObjCmd --
- *
- * This procedure is invoked to process the "trace" Tcl command.
- * See the user documentation for details on what it does.
- *
- * Standard syntax as of Tcl 8.4 is
- *
- * trace {add|info|remove} {command|variable} name ops cmd
+ * StringStartCmd --
*
+ * This procedure is invoked to process the "string wordstart" Tcl
+ * command. See the user documentation for details on what it does. Note
+ * that this command only functions correctly on properly formed Tcl UTF
+ * strings.
*
* Results:
* A standard Tcl result.
*
* Side effects:
* See the user documentation.
+ *
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
-int
-Tcl_TraceObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+static int
+StringStartCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- int optionIndex;
- char *name, *flagOps, *p;
- /* Main sub commands to 'trace' */
- static CONST char *traceOptions[] = {
- "add", "info", "remove",
-#ifndef TCL_REMOVE_OBSOLETE_TRACES
- "variable", "vdelete", "vinfo",
-#endif
- (char *) NULL
- };
- /* 'OLD' options are pre-Tcl-8.4 style */
- enum traceOptions {
- TRACE_ADD, TRACE_INFO, TRACE_REMOVE,
-#ifndef TCL_REMOVE_OBSOLETE_TRACES
- TRACE_OLD_VARIABLE, TRACE_OLD_VDELETE, TRACE_OLD_VINFO
-#endif
- };
+ Tcl_UniChar ch;
+ const char *p, *string;
+ int cur, index, length, numChars;
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "string index");
return TCL_ERROR;
}
- if (Tcl_GetIndexFromObj(interp, objv[1], traceOptions,
- "option", 0, &optionIndex) != TCL_OK) {
+ string = TclGetStringFromObj(objv[1], &length);
+ numChars = Tcl_NumUtfChars(string, length);
+ if (TclGetIntForIndexM(interp, objv[2], numChars-1, &index) != TCL_OK) {
return TCL_ERROR;
}
- switch ((enum traceOptions) optionIndex) {
- case TRACE_ADD:
- case TRACE_REMOVE:
- case TRACE_INFO: {
- /*
- * All sub commands of trace add/remove must take at least
- * one more argument. Beyond that we let the subcommand itself
- * control the argument structure.
- */
- int typeIndex;
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "type ?arg arg ...?");
- return TCL_ERROR;
- }
- if (Tcl_GetIndexFromObj(interp, objv[2], traceTypeOptions,
- "option", 0, &typeIndex) != TCL_OK) {
- return TCL_ERROR;
- }
- return (traceSubCmds[typeIndex])(interp, optionIndex, objc, objv);
- }
-#ifndef TCL_REMOVE_OBSOLETE_TRACES
- case TRACE_OLD_VARIABLE:
- case TRACE_OLD_VDELETE: {
- Tcl_Obj *copyObjv[6];
- Tcl_Obj *opsList;
- int code, numFlags;
-
- if (objc != 5) {
- Tcl_WrongNumArgs(interp, 2, objv, "name ops command");
- return TCL_ERROR;
- }
-
- opsList = Tcl_NewObj();
- Tcl_IncrRefCount(opsList);
- flagOps = Tcl_GetStringFromObj(objv[3], &numFlags);
- if (numFlags == 0) {
- Tcl_DecrRefCount(opsList);
- goto badVarOps;
- }
- for (p = flagOps; *p != 0; p++) {
- if (*p == 'r') {
- Tcl_ListObjAppendElement(NULL, opsList,
- Tcl_NewStringObj("read", -1));
- } else if (*p == 'w') {
- Tcl_ListObjAppendElement(NULL, opsList,
- Tcl_NewStringObj("write", -1));
- } else if (*p == 'u') {
- Tcl_ListObjAppendElement(NULL, opsList,
- Tcl_NewStringObj("unset", -1));
- } else if (*p == 'a') {
- Tcl_ListObjAppendElement(NULL, opsList,
- Tcl_NewStringObj("array", -1));
- } else {
- Tcl_DecrRefCount(opsList);
- goto badVarOps;
- }
- }
- copyObjv[0] = NULL;
- memcpy(copyObjv+1, objv, objc*sizeof(Tcl_Obj *));
- copyObjv[4] = opsList;
- if (optionIndex == TRACE_OLD_VARIABLE) {
- code = (traceSubCmds[2])(interp,TRACE_ADD,objc+1,copyObjv);
- } else {
- code = (traceSubCmds[2])(interp,TRACE_REMOVE,objc+1,copyObjv);
+ string = TclGetStringFromObj(objv[1], &length);
+ if (index >= numChars) {
+ index = numChars - 1;
+ }
+ cur = 0;
+ if (index > 0) {
+ p = Tcl_UtfAtIndex(string, index);
+ for (cur = index; cur >= 0; cur--) {
+ TclUtfToUniChar(p, &ch);
+ if (!Tcl_UniCharIsWordChar(ch)) {
+ break;
}
- Tcl_DecrRefCount(opsList);
- return code;
+ p = Tcl_UtfPrev(p, string);
}
- case TRACE_OLD_VINFO: {
- ClientData clientData;
- char ops[5];
- Tcl_Obj *resultListPtr, *pairObjPtr, *elemObjPtr;
-
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 2, objv, "name");
- return TCL_ERROR;
- }
- resultListPtr = Tcl_GetObjResult(interp);
- clientData = 0;
- name = Tcl_GetString(objv[2]);
- while ((clientData = Tcl_VarTraceInfo(interp, name, 0,
- TraceVarProc, clientData)) != 0) {
-
- TraceVarInfo *tvarPtr = (TraceVarInfo *) clientData;
-
- pairObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
- p = ops;
- if (tvarPtr->flags & TCL_TRACE_READS) {
- *p = 'r';
- p++;
- }
- if (tvarPtr->flags & TCL_TRACE_WRITES) {
- *p = 'w';
- p++;
- }
- if (tvarPtr->flags & TCL_TRACE_UNSETS) {
- *p = 'u';
- p++;
- }
- if (tvarPtr->flags & TCL_TRACE_ARRAY) {
- *p = 'a';
- p++;
- }
- *p = '\0';
-
- /*
- * Build a pair (2-item list) with the ops string as
- * the first obj element and the tvarPtr->command string
- * as the second obj element. Append the pair (as an
- * element) to the end of the result object list.
- */
-
- elemObjPtr = Tcl_NewStringObj(ops, -1);
- Tcl_ListObjAppendElement(NULL, pairObjPtr, elemObjPtr);
- elemObjPtr = Tcl_NewStringObj(tvarPtr->command, -1);
- Tcl_ListObjAppendElement(NULL, pairObjPtr, elemObjPtr);
- Tcl_ListObjAppendElement(interp, resultListPtr, pairObjPtr);
- }
- Tcl_SetObjResult(interp, resultListPtr);
- break;
+ if (cur != index) {
+ cur += 1;
}
-#endif /* TCL_REMOVE_OBSOLETE_TRACES */
}
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(cur));
return TCL_OK;
-
- badVarOps:
- Tcl_AppendResult(interp, "bad operations \"", flagOps,
- "\": should be one or more of rwua", (char *) NULL);
- return TCL_ERROR;
}
-
/*
*----------------------------------------------------------------------
*
- * TclTraceExecutionObjCmd --
+ * StringEndCmd --
*
- * Helper function for Tcl_TraceObjCmd; implements the
- * [trace {add|remove|info} execution ...] subcommands.
- * See the user documentation for details on what these do.
+ * This procedure is invoked to process the "string wordend" Tcl command.
+ * See the user documentation for details on what it does. Note that this
+ * command only functions correctly on properly formed Tcl UTF strings.
*
* Results:
- * Standard Tcl result.
+ * A standard Tcl result.
*
* Side effects:
- * Depends on the operation (add, remove, or info) being performed;
- * may add or remove command traces on a command.
+ * See the user documentation.
*
*----------------------------------------------------------------------
*/
-int
-TclTraceExecutionObjCmd(interp, optionIndex, objc, objv)
- Tcl_Interp *interp; /* Current interpreter. */
- int optionIndex; /* Add, info or remove */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+static int
+StringEndCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- int commandLength, index;
- char *name, *command;
- size_t length;
- enum traceOptions { TRACE_ADD, TRACE_INFO, TRACE_REMOVE };
- static CONST char *opStrings[] = { "enter", "leave",
- "enterstep", "leavestep", (char *) NULL };
- enum operations { TRACE_EXEC_ENTER, TRACE_EXEC_LEAVE,
- TRACE_EXEC_ENTER_STEP, TRACE_EXEC_LEAVE_STEP };
-
- switch ((enum traceOptions) optionIndex) {
- case TRACE_ADD:
- case TRACE_REMOVE: {
- int flags = 0;
- int i, listLen, result;
- Tcl_Obj **elemPtrs;
- if (objc != 6) {
- Tcl_WrongNumArgs(interp, 3, objv, "name opList command");
- return TCL_ERROR;
- }
- /*
- * Make sure the ops argument is a list object; get its length and
- * a pointer to its array of element pointers.
- */
-
- result = Tcl_ListObjGetElements(interp, objv[4], &listLen,
- &elemPtrs);
- if (result != TCL_OK) {
- return result;
- }
- if (listLen == 0) {
- Tcl_SetResult(interp, "bad operation list \"\": must be "
- "one or more of enter, leave, enterstep, or leavestep",
- TCL_STATIC);
- return TCL_ERROR;
- }
- for (i = 0; i < listLen; i++) {
- if (Tcl_GetIndexFromObj(interp, elemPtrs[i], opStrings,
- "operation", TCL_EXACT, &index) != TCL_OK) {
- return TCL_ERROR;
- }
- switch ((enum operations) index) {
- case TRACE_EXEC_ENTER:
- flags |= TCL_TRACE_ENTER_EXEC;
- break;
- case TRACE_EXEC_LEAVE:
- flags |= TCL_TRACE_LEAVE_EXEC;
- break;
- case TRACE_EXEC_ENTER_STEP:
- flags |= TCL_TRACE_ENTER_DURING_EXEC;
- break;
- case TRACE_EXEC_LEAVE_STEP:
- flags |= TCL_TRACE_LEAVE_DURING_EXEC;
- break;
- }
- }
- command = Tcl_GetStringFromObj(objv[5], &commandLength);
- length = (size_t) commandLength;
- if ((enum traceOptions) optionIndex == TRACE_ADD) {
- TraceCommandInfo *tcmdPtr;
- tcmdPtr = (TraceCommandInfo *) ckalloc((unsigned)
- (sizeof(TraceCommandInfo) - sizeof(tcmdPtr->command)
- + length + 1));
- tcmdPtr->flags = flags;
- tcmdPtr->stepTrace = NULL;
- tcmdPtr->startLevel = 0;
- tcmdPtr->startCmd = NULL;
- tcmdPtr->length = length;
- tcmdPtr->refCount = 1;
- flags |= TCL_TRACE_DELETE;
- if (flags & (TCL_TRACE_ENTER_DURING_EXEC |
- TCL_TRACE_LEAVE_DURING_EXEC)) {
- flags |= (TCL_TRACE_ENTER_EXEC |
- TCL_TRACE_LEAVE_EXEC);
- }
- memcpy(tcmdPtr->command, command, length + 1);
- name = Tcl_GetString(objv[3]);
- if (Tcl_TraceCommand(interp, name, flags, TraceCommandProc,
- (ClientData) tcmdPtr) != TCL_OK) {
- ckfree((char *) tcmdPtr);
- return TCL_ERROR;
- }
- } else {
- /*
- * Search through all of our traces on this command to
- * see if there's one with the given command. If so, then
- * delete the first one that matches.
- */
-
- TraceCommandInfo *tcmdPtr;
- ClientData clientData = NULL;
- name = Tcl_GetString(objv[3]);
-
- /* First ensure the name given is valid */
- if (Tcl_FindCommand(interp, name, NULL,
- TCL_LEAVE_ERR_MSG) == NULL) {
- return TCL_ERROR;
- }
-
- while ((clientData = Tcl_CommandTraceInfo(interp, name, 0,
- TraceCommandProc, clientData)) != NULL) {
- tcmdPtr = (TraceCommandInfo *) clientData;
- /*
- * In checking the 'flags' field we must remove any
- * extraneous flags which may have been temporarily
- * added by various pieces of the trace mechanism.
- */
- if ((tcmdPtr->length == length)
- && ((tcmdPtr->flags & (TCL_TRACE_ANY_EXEC |
- TCL_TRACE_RENAME |
- TCL_TRACE_DELETE)) == flags)
- && (strncmp(command, tcmdPtr->command,
- (size_t) length) == 0)) {
- flags |= TCL_TRACE_DELETE;
- if (flags & (TCL_TRACE_ENTER_DURING_EXEC |
- TCL_TRACE_LEAVE_DURING_EXEC)) {
- flags |= (TCL_TRACE_ENTER_EXEC |
- TCL_TRACE_LEAVE_EXEC);
- }
- Tcl_UntraceCommand(interp, name,
- flags, TraceCommandProc, clientData);
- if (tcmdPtr->stepTrace != NULL) {
- /*
- * We need to remove the interpreter-wide trace
- * which we created to allow 'step' traces.
- */
- Tcl_DeleteTrace(interp, tcmdPtr->stepTrace);
- tcmdPtr->stepTrace = NULL;
- if (tcmdPtr->startCmd != NULL) {
- ckfree((char *)tcmdPtr->startCmd);
- }
- }
- if (tcmdPtr->flags & TCL_TRACE_EXEC_IN_PROGRESS) {
- /* Postpone deletion */
- tcmdPtr->flags = 0;
- }
- tcmdPtr->refCount--;
- if (tcmdPtr->refCount < 0) {
- Tcl_Panic("TclTraceExecutionObjCmd: negative TraceCommandInfo refCount");
- }
- if (tcmdPtr->refCount == 0) {
- ckfree((char*)tcmdPtr);
- }
- break;
- }
- }
- }
- break;
- }
- case TRACE_INFO: {
- ClientData clientData;
- Tcl_Obj *resultListPtr, *eachTraceObjPtr, *elemObjPtr;
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 3, objv, "name");
- return TCL_ERROR;
- }
-
- clientData = NULL;
- name = Tcl_GetString(objv[3]);
-
- /* First ensure the name given is valid */
- if (Tcl_FindCommand(interp, name, NULL,
- TCL_LEAVE_ERR_MSG) == NULL) {
- return TCL_ERROR;
- }
-
- resultListPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
- while ((clientData = Tcl_CommandTraceInfo(interp, name, 0,
- TraceCommandProc, clientData)) != NULL) {
- int numOps = 0;
-
- TraceCommandInfo *tcmdPtr = (TraceCommandInfo *) clientData;
+ Tcl_UniChar ch;
+ const char *p, *end, *string;
+ int cur, index, length, numChars;
- /*
- * Build a list with the ops list as the first obj
- * element and the tcmdPtr->command string as the
- * second obj element. Append this list (as an
- * element) to the end of the result object list.
- */
+ if (objc != 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "string index");
+ return TCL_ERROR;
+ }
- elemObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
- Tcl_IncrRefCount(elemObjPtr);
- if (tcmdPtr->flags & TCL_TRACE_ENTER_EXEC) {
- Tcl_ListObjAppendElement(NULL, elemObjPtr,
- Tcl_NewStringObj("enter",5));
- }
- if (tcmdPtr->flags & TCL_TRACE_LEAVE_EXEC) {
- Tcl_ListObjAppendElement(NULL, elemObjPtr,
- Tcl_NewStringObj("leave",5));
- }
- if (tcmdPtr->flags & TCL_TRACE_ENTER_DURING_EXEC) {
- Tcl_ListObjAppendElement(NULL, elemObjPtr,
- Tcl_NewStringObj("enterstep",9));
- }
- if (tcmdPtr->flags & TCL_TRACE_LEAVE_DURING_EXEC) {
- Tcl_ListObjAppendElement(NULL, elemObjPtr,
- Tcl_NewStringObj("leavestep",9));
- }
- Tcl_ListObjLength(NULL, elemObjPtr, &numOps);
- if (0 == numOps) {
- Tcl_DecrRefCount(elemObjPtr);
- continue;
- }
- eachTraceObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
- Tcl_ListObjAppendElement(NULL, eachTraceObjPtr, elemObjPtr);
- Tcl_DecrRefCount(elemObjPtr);
- elemObjPtr = NULL;
-
- Tcl_ListObjAppendElement(NULL, eachTraceObjPtr,
- Tcl_NewStringObj(tcmdPtr->command, -1));
- Tcl_ListObjAppendElement(interp, resultListPtr,
- eachTraceObjPtr);
+ string = TclGetStringFromObj(objv[1], &length);
+ numChars = Tcl_NumUtfChars(string, length);
+ if (TclGetIntForIndexM(interp, objv[2], numChars-1, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ string = TclGetStringFromObj(objv[1], &length);
+ if (index < 0) {
+ index = 0;
+ }
+ if (index < numChars) {
+ p = Tcl_UtfAtIndex(string, index);
+ end = string+length;
+ for (cur = index; p < end; cur++) {
+ p += TclUtfToUniChar(p, &ch);
+ if (!Tcl_UniCharIsWordChar(ch)) {
+ break;
}
- Tcl_SetObjResult(interp, resultListPtr);
- break;
}
+ if (cur == index) {
+ cur++;
+ }
+ } else {
+ cur = numChars;
}
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(cur));
return TCL_OK;
}
-
/*
*----------------------------------------------------------------------
*
- * TclTraceCommandObjCmd --
+ * StringEqualCmd --
*
- * Helper function for Tcl_TraceObjCmd; implements the
- * [trace {add|info|remove} command ...] subcommands.
- * See the user documentation for details on what these do.
+ * This procedure is invoked to process the "string equal" Tcl command.
+ * See the user documentation for details on what it does. Note that this
+ * command only functions correctly on properly formed Tcl UTF strings.
*
* Results:
- * Standard Tcl result.
+ * A standard Tcl result.
*
* Side effects:
- * Depends on the operation (add, remove, or info) being performed;
- * may add or remove command traces on a command.
+ * See the user documentation.
*
*----------------------------------------------------------------------
*/
-int
-TclTraceCommandObjCmd(interp, optionIndex, objc, objv)
- Tcl_Interp *interp; /* Current interpreter. */
- int optionIndex; /* Add, info or remove */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+static int
+StringEqualCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- int commandLength, index;
- char *name, *command;
- size_t length;
- enum traceOptions { TRACE_ADD, TRACE_INFO, TRACE_REMOVE };
- static CONST char *opStrings[] = { "delete", "rename", (char *) NULL };
- enum operations { TRACE_CMD_DELETE, TRACE_CMD_RENAME };
-
- switch ((enum traceOptions) optionIndex) {
- case TRACE_ADD:
- case TRACE_REMOVE: {
- int flags = 0;
- int i, listLen, result;
- Tcl_Obj **elemPtrs;
- if (objc != 6) {
- Tcl_WrongNumArgs(interp, 3, objv, "name opList command");
- return TCL_ERROR;
- }
- /*
- * Make sure the ops argument is a list object; get its length and
- * a pointer to its array of element pointers.
- */
+ /*
+ * Remember to keep code here in some sync with the byte-compiled versions
+ * in tclExecute.c (INST_STR_EQ, INST_STR_NEQ and INST_STR_CMP as well as
+ * the expr string comparison in INST_EQ/INST_NEQ/INST_LT/...).
+ */
- result = Tcl_ListObjGetElements(interp, objv[4], &listLen,
- &elemPtrs);
- if (result != TCL_OK) {
- return result;
+ char *string1, *string2;
+ int length1, length2, i, match, length, nocase = 0, reqlength = -1;
+ typedef int (*strCmpFn_t)(const char *, const char *, unsigned int);
+ strCmpFn_t strCmpFn;
+
+ if (objc < 3 || objc > 6) {
+ str_cmp_args:
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "?-nocase? ?-length int? string1 string2");
+ return TCL_ERROR;
+ }
+
+ for (i = 1; i < objc-2; i++) {
+ string2 = TclGetStringFromObj(objv[i], &length2);
+ if ((length2 > 1) && !strncmp(string2, "-nocase", (size_t)length2)) {
+ nocase = 1;
+ } else if ((length2 > 1)
+ && !strncmp(string2, "-length", (size_t)length2)) {
+ if (i+1 >= objc-2) {
+ goto str_cmp_args;
}
- if (listLen == 0) {
- Tcl_SetResult(interp, "bad operation list \"\": must be "
- "one or more of delete or rename", TCL_STATIC);
+ ++i;
+ if (TclGetIntFromObj(interp, objv[i], &reqlength) != TCL_OK) {
return TCL_ERROR;
}
- for (i = 0; i < listLen; i++) {
- if (Tcl_GetIndexFromObj(interp, elemPtrs[i], opStrings,
- "operation", TCL_EXACT, &index) != TCL_OK) {
- return TCL_ERROR;
- }
- switch ((enum operations) index) {
- case TRACE_CMD_RENAME:
- flags |= TCL_TRACE_RENAME;
- break;
- case TRACE_CMD_DELETE:
- flags |= TCL_TRACE_DELETE;
- break;
- }
- }
- command = Tcl_GetStringFromObj(objv[5], &commandLength);
- length = (size_t) commandLength;
- if ((enum traceOptions) optionIndex == TRACE_ADD) {
- TraceCommandInfo *tcmdPtr;
- tcmdPtr = (TraceCommandInfo *) ckalloc((unsigned)
- (sizeof(TraceCommandInfo) - sizeof(tcmdPtr->command)
- + length + 1));
- tcmdPtr->flags = flags;
- tcmdPtr->stepTrace = NULL;
- tcmdPtr->startLevel = 0;
- tcmdPtr->startCmd = NULL;
- tcmdPtr->length = length;
- tcmdPtr->refCount = 1;
- flags |= TCL_TRACE_DELETE;
- memcpy(tcmdPtr->command, command, length + 1);
- name = Tcl_GetString(objv[3]);
- if (Tcl_TraceCommand(interp, name, flags, TraceCommandProc,
- (ClientData) tcmdPtr) != TCL_OK) {
- ckfree((char *) tcmdPtr);
- return TCL_ERROR;
- }
- } else {
- /*
- * Search through all of our traces on this command to
- * see if there's one with the given command. If so, then
- * delete the first one that matches.
- */
-
- TraceCommandInfo *tcmdPtr;
- ClientData clientData = NULL;
- name = Tcl_GetString(objv[3]);
-
- /* First ensure the name given is valid */
- if (Tcl_FindCommand(interp, name, NULL,
- TCL_LEAVE_ERR_MSG) == NULL) {
- return TCL_ERROR;
- }
-
- while ((clientData = Tcl_CommandTraceInfo(interp, name, 0,
- TraceCommandProc, clientData)) != NULL) {
- tcmdPtr = (TraceCommandInfo *) clientData;
- if ((tcmdPtr->length == length)
- && (tcmdPtr->flags == flags)
- && (strncmp(command, tcmdPtr->command,
- (size_t) length) == 0)) {
- Tcl_UntraceCommand(interp, name,
- flags | TCL_TRACE_DELETE,
- TraceCommandProc, clientData);
- tcmdPtr->flags |= TCL_TRACE_DESTROYED;
- tcmdPtr->refCount--;
- if (tcmdPtr->refCount < 0) {
- Tcl_Panic("TclTraceCommandObjCmd: negative TraceCommandInfo refCount");
- }
- if (tcmdPtr->refCount == 0) {
- ckfree((char *) tcmdPtr);
- }
- break;
- }
- }
- }
- break;
+ } else {
+ Tcl_AppendResult(interp, "bad option \"", string2,
+ "\": must be -nocase or -length", NULL);
+ return TCL_ERROR;
}
- case TRACE_INFO: {
- ClientData clientData;
- Tcl_Obj *resultListPtr, *eachTraceObjPtr, *elemObjPtr;
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 3, objv, "name");
- return TCL_ERROR;
- }
+ }
- clientData = NULL;
- name = Tcl_GetString(objv[3]);
-
- /* First ensure the name given is valid */
- if (Tcl_FindCommand(interp, name, NULL,
- TCL_LEAVE_ERR_MSG) == NULL) {
- return TCL_ERROR;
- }
-
- resultListPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
- while ((clientData = Tcl_CommandTraceInfo(interp, name, 0,
- TraceCommandProc, clientData)) != NULL) {
- int numOps = 0;
+ /*
+ * From now on, we only access the two objects at the end of the argument
+ * array.
+ */
- TraceCommandInfo *tcmdPtr = (TraceCommandInfo *) clientData;
+ objv += objc-2;
- /*
- * Build a list with the ops list as
- * the first obj element and the tcmdPtr->command string
- * as the second obj element. Append this list (as an
- * element) to the end of the result object list.
- */
+ if ((reqlength == 0) || (objv[0] == objv[1])) {
+ /*
+ * Always match at 0 chars of if it is the same obj.
+ */
- elemObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
- Tcl_IncrRefCount(elemObjPtr);
- if (tcmdPtr->flags & TCL_TRACE_RENAME) {
- Tcl_ListObjAppendElement(NULL, elemObjPtr,
- Tcl_NewStringObj("rename",6));
- }
- if (tcmdPtr->flags & TCL_TRACE_DELETE) {
- Tcl_ListObjAppendElement(NULL, elemObjPtr,
- Tcl_NewStringObj("delete",6));
- }
- Tcl_ListObjLength(NULL, elemObjPtr, &numOps);
- if (0 == numOps) {
- Tcl_DecrRefCount(elemObjPtr);
- continue;
- }
- eachTraceObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
- Tcl_ListObjAppendElement(NULL, eachTraceObjPtr, elemObjPtr);
- Tcl_DecrRefCount(elemObjPtr);
-
- elemObjPtr = Tcl_NewStringObj(tcmdPtr->command, -1);
- Tcl_ListObjAppendElement(NULL, eachTraceObjPtr, elemObjPtr);
- Tcl_ListObjAppendElement(interp, resultListPtr,
- eachTraceObjPtr);
- }
- Tcl_SetObjResult(interp, resultListPtr);
- break;
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
+ return TCL_OK;
+ }
+
+ if (!nocase && objv[0]->typePtr == &tclByteArrayType &&
+ objv[1]->typePtr == &tclByteArrayType) {
+ /*
+ * Use binary versions of comparisons since that won't cause undue
+ * type conversions and it is much faster. Only do this if we're
+ * case-sensitive (which is all that really makes sense with byte
+ * arrays anyway, and we have no memcasecmp() for some reason... :^)
+ */
+
+ string1 = (char *) Tcl_GetByteArrayFromObj(objv[0], &length1);
+ string2 = (char *) Tcl_GetByteArrayFromObj(objv[1], &length2);
+ strCmpFn = (strCmpFn_t) memcmp;
+ } else if ((objv[0]->typePtr == &tclStringType)
+ && (objv[1]->typePtr == &tclStringType)) {
+ /*
+ * Do a unicode-specific comparison if both of the args are of String
+ * type. In benchmark testing this proved the most efficient check
+ * between the unicode and string comparison operations.
+ */
+
+ string1 = (char *) Tcl_GetUnicodeFromObj(objv[0], &length1);
+ string2 = (char *) Tcl_GetUnicodeFromObj(objv[1], &length2);
+ strCmpFn = (strCmpFn_t)
+ (nocase ? Tcl_UniCharNcasecmp : Tcl_UniCharNcmp);
+ } else {
+ /*
+ * As a catch-all we will work with UTF-8. We cannot use memcmp() as
+ * that is unsafe with any string containing NUL (\xC0\x80 in Tcl's
+ * utf rep). We can use the more efficient TclpUtfNcmp2 if we are
+ * case-sensitive and no specific length was requested.
+ */
+
+ string1 = (char *) TclGetStringFromObj(objv[0], &length1);
+ string2 = (char *) TclGetStringFromObj(objv[1], &length2);
+ if ((reqlength < 0) && !nocase) {
+ strCmpFn = (strCmpFn_t) TclpUtfNcmp2;
+ } else {
+ length1 = Tcl_NumUtfChars(string1, length1);
+ length2 = Tcl_NumUtfChars(string2, length2);
+ strCmpFn = (strCmpFn_t) (nocase ? Tcl_UtfNcasecmp : Tcl_UtfNcmp);
+ }
+ }
+
+ if ((reqlength < 0) && (length1 != length2)) {
+ match = 1; /* This will be reversed below. */
+ } else {
+ length = (length1 < length2) ? length1 : length2;
+ if (reqlength > 0 && reqlength < length) {
+ length = reqlength;
+ } else if (reqlength < 0) {
+ /*
+ * The requested length is negative, so we ignore it by setting it
+ * to length + 1 so we correct the match var.
+ */
+
+ reqlength = length + 1;
+ }
+
+ match = strCmpFn(string1, string2, (unsigned) length);
+ if ((match == 0) && (reqlength > length)) {
+ match = length1 - length2;
}
}
+
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(match ? 0 : 1));
return TCL_OK;
}
-
/*
*----------------------------------------------------------------------
*
- * TclTraceVariableObjCmd --
+ * StringCmpCmd --
*
- * Helper function for Tcl_TraceObjCmd; implements the
- * [trace {add|info|remove} variable ...] subcommands.
- * See the user documentation for details on what these do.
+ * This procedure is invoked to process the "string compare" Tcl command.
+ * See the user documentation for details on what it does. Note that this
+ * command only functions correctly on properly formed Tcl UTF strings.
*
* Results:
- * Standard Tcl result.
+ * A standard Tcl result.
*
* Side effects:
- * Depends on the operation (add, remove, or info) being performed;
- * may add or remove variable traces on a variable.
+ * See the user documentation.
*
*----------------------------------------------------------------------
*/
-int
-TclTraceVariableObjCmd(interp, optionIndex, objc, objv)
- Tcl_Interp *interp; /* Current interpreter. */
- int optionIndex; /* Add, info or remove */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+static int
+StringCmpCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- int commandLength, index;
- char *name, *command;
- size_t length;
- enum traceOptions { TRACE_ADD, TRACE_INFO, TRACE_REMOVE };
- static CONST char *opStrings[] = { "array", "read", "unset", "write",
- (char *) NULL };
- enum operations { TRACE_VAR_ARRAY, TRACE_VAR_READ, TRACE_VAR_UNSET,
- TRACE_VAR_WRITE };
-
- switch ((enum traceOptions) optionIndex) {
- case TRACE_ADD:
- case TRACE_REMOVE: {
- int flags = 0;
- int i, listLen, result;
- Tcl_Obj **elemPtrs;
- if (objc != 6) {
- Tcl_WrongNumArgs(interp, 3, objv, "name opList command");
- return TCL_ERROR;
- }
- /*
- * Make sure the ops argument is a list object; get its length and
- * a pointer to its array of element pointers.
- */
+ /*
+ * Remember to keep code here in some sync with the byte-compiled versions
+ * in tclExecute.c (INST_STR_EQ, INST_STR_NEQ and INST_STR_CMP as well as
+ * the expr string comparison in INST_EQ/INST_NEQ/INST_LT/...).
+ */
- result = Tcl_ListObjGetElements(interp, objv[4], &listLen,
- &elemPtrs);
- if (result != TCL_OK) {
- return result;
- }
- if (listLen == 0) {
- Tcl_SetResult(interp, "bad operation list \"\": must be "
- "one or more of array, read, unset, or write",
- TCL_STATIC);
- return TCL_ERROR;
- }
- for (i = 0; i < listLen ; i++) {
- if (Tcl_GetIndexFromObj(interp, elemPtrs[i], opStrings,
- "operation", TCL_EXACT, &index) != TCL_OK) {
- return TCL_ERROR;
- }
- switch ((enum operations) index) {
- case TRACE_VAR_ARRAY:
- flags |= TCL_TRACE_ARRAY;
- break;
- case TRACE_VAR_READ:
- flags |= TCL_TRACE_READS;
- break;
- case TRACE_VAR_UNSET:
- flags |= TCL_TRACE_UNSETS;
- break;
- case TRACE_VAR_WRITE:
- flags |= TCL_TRACE_WRITES;
- break;
- }
- }
- command = Tcl_GetStringFromObj(objv[5], &commandLength);
- length = (size_t) commandLength;
- if ((enum traceOptions) optionIndex == TRACE_ADD) {
- /*
- * This code essentially mallocs together the VarTrace and the
- * TraceVarInfo, then inlines the Tcl_TraceVar(). This is
- * necessary in order to have the TraceVarInfo to be freed
- * automatically when the VarTrace is freed [Bug 1348775]
- */
+ char *string1, *string2;
+ int length1, length2, i, match, length, nocase = 0, reqlength = -1;
+ typedef int (*strCmpFn_t)(const char *, const char *, unsigned int);
+ strCmpFn_t strCmpFn;
- CompoundVarTrace *compTracePtr;
- TraceVarInfo *tvarPtr;
- Var *varPtr, *arrayPtr;
- VarTrace *tracePtr;
- int flagMask;
-
- compTracePtr = (CompoundVarTrace *) ckalloc((unsigned)
- (sizeof(CompoundVarTrace) - sizeof(tvarPtr->command)
- + length + 1));
- tracePtr = &(compTracePtr->trace);
- tvarPtr = &(compTracePtr->tvar);
- tvarPtr->flags = flags;
- if (objv[0] == NULL) {
- tvarPtr->flags |= TCL_TRACE_OLD_STYLE;
- }
- tvarPtr->length = length;
- flags |= TCL_TRACE_UNSETS | TCL_TRACE_RESULT_OBJECT;
- memcpy(tvarPtr->command, command, length + 1);
- name = Tcl_GetString(objv[3]);
- flagMask = TCL_GLOBAL_ONLY | TCL_NAMESPACE_ONLY;
- varPtr = TclLookupVar(interp, name, NULL,
- (flags & flagMask) | TCL_LEAVE_ERR_MSG, "trace",
- /*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr);
- if (varPtr == NULL) {
- ckfree((char *) tracePtr);
- return TCL_ERROR;
- }
- flagMask = TCL_TRACE_READS | TCL_TRACE_WRITES
- | TCL_TRACE_UNSETS | TCL_TRACE_ARRAY
- | TCL_TRACE_RESULT_DYNAMIC | TCL_TRACE_RESULT_OBJECT;
-#ifndef TCL_REMOVE_OBSOLETE_TRACES
- flagMask |= TCL_TRACE_OLD_STYLE;
-#endif
- tracePtr->traceProc = TraceVarProc;
- tracePtr->clientData = (ClientData) tvarPtr;
- tracePtr->flags = flags & flagMask;
- tracePtr->nextPtr = varPtr->tracePtr;
- varPtr->tracePtr = tracePtr;
- } else {
- /*
- * Search through all of our traces on this variable to
- * see if there's one with the given command. If so, then
- * delete the first one that matches.
- */
-
- TraceVarInfo *tvarPtr;
- ClientData clientData = 0;
- name = Tcl_GetString(objv[3]);
- while ((clientData = Tcl_VarTraceInfo(interp, name, 0,
- TraceVarProc, clientData)) != 0) {
- tvarPtr = (TraceVarInfo *) clientData;
- if ((tvarPtr->length == length)
- && ((tvarPtr->flags & ~TCL_TRACE_OLD_STYLE)==flags)
- && (strncmp(command, tvarPtr->command,
- (size_t) length) == 0)) {
- Tcl_UntraceVar2(interp, name, NULL,
- flags | TCL_TRACE_UNSETS | TCL_TRACE_RESULT_OBJECT,
- TraceVarProc, clientData);
- break;
- }
- }
+ if (objc < 3 || objc > 6) {
+ str_cmp_args:
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "?-nocase? ?-length int? string1 string2");
+ return TCL_ERROR;
+ }
+
+ for (i = 1; i < objc-2; i++) {
+ string2 = TclGetStringFromObj(objv[i], &length2);
+ if ((length2 > 1) && !strncmp(string2, "-nocase", (size_t)length2)) {
+ nocase = 1;
+ } else if ((length2 > 1)
+ && !strncmp(string2, "-length", (size_t)length2)) {
+ if (i+1 >= objc-2) {
+ goto str_cmp_args;
}
- break;
- }
- case TRACE_INFO: {
- ClientData clientData;
- Tcl_Obj *resultListPtr, *eachTraceObjPtr, *elemObjPtr;
- if (objc != 4) {
- Tcl_WrongNumArgs(interp, 3, objv, "name");
+ ++i;
+ if (TclGetIntFromObj(interp, objv[i], &reqlength) != TCL_OK) {
return TCL_ERROR;
}
+ } else {
+ Tcl_AppendResult(interp, "bad option \"", string2,
+ "\": must be -nocase or -length", NULL);
+ return TCL_ERROR;
+ }
+ }
- resultListPtr = Tcl_GetObjResult(interp);
- clientData = 0;
- name = Tcl_GetString(objv[3]);
- while ((clientData = Tcl_VarTraceInfo(interp, name, 0,
- TraceVarProc, clientData)) != 0) {
+ /*
+ * From now on, we only access the two objects at the end of the argument
+ * array.
+ */
- TraceVarInfo *tvarPtr = (TraceVarInfo *) clientData;
+ objv += objc-2;
- /*
- * Build a list with the ops list as
- * the first obj element and the tcmdPtr->command string
- * as the second obj element. Append this list (as an
- * element) to the end of the result object list.
- */
+ if ((reqlength == 0) || (objv[0] == objv[1])) {
+ /*
+ * Always match at 0 chars of if it is the same obj.
+ */
- elemObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
- if (tvarPtr->flags & TCL_TRACE_ARRAY) {
- Tcl_ListObjAppendElement(NULL, elemObjPtr,
- Tcl_NewStringObj("array", 5));
- }
- if (tvarPtr->flags & TCL_TRACE_READS) {
- Tcl_ListObjAppendElement(NULL, elemObjPtr,
- Tcl_NewStringObj("read", 4));
- }
- if (tvarPtr->flags & TCL_TRACE_WRITES) {
- Tcl_ListObjAppendElement(NULL, elemObjPtr,
- Tcl_NewStringObj("write", 5));
- }
- if (tvarPtr->flags & TCL_TRACE_UNSETS) {
- Tcl_ListObjAppendElement(NULL, elemObjPtr,
- Tcl_NewStringObj("unset", 5));
- }
- eachTraceObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
- Tcl_ListObjAppendElement(NULL, eachTraceObjPtr, elemObjPtr);
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
+ return TCL_OK;
+ }
- elemObjPtr = Tcl_NewStringObj(tvarPtr->command, -1);
- Tcl_ListObjAppendElement(NULL, eachTraceObjPtr, elemObjPtr);
- Tcl_ListObjAppendElement(interp, resultListPtr,
- eachTraceObjPtr);
- }
- Tcl_SetObjResult(interp, resultListPtr);
- break;
+ if (!nocase && objv[0]->typePtr == &tclByteArrayType &&
+ objv[1]->typePtr == &tclByteArrayType) {
+ /*
+ * Use binary versions of comparisons since that won't cause undue
+ * type conversions and it is much faster. Only do this if we're
+ * case-sensitive (which is all that really makes sense with byte
+ * arrays anyway, and we have no memcasecmp() for some reason... :^)
+ */
+
+ string1 = (char *) Tcl_GetByteArrayFromObj(objv[0], &length1);
+ string2 = (char *) Tcl_GetByteArrayFromObj(objv[1], &length2);
+ strCmpFn = (strCmpFn_t) memcmp;
+ } else if ((objv[0]->typePtr == &tclStringType)
+ && (objv[1]->typePtr == &tclStringType)) {
+ /*
+ * Do a unicode-specific comparison if both of the args are of String
+ * type. In benchmark testing this proved the most efficient check
+ * between the unicode and string comparison operations.
+ */
+
+ string1 = (char *) Tcl_GetUnicodeFromObj(objv[0], &length1);
+ string2 = (char *) Tcl_GetUnicodeFromObj(objv[1], &length2);
+ strCmpFn = (strCmpFn_t)
+ (nocase ? Tcl_UniCharNcasecmp : Tcl_UniCharNcmp);
+ } else {
+ /*
+ * As a catch-all we will work with UTF-8. We cannot use memcmp() as
+ * that is unsafe with any string containing NUL (\xC0\x80 in Tcl's
+ * utf rep). We can use the more efficient TclpUtfNcmp2 if we are
+ * case-sensitive and no specific length was requested.
+ */
+
+ string1 = (char *) TclGetStringFromObj(objv[0], &length1);
+ string2 = (char *) TclGetStringFromObj(objv[1], &length2);
+ if ((reqlength < 0) && !nocase) {
+ strCmpFn = (strCmpFn_t) TclpUtfNcmp2;
+ } else {
+ length1 = Tcl_NumUtfChars(string1, length1);
+ length2 = Tcl_NumUtfChars(string2, length2);
+ strCmpFn = (strCmpFn_t) (nocase ? Tcl_UtfNcasecmp : Tcl_UtfNcmp);
}
}
+
+ length = (length1 < length2) ? length1 : length2;
+ if (reqlength > 0 && reqlength < length) {
+ length = reqlength;
+ } else if (reqlength < 0) {
+ /*
+ * The requested length is negative, so we ignore it by setting it to
+ * length + 1 so we correct the match var.
+ */
+
+ reqlength = length + 1;
+ }
+
+ match = strCmpFn(string1, string2, (unsigned) length);
+ if ((match == 0) && (reqlength > length)) {
+ match = length1 - length2;
+ }
+
+ Tcl_SetObjResult(interp,
+ Tcl_NewIntObj((match > 0) ? 1 : (match < 0) ? -1 : 0));
return TCL_OK;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringBytesCmd --
+ *
+ * This procedure is invoked to process the "string bytelength" Tcl
+ * command. See the user documentation for details on what it does. Note
+ * that this command only functions correctly on properly formed Tcl UTF
+ * strings.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+StringBytesCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ int length;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "string");
+ return TCL_ERROR;
+ }
+
+ (void) TclGetStringFromObj(objv[1], &length);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(length));
+ return TCL_OK;
+}
/*
*----------------------------------------------------------------------
*
- * Tcl_CommandTraceInfo --
+ * StringLenCmd --
*
- * Return the clientData value associated with a trace on a
- * command. This procedure can also be used to step through
- * all of the traces on a particular command that have the
- * same trace procedure.
+ * This procedure is invoked to process the "string length" Tcl command.
+ * See the user documentation for details on what it does. Note that this
+ * command only functions correctly on properly formed Tcl UTF strings.
*
* Results:
- * The return value is the clientData value associated with
- * a trace on the given command. Information will only be
- * returned for a trace with proc as trace procedure. If
- * the clientData argument is NULL then the first such trace is
- * returned; otherwise, the next relevant one after the one
- * given by clientData will be returned. If the command
- * doesn't exist then an error message is left in the interpreter
- * and NULL is returned. Also, if there are no (more) traces for
- * the given command, NULL is returned.
+ * A standard Tcl result.
*
* Side effects:
- * None.
+ * See the user documentation.
*
*----------------------------------------------------------------------
*/
-ClientData
-Tcl_CommandTraceInfo(interp, cmdName, flags, proc, prevClientData)
- Tcl_Interp *interp; /* Interpreter containing command. */
- CONST char *cmdName; /* Name of command. */
- int flags; /* OR-ed combo or TCL_GLOBAL_ONLY,
- * TCL_NAMESPACE_ONLY (can be 0). */
- Tcl_CommandTraceProc *proc; /* Procedure assocated with trace. */
- ClientData prevClientData; /* If non-NULL, gives last value returned
- * by this procedure, so this call will
- * return the next trace after that one.
- * If NULL, this call will return the
- * first trace. */
+static int
+StringLenCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- Command *cmdPtr;
- register CommandTrace *tracePtr;
+ int length;
- cmdPtr = (Command*)Tcl_FindCommand(interp, cmdName,
- NULL, TCL_LEAVE_ERR_MSG);
- if (cmdPtr == NULL) {
- return NULL;
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "string");
+ return TCL_ERROR;
}
/*
- * Find the relevant trace, if any, and return its clientData.
+ * If we have a ByteArray object, avoid recomputing the string since the
+ * byte array contains one byte per character. Otherwise, use the Unicode
+ * string rep to calculate the length.
*/
- tracePtr = cmdPtr->tracePtr;
- if (prevClientData != NULL) {
- for ( ; tracePtr != NULL; tracePtr = tracePtr->nextPtr) {
- if ((tracePtr->clientData == prevClientData)
- && (tracePtr->traceProc == proc)) {
- tracePtr = tracePtr->nextPtr;
- break;
- }
- }
- }
- for ( ; tracePtr != NULL; tracePtr = tracePtr->nextPtr) {
- if (tracePtr->traceProc == proc) {
- return tracePtr->clientData;
- }
+ if (objv[1]->typePtr == &tclByteArrayType) {
+ (void) Tcl_GetByteArrayFromObj(objv[1], &length);
+ } else {
+ length = Tcl_GetCharLength(objv[1]);
}
- return NULL;
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(length));
+ return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
- * Tcl_TraceCommand --
+ * StringLowerCmd --
*
- * Arrange for rename/deletes to a command to cause a
- * procedure to be invoked, which can monitor the operations.
- *
- * Also optionally arrange for execution of that command
- * to cause a procedure to be invoked.
+ * This procedure is invoked to process the "string tolower" Tcl command.
+ * See the user documentation for details on what it does. Note that this
+ * command only functions correctly on properly formed Tcl UTF strings.
*
* Results:
- * A standard Tcl return value.
+ * A standard Tcl result.
*
* Side effects:
- * A trace is set up on the command given by cmdName, such that
- * future changes to the command will be intermediated by
- * proc. See the manual entry for complete details on the calling
- * sequence for proc.
+ * See the user documentation.
*
*----------------------------------------------------------------------
*/
-int
-Tcl_TraceCommand(interp, cmdName, flags, proc, clientData)
- Tcl_Interp *interp; /* Interpreter in which command is
- * to be traced. */
- CONST char *cmdName; /* Name of command. */
- int flags; /* OR-ed collection of bits, including any
- * of TCL_TRACE_RENAME, TCL_TRACE_DELETE,
- * and any of the TRACE_*_EXEC flags */
- Tcl_CommandTraceProc *proc; /* Procedure to call when specified ops are
- * invoked upon varName. */
- ClientData clientData; /* Arbitrary argument to pass to proc. */
+static int
+StringLowerCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- Command *cmdPtr;
- register CommandTrace *tracePtr;
+ int length1, length2;
+ char *string1, *string2;
- cmdPtr = (Command*)Tcl_FindCommand(interp, cmdName,
- NULL, TCL_LEAVE_ERR_MSG);
- if (cmdPtr == NULL) {
+ if (objc < 2 || objc > 4) {
+ Tcl_WrongNumArgs(interp, 1, objv, "string ?first? ?last?");
return TCL_ERROR;
}
- /*
- * Set up trace information.
- */
+ string1 = TclGetStringFromObj(objv[1], &length1);
- tracePtr = (CommandTrace *) ckalloc(sizeof(CommandTrace));
- tracePtr->traceProc = proc;
- tracePtr->clientData = clientData;
- tracePtr->flags = flags & (TCL_TRACE_RENAME | TCL_TRACE_DELETE
- | TCL_TRACE_ANY_EXEC);
- tracePtr->nextPtr = cmdPtr->tracePtr;
- tracePtr->refCount = 1;
- cmdPtr->tracePtr = tracePtr;
- if ((tracePtr->flags & TCL_TRACE_ANY_EXEC)
- && !(cmdPtr->flags & CMD_HAS_EXEC_TRACES)) {
- cmdPtr->flags |= CMD_HAS_EXEC_TRACES;
+ if (objc == 2) {
+ Tcl_Obj *resultPtr = Tcl_NewStringObj(string1, length1);
- /*
- * Bug 3484621: New execution trace means we no longer compile
- * this command if we normally would. Invalidate bytecode.
- */
+ length1 = Tcl_UtfToLower(TclGetString(resultPtr));
+ Tcl_SetObjLength(resultPtr, length1);
+ Tcl_SetObjResult(interp, resultPtr);
+ } else {
+ int first, last;
+ const char *start, *end;
+ Tcl_Obj *resultPtr;
- if (cmdPtr->compileProc != NULL) {
- ((Interp *)interp)->compileEpoch++;
+ length1 = Tcl_NumUtfChars(string1, length1) - 1;
+ if (TclGetIntForIndexM(interp,objv[2],length1, &first) != TCL_OK) {
+ return TCL_ERROR;
}
+ if (first < 0) {
+ first = 0;
+ }
+ last = first;
+
+ if ((objc == 4) && (TclGetIntForIndexM(interp, objv[3], length1,
+ &last) != TCL_OK)) {
+ return TCL_ERROR;
+ }
+
+ if (last >= length1) {
+ last = length1;
+ }
+ if (last < first) {
+ Tcl_SetObjResult(interp, objv[1]);
+ return TCL_OK;
+ }
+
+ string1 = TclGetStringFromObj(objv[1], &length1);
+ start = Tcl_UtfAtIndex(string1, first);
+ end = Tcl_UtfAtIndex(start, last - first + 1);
+ resultPtr = Tcl_NewStringObj(string1, end - string1);
+ string2 = TclGetString(resultPtr) + (start - string1);
+
+ length2 = Tcl_UtfToLower(string2);
+ Tcl_SetObjLength(resultPtr, length2 + (start - string1));
+
+ Tcl_AppendToObj(resultPtr, end, -1);
+ Tcl_SetObjResult(interp, resultPtr);
}
+
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
- * Tcl_UntraceCommand --
+ * StringUpperCmd --
*
- * Remove a previously-created trace for a command.
+ * This procedure is invoked to process the "string toupper" Tcl command.
+ * See the user documentation for details on what it does. Note that this
+ * command only functions correctly on properly formed Tcl UTF strings.
*
* Results:
- * None.
+ * A standard Tcl result.
*
* Side effects:
- * If there exists a trace for the command given by cmdName
- * with the given flags, proc, and clientData, then that trace
- * is removed.
+ * See the user documentation.
*
*----------------------------------------------------------------------
*/
-void
-Tcl_UntraceCommand(interp, cmdName, flags, proc, clientData)
- Tcl_Interp *interp; /* Interpreter containing command. */
- CONST char *cmdName; /* Name of command. */
- int flags; /* OR-ed collection of bits, including any
- * of TCL_TRACE_RENAME, TCL_TRACE_DELETE,
- * and any of the TRACE_*_EXEC flags */
- Tcl_CommandTraceProc *proc; /* Procedure assocated with trace. */
- ClientData clientData; /* Arbitrary argument to pass to proc. */
+static int
+StringUpperCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- register CommandTrace *tracePtr;
- CommandTrace *prevPtr;
- Command *cmdPtr;
- Interp *iPtr = (Interp *) interp;
- ActiveCommandTrace *activePtr;
- int hasExecTraces = 0;
-
- cmdPtr = (Command*)Tcl_FindCommand(interp, cmdName,
- NULL, TCL_LEAVE_ERR_MSG);
- if (cmdPtr == NULL) {
- return;
+ int length1, length2;
+ char *string1, *string2;
+
+ if (objc < 2 || objc > 4) {
+ Tcl_WrongNumArgs(interp, 1, objv, "string ?first? ?last?");
+ return TCL_ERROR;
}
- flags &= (TCL_TRACE_RENAME | TCL_TRACE_DELETE | TCL_TRACE_ANY_EXEC);
+ string1 = TclGetStringFromObj(objv[1], &length1);
+
+ if (objc == 2) {
+ Tcl_Obj *resultPtr = Tcl_NewStringObj(string1, length1);
- for (tracePtr = cmdPtr->tracePtr, prevPtr = NULL; ;
- prevPtr = tracePtr, tracePtr = tracePtr->nextPtr) {
- if (tracePtr == NULL) {
- return;
+ length1 = Tcl_UtfToUpper(TclGetString(resultPtr));
+ Tcl_SetObjLength(resultPtr, length1);
+ Tcl_SetObjResult(interp, resultPtr);
+ } else {
+ int first, last;
+ const char *start, *end;
+ Tcl_Obj *resultPtr;
+
+ length1 = Tcl_NumUtfChars(string1, length1) - 1;
+ if (TclGetIntForIndexM(interp,objv[2],length1, &first) != TCL_OK) {
+ return TCL_ERROR;
}
- if ((tracePtr->traceProc == proc)
- && ((tracePtr->flags & (TCL_TRACE_RENAME | TCL_TRACE_DELETE |
- TCL_TRACE_ANY_EXEC)) == flags)
- && (tracePtr->clientData == clientData)) {
- if (tracePtr->flags & TCL_TRACE_ANY_EXEC) {
- hasExecTraces = 1;
- }
- break;
+ if (first < 0) {
+ first = 0;
}
- }
-
- /*
- * The code below makes it possible to delete traces while traces
- * are active: it makes sure that the deleted trace won't be
- * processed by CallCommandTraces.
- */
+ last = first;
- for (activePtr = iPtr->activeCmdTracePtr; activePtr != NULL;
- activePtr = activePtr->nextPtr) {
- if (activePtr->nextTracePtr == tracePtr) {
- if (activePtr->reverseScan) {
- activePtr->nextTracePtr = prevPtr;
- } else {
- activePtr->nextTracePtr = tracePtr->nextPtr;
- }
+ if ((objc == 4) && (TclGetIntForIndexM(interp, objv[3], length1,
+ &last) != TCL_OK)) {
+ return TCL_ERROR;
}
- }
- if (prevPtr == NULL) {
- cmdPtr->tracePtr = tracePtr->nextPtr;
- } else {
- prevPtr->nextPtr = tracePtr->nextPtr;
- }
- tracePtr->flags = 0;
-
- if ((--tracePtr->refCount) <= 0) {
- ckfree((char*)tracePtr);
- }
-
- if (hasExecTraces) {
- for (tracePtr = cmdPtr->tracePtr, prevPtr = NULL; tracePtr != NULL ;
- prevPtr = tracePtr, tracePtr = tracePtr->nextPtr) {
- if (tracePtr->flags & TCL_TRACE_ANY_EXEC) {
- return;
- }
+
+ if (last >= length1) {
+ last = length1;
+ }
+ if (last < first) {
+ Tcl_SetObjResult(interp, objv[1]);
+ return TCL_OK;
}
- /*
- * None of the remaining traces on this command are execution
- * traces. We therefore remove this flag:
- */
- cmdPtr->flags &= ~CMD_HAS_EXEC_TRACES;
- /*
- * Bug 3484621: No more execution trace means we can compile
- * the command again. If we will, invalidate bytecode.
- */
+ string1 = TclGetStringFromObj(objv[1], &length1);
+ start = Tcl_UtfAtIndex(string1, first);
+ end = Tcl_UtfAtIndex(start, last - first + 1);
+ resultPtr = Tcl_NewStringObj(string1, end - string1);
+ string2 = TclGetString(resultPtr) + (start - string1);
- if (cmdPtr->compileProc != NULL) {
- ((Interp *)interp)->compileEpoch++;
- }
+ length2 = Tcl_UtfToUpper(string2);
+ Tcl_SetObjLength(resultPtr, length2 + (start - string1));
+
+ Tcl_AppendToObj(resultPtr, end, -1);
+ Tcl_SetObjResult(interp, resultPtr);
}
+
+ return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
- * TraceCommandProc --
+ * StringTitleCmd --
*
- * This procedure is called to handle command changes that have
- * been traced using the "trace" command, when using the
- * 'rename' or 'delete' options.
+ * This procedure is invoked to process the "string totitle" Tcl command.
+ * See the user documentation for details on what it does. Note that this
+ * command only functions correctly on properly formed Tcl UTF strings.
*
* Results:
- * None.
+ * A standard Tcl result.
*
* Side effects:
- * Depends on the command associated with the trace.
+ * See the user documentation.
*
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
-static void
-TraceCommandProc(clientData, interp, oldName, newName, flags)
- ClientData clientData; /* Information about the command trace. */
- Tcl_Interp *interp; /* Interpreter containing command. */
- CONST char *oldName; /* Name of command being changed. */
- CONST char *newName; /* New name of command. Empty string
- * or NULL means command is being deleted
- * (renamed to ""). */
- int flags; /* OR-ed bits giving operation and other
- * information. */
+static int
+StringTitleCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- Interp *iPtr = (Interp *) interp;
- int stateCode;
- Tcl_SavedResult state;
- TraceCommandInfo *tcmdPtr = (TraceCommandInfo *) clientData;
- int code;
- Tcl_DString cmd;
-
- tcmdPtr->refCount++;
-
- if ((tcmdPtr->flags & flags) && !Tcl_InterpDeleted(interp)) {
- /*
- * Generate a command to execute by appending list elements
- * for the old and new command name and the operation.
- */
+ int length1, length2;
+ char *string1, *string2;
- Tcl_DStringInit(&cmd);
- Tcl_DStringAppend(&cmd, tcmdPtr->command, (int) tcmdPtr->length);
- Tcl_DStringAppendElement(&cmd, oldName);
- Tcl_DStringAppendElement(&cmd, (newName ? newName : ""));
- if (flags & TCL_TRACE_RENAME) {
- Tcl_DStringAppend(&cmd, " rename", 7);
- } else if (flags & TCL_TRACE_DELETE) {
- Tcl_DStringAppend(&cmd, " delete", 7);
- }
+ if (objc < 2 || objc > 4) {
+ Tcl_WrongNumArgs(interp, 1, objv, "string ?first? ?last?");
+ return TCL_ERROR;
+ }
- /*
- * Execute the command. Save the interp's result used for the
- * command, including the value of iPtr->returnCode which may be
- * modified when Tcl_Eval is invoked. We discard any object
- * result the command returns.
- *
- * Add the TCL_TRACE_DESTROYED flag to tcmdPtr to indicate to
- * other areas that this will be destroyed by us, otherwise a
- * double-free might occur depending on what the eval does.
- */
+ string1 = TclGetStringFromObj(objv[1], &length1);
- Tcl_SaveResult(interp, &state);
- stateCode = iPtr->returnCode;
- if (flags & TCL_TRACE_DESTROYED) {
- tcmdPtr->flags |= TCL_TRACE_DESTROYED;
- }
+ if (objc == 2) {
+ Tcl_Obj *resultPtr = Tcl_NewStringObj(string1, length1);
- code = Tcl_EvalEx(interp, Tcl_DStringValue(&cmd),
- Tcl_DStringLength(&cmd), 0);
- if (code != TCL_OK) {
- /* We ignore errors in these traced commands */
- }
+ length1 = Tcl_UtfToTitle(TclGetString(resultPtr));
+ Tcl_SetObjLength(resultPtr, length1);
+ Tcl_SetObjResult(interp, resultPtr);
+ } else {
+ int first, last;
+ const char *start, *end;
+ Tcl_Obj *resultPtr;
- Tcl_RestoreResult(interp, &state);
- iPtr->returnCode = stateCode;
-
- Tcl_DStringFree(&cmd);
- }
- /*
- * We delete when the trace was destroyed or if this is a delete trace,
- * because command deletes are unconditional, so the trace must go away.
- */
- if (flags & (TCL_TRACE_DESTROYED | TCL_TRACE_DELETE)) {
- int untraceFlags = tcmdPtr->flags;
-
- if (tcmdPtr->stepTrace != NULL) {
- Tcl_DeleteTrace(interp, tcmdPtr->stepTrace);
- tcmdPtr->stepTrace = NULL;
- if (tcmdPtr->startCmd != NULL) {
- ckfree((char *)tcmdPtr->startCmd);
- }
+ length1 = Tcl_NumUtfChars(string1, length1) - 1;
+ if (TclGetIntForIndexM(interp,objv[2],length1, &first) != TCL_OK) {
+ return TCL_ERROR;
}
- if (tcmdPtr->flags & TCL_TRACE_EXEC_IN_PROGRESS) {
- /* Postpone deletion, until exec trace returns */
- tcmdPtr->flags = 0;
+ if (first < 0) {
+ first = 0;
}
+ last = first;
- /*
- * We need to construct the same flags for Tcl_UntraceCommand
- * as were passed to Tcl_TraceCommand. Reproduce the processing
- * of [trace add execution/command]. Be careful to keep this
- * code in sync with that.
- */
+ if ((objc == 4) && (TclGetIntForIndexM(interp, objv[3], length1,
+ &last) != TCL_OK)) {
+ return TCL_ERROR;
+ }
- if (untraceFlags & TCL_TRACE_ANY_EXEC) {
- untraceFlags |= TCL_TRACE_DELETE;
- if (untraceFlags & (TCL_TRACE_ENTER_DURING_EXEC
- | TCL_TRACE_LEAVE_DURING_EXEC)) {
- untraceFlags |= (TCL_TRACE_ENTER_EXEC | TCL_TRACE_LEAVE_EXEC);
- }
- } else if (untraceFlags & TCL_TRACE_RENAME) {
- untraceFlags |= TCL_TRACE_DELETE;
+ if (last >= length1) {
+ last = length1;
+ }
+ if (last < first) {
+ Tcl_SetObjResult(interp, objv[1]);
+ return TCL_OK;
}
- /*
- * Remove the trace since TCL_TRACE_DESTROYED tells us to, or the
- * command we're tracing has just gone away. Then decrement the
- * clientData refCount that was set up by trace creation.
- *
- * Note that we save the (return) state of the interpreter to prevent
- * bizarre error messages.
- */
+ string1 = TclGetStringFromObj(objv[1], &length1);
+ start = Tcl_UtfAtIndex(string1, first);
+ end = Tcl_UtfAtIndex(start, last - first + 1);
+ resultPtr = Tcl_NewStringObj(string1, end - string1);
+ string2 = TclGetString(resultPtr) + (start - string1);
- Tcl_SaveResult(interp, &state);
- stateCode = iPtr->returnCode;
- Tcl_UntraceCommand(interp, oldName, untraceFlags,
- TraceCommandProc, clientData);
- Tcl_RestoreResult(interp, &state);
- iPtr->returnCode = stateCode;
+ length2 = Tcl_UtfToTitle(string2);
+ Tcl_SetObjLength(resultPtr, length2 + (start - string1));
- tcmdPtr->refCount--;
- }
- tcmdPtr->refCount--;
- if (tcmdPtr->refCount < 0) {
- Tcl_Panic("TraceCommandProc: negative TraceCommandInfo refCount");
- }
- if (tcmdPtr->refCount == 0) {
- ckfree((char*)tcmdPtr);
+ Tcl_AppendToObj(resultPtr, end, -1);
+ Tcl_SetObjResult(interp, resultPtr);
}
- return;
+
+ return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
- * TclCheckExecutionTraces --
+ * StringTrimCmd --
*
- * Checks on all current command execution traces, and invokes
- * procedures which have been registered. This procedure can be
- * used by other code which performs execution to unify the
- * tracing system, so that execution traces will function for that
- * other code.
- *
- * For instance extensions like [incr Tcl] which use their
- * own execution technique can make use of Tcl's tracing.
- *
- * This procedure is called by 'TclEvalObjvInternal'
+ * This procedure is invoked to process the "string trim" Tcl command.
+ * See the user documentation for details on what it does. Note that this
+ * command only functions correctly on properly formed Tcl UTF strings.
*
* Results:
- * The return value is a standard Tcl completion code such as
- * TCL_OK or TCL_ERROR, etc.
+ * A standard Tcl result.
*
* Side effects:
- * Those side effects made by any trace procedures called.
+ * See the user documentation.
*
*----------------------------------------------------------------------
*/
-int
-TclCheckExecutionTraces(interp, command, numChars, cmdPtr, code,
- traceFlags, objc, objv)
- Tcl_Interp *interp; /* The current interpreter. */
- CONST char *command; /* Pointer to beginning of the current
- * command string. */
- int numChars; /* The number of characters in 'command'
- * which are part of the command string. */
- Command *cmdPtr; /* Points to command's Command struct. */
- int code; /* The current result code. */
- int traceFlags; /* Current tracing situation. */
- int objc; /* Number of arguments for the command. */
- Tcl_Obj *CONST objv[]; /* Pointers to Tcl_Obj of each argument. */
+
+static int
+StringTrimCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- Interp *iPtr = (Interp *) interp;
- CommandTrace *tracePtr, *lastTracePtr;
- ActiveCommandTrace active;
- int curLevel;
- int traceCode = TCL_OK;
- TraceCommandInfo* tcmdPtr;
-
- if (command == NULL || cmdPtr->tracePtr == NULL) {
- return traceCode;
- }
-
- curLevel = ((iPtr->varFramePtr == NULL) ? 0 : iPtr->varFramePtr->level);
-
- active.nextPtr = iPtr->activeCmdTracePtr;
- iPtr->activeCmdTracePtr = &active;
-
- active.cmdPtr = cmdPtr;
- lastTracePtr = NULL;
- for (tracePtr = cmdPtr->tracePtr;
- (traceCode == TCL_OK) && (tracePtr != NULL);
- tracePtr = active.nextTracePtr) {
- if (traceFlags & TCL_TRACE_LEAVE_EXEC) {
- /* execute the trace command in order of creation for "leave" */
- active.reverseScan = 1;
- active.nextTracePtr = NULL;
- tracePtr = cmdPtr->tracePtr;
- while (tracePtr->nextPtr != lastTracePtr) {
- active.nextTracePtr = tracePtr;
- tracePtr = tracePtr->nextPtr;
- }
- } else {
- active.reverseScan = 0;
- active.nextTracePtr = tracePtr->nextPtr;
- }
- if (tracePtr->traceProc == TraceCommandProc) {
- tcmdPtr = (TraceCommandInfo*)tracePtr->clientData;
- if (tcmdPtr->flags != 0) {
- tcmdPtr->curFlags = traceFlags | TCL_TRACE_EXEC_DIRECT;
- tcmdPtr->curCode = code;
- tcmdPtr->refCount++;
- traceCode = TraceExecutionProc((ClientData)tcmdPtr, interp,
- curLevel, command, (Tcl_Command)cmdPtr, objc, objv);
- tcmdPtr->refCount--;
- if (tcmdPtr->refCount < 0) {
- Tcl_Panic("TclCheckExecutionTraces: negative TraceCommandInfo refCount");
- }
- if (tcmdPtr->refCount == 0) {
- ckfree((char*)tcmdPtr);
- }
- }
- }
- if (active.nextTracePtr) {
- lastTracePtr = active.nextTracePtr->nextPtr;
- }
+ const char *string1, *string2;
+ int triml, trimr, length1, length2;
+
+ if (objc == 3) {
+ string2 = TclGetStringFromObj(objv[2], &length2);
+ } else if (objc == 2) {
+ string2 = " \t\n\r";
+ length2 = strlen(string2);
+ } else {
+ Tcl_WrongNumArgs(interp, 1, objv, "string ?chars?");
+ return TCL_ERROR;
}
- iPtr->activeCmdTracePtr = active.nextPtr;
- return(traceCode);
+ string1 = TclGetStringFromObj(objv[1], &length1);
+
+ triml = TclTrimLeft(string1, length1, string2, length2);
+ trimr = TclTrimRight(string1 + triml, length1 - triml, string2, length2);
+
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj(string1 + triml, length1 - triml - trimr));
+ return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
- * TclCheckInterpTraces --
+ * StringTrimLCmd --
*
- * Checks on all current traces, and invokes procedures which
- * have been registered. This procedure can be used by other
- * code which performs execution to unify the tracing system.
- * For instance extensions like [incr Tcl] which use their
- * own execution technique can make use of Tcl's tracing.
- *
- * This procedure is called by 'TclEvalObjvInternal'
+ * This procedure is invoked to process the "string trimleft" Tcl
+ * command. See the user documentation for details on what it does. Note
+ * that this command only functions correctly on properly formed Tcl UTF
+ * strings.
*
* Results:
- * The return value is a standard Tcl completion code such as
- * TCL_OK or TCL_ERROR, etc.
+ * A standard Tcl result.
*
* Side effects:
- * Those side effects made by any trace procedures called.
+ * See the user documentation.
*
*----------------------------------------------------------------------
*/
-int
-TclCheckInterpTraces(interp, command, numChars, cmdPtr, code,
- traceFlags, objc, objv)
- Tcl_Interp *interp; /* The current interpreter. */
- CONST char *command; /* Pointer to beginning of the current
- * command string. */
- int numChars; /* The number of characters in 'command'
- * which are part of the command string. */
- Command *cmdPtr; /* Points to command's Command struct. */
- int code; /* The current result code. */
- int traceFlags; /* Current tracing situation. */
- int objc; /* Number of arguments for the command. */
- Tcl_Obj *CONST objv[]; /* Pointers to Tcl_Obj of each argument. */
+
+static int
+StringTrimLCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- Interp *iPtr = (Interp *) interp;
- Trace *tracePtr, *lastTracePtr;
- ActiveInterpTrace active;
- int curLevel;
- int traceCode = TCL_OK;
-
- if (command == NULL || iPtr->tracePtr == NULL ||
- (iPtr->flags & INTERP_TRACE_IN_PROGRESS)) {
- return(traceCode);
- }
-
- curLevel = iPtr->numLevels;
-
- active.nextPtr = iPtr->activeInterpTracePtr;
- iPtr->activeInterpTracePtr = &active;
-
- lastTracePtr = NULL;
- for ( tracePtr = iPtr->tracePtr;
- (traceCode == TCL_OK) && (tracePtr != NULL);
- tracePtr = active.nextTracePtr) {
- if (traceFlags & TCL_TRACE_ENTER_EXEC) {
- /*
- * Execute the trace command in reverse order of creation
- * for "enterstep" operation. The order is changed for
- * "enterstep" instead of for "leavestep" as was done in
- * TclCheckExecutionTraces because for step traces,
- * Tcl_CreateObjTrace creates one more linked list of traces
- * which results in one more reversal of trace invocation.
- */
- active.reverseScan = 1;
- active.nextTracePtr = NULL;
- tracePtr = iPtr->tracePtr;
- while (tracePtr->nextPtr != lastTracePtr) {
- active.nextTracePtr = tracePtr;
- tracePtr = tracePtr->nextPtr;
- }
- if (active.nextTracePtr) {
- lastTracePtr = active.nextTracePtr->nextPtr;
- }
- } else {
- active.reverseScan = 0;
- active.nextTracePtr = tracePtr->nextPtr;
- }
- if (tracePtr->level > 0 && curLevel > tracePtr->level) {
- continue;
- }
- if (!(tracePtr->flags & TCL_TRACE_EXEC_IN_PROGRESS)) {
- /*
- * The proc invoked might delete the traced command which
- * which might try to free tracePtr. We want to use tracePtr
- * until the end of this if section, so we use
- * Tcl_Preserve() and Tcl_Release() to be sure it is not
- * freed while we still need it.
- */
- Tcl_Preserve((ClientData) tracePtr);
- tracePtr->flags |= TCL_TRACE_EXEC_IN_PROGRESS;
-
- if (tracePtr->flags & (TCL_TRACE_ENTER_EXEC | TCL_TRACE_LEAVE_EXEC)) {
- /* New style trace */
- if (tracePtr->flags & traceFlags) {
- if (tracePtr->proc == TraceExecutionProc) {
- TraceCommandInfo *tcmdPtr =
- (TraceCommandInfo *) tracePtr->clientData;
- tcmdPtr->curFlags = traceFlags;
- tcmdPtr->curCode = code;
- }
- traceCode = (tracePtr->proc)(tracePtr->clientData,
- interp, curLevel, command, (Tcl_Command)cmdPtr,
- objc, objv);
- }
- } else {
- /* Old-style trace */
-
- if (traceFlags & TCL_TRACE_ENTER_EXEC) {
- /*
- * Old-style interpreter-wide traces only trigger
- * before the command is executed.
- */
- traceCode = CallTraceProcedure(interp, tracePtr, cmdPtr,
- command, numChars, objc, objv);
- }
- }
- tracePtr->flags &= ~TCL_TRACE_EXEC_IN_PROGRESS;
- Tcl_Release((ClientData) tracePtr);
- }
+ const char *string1, *string2;
+ int trim, length1, length2;
+
+ if (objc == 3) {
+ string2 = TclGetStringFromObj(objv[2], &length2);
+ } else if (objc == 2) {
+ string2 = " \t\n\r";
+ length2 = strlen(string2);
+ } else {
+ Tcl_WrongNumArgs(interp, 1, objv, "string ?chars?");
+ return TCL_ERROR;
}
- iPtr->activeInterpTracePtr = active.nextPtr;
- return(traceCode);
+ string1 = TclGetStringFromObj(objv[1], &length1);
+
+ trim = TclTrimLeft(string1, length1, string2, length2);
+
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(string1+trim, length1-trim));
+ return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
- * CallTraceProcedure --
+ * StringTrimRCmd --
*
- * Invokes a trace procedure registered with an interpreter. These
- * procedures trace command execution. Currently this trace procedure
- * is called with the address of the string-based Tcl_CmdProc for the
- * command, not the Tcl_ObjCmdProc.
+ * This procedure is invoked to process the "string trimright" Tcl
+ * command. See the user documentation for details on what it does. Note
+ * that this command only functions correctly on properly formed Tcl UTF
+ * strings.
*
* Results:
- * None.
+ * A standard Tcl result.
*
* Side effects:
- * Those side effects made by the trace procedure.
+ * See the user documentation.
*
*----------------------------------------------------------------------
*/
static int
-CallTraceProcedure(interp, tracePtr, cmdPtr, command, numChars, objc, objv)
- Tcl_Interp *interp; /* The current interpreter. */
- register Trace *tracePtr; /* Describes the trace procedure to call. */
- Command *cmdPtr; /* Points to command's Command struct. */
- CONST char *command; /* Points to the first character of the
- * command's source before substitutions. */
- int numChars; /* The number of characters in the
- * command's source. */
- register int objc; /* Number of arguments for the command. */
- Tcl_Obj *CONST objv[]; /* Pointers to Tcl_Obj of each argument. */
+StringTrimRCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
- Interp *iPtr = (Interp *) interp;
- char *commandCopy;
- int traceCode;
+ const char *string1, *string2;
+ int trim, length1, length2;
+
+ if (objc == 3) {
+ string2 = TclGetStringFromObj(objv[2], &length2);
+ } else if (objc == 2) {
+ string2 = " \t\n\r";
+ length2 = strlen(string2);
+ } else {
+ Tcl_WrongNumArgs(interp, 1, objv, "string ?chars?");
+ return TCL_ERROR;
+ }
+ string1 = TclGetStringFromObj(objv[1], &length1);
- /*
- * Copy the command characters into a new string.
- */
+ trim = TclTrimRight(string1, length1, string2, length2);
- commandCopy = (char *) ckalloc((unsigned) (numChars + 1));
- memcpy((VOID *) commandCopy, (VOID *) command, (size_t) numChars);
- commandCopy[numChars] = '\0';
-
- /*
- * Call the trace procedure then free allocated storage.
- */
-
- traceCode = (tracePtr->proc)( tracePtr->clientData, (Tcl_Interp*) iPtr,
- iPtr->numLevels, commandCopy,
- (Tcl_Command) cmdPtr, objc, objv );
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(string1, length1-trim));
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitStringCmd --
+ *
+ * This procedure creates the "string" Tcl command. See the user
+ * documentation for details on what it does. Note that this command only
+ * functions correctly on properly formed Tcl UTF strings.
+ *
+ * Also note that the primary methods here (equal, compare, match, ...)
+ * have bytecode equivalents. You will find the code for those in
+ * tclExecute.c. The code here will only be used in the non-bc case (like
+ * in an 'eval').
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
- ckfree((char *) commandCopy);
- return(traceCode);
+Tcl_Command
+TclInitStringCmd(
+ Tcl_Interp *interp) /* Current interpreter. */
+{
+ static const EnsembleImplMap stringImplMap[] = {
+ {"bytelength", StringBytesCmd, NULL},
+ {"compare", StringCmpCmd, TclCompileStringCmpCmd},
+ {"equal", StringEqualCmd, TclCompileStringEqualCmd},
+ {"first", StringFirstCmd, NULL},
+ {"index", StringIndexCmd, TclCompileStringIndexCmd},
+ {"is", StringIsCmd, NULL},
+ {"last", StringLastCmd, NULL},
+ {"length", StringLenCmd, TclCompileStringLenCmd},
+ {"map", StringMapCmd, NULL},
+ {"match", StringMatchCmd, TclCompileStringMatchCmd},
+ {"range", StringRangeCmd, NULL},
+ {"repeat", StringReptCmd, NULL},
+ {"replace", StringRplcCmd, NULL},
+ {"reverse", StringRevCmd, NULL},
+ {"tolower", StringLowerCmd, NULL},
+ {"toupper", StringUpperCmd, NULL},
+ {"totitle", StringTitleCmd, NULL},
+ {"trim", StringTrimCmd, NULL},
+ {"trimleft", StringTrimLCmd, NULL},
+ {"trimright", StringTrimRCmd, NULL},
+ {"wordend", StringEndCmd, NULL},
+ {"wordstart", StringStartCmd, NULL},
+ {NULL}
+ };
+
+ return TclMakeEnsemble(interp, "string", stringImplMap);
}
/*
*----------------------------------------------------------------------
*
- * CommandObjTraceDeleted --
+ * Tcl_SubstObjCmd --
*
- * Ensure the trace is correctly deleted by decrementing its
- * refCount and only deleting if no other references exist.
+ * This procedure is invoked to process the "subst" Tcl command. See the
+ * user documentation for details on what it does. This command relies on
+ * Tcl_SubstObj() for its implementation.
*
* Results:
- * None.
+ * A standard Tcl result.
*
* Side effects:
- * May release memory.
+ * See the user documentation.
*
*----------------------------------------------------------------------
*/
-static void
-CommandObjTraceDeleted(ClientData clientData) {
- TraceCommandInfo* tcmdPtr = (TraceCommandInfo*)clientData;
- tcmdPtr->refCount--;
- if (tcmdPtr->refCount < 0) {
- Tcl_Panic("CommandObjTraceDeleted: negative TraceCommandInfo refCount");
+
+int
+Tcl_SubstObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
+{
+ static CONST char *substOptions[] = {
+ "-nobackslashes", "-nocommands", "-novariables", NULL
+ };
+ enum substOptions {
+ SUBST_NOBACKSLASHES, SUBST_NOCOMMANDS, SUBST_NOVARS
+ };
+ Tcl_Obj *resultPtr;
+ int flags, i;
+
+ /*
+ * Parse command-line options.
+ */
+
+ flags = TCL_SUBST_ALL;
+ for (i = 1; i < (objc-1); i++) {
+ int optionIndex;
+
+ if (Tcl_GetIndexFromObj(interp, objv[i], substOptions, "switch", 0,
+ &optionIndex) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ switch (optionIndex) {
+ case SUBST_NOBACKSLASHES:
+ flags &= ~TCL_SUBST_BACKSLASHES;
+ break;
+ case SUBST_NOCOMMANDS:
+ flags &= ~TCL_SUBST_COMMANDS;
+ break;
+ case SUBST_NOVARS:
+ flags &= ~TCL_SUBST_VARIABLES;
+ break;
+ default:
+ Tcl_Panic("Tcl_SubstObjCmd: bad option index to SubstOptions");
+ }
}
- if (tcmdPtr->refCount == 0) {
- ckfree((char*)tcmdPtr);
+ if (i != objc-1) {
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "?-nobackslashes? ?-nocommands? ?-novariables? string");
+ return TCL_ERROR;
+ }
+
+ /*
+ * Perform the substitution.
+ */
+
+ resultPtr = Tcl_SubstObj(interp, objv[i], flags);
+
+ if (resultPtr == NULL) {
+ return TCL_ERROR;
}
+ Tcl_SetObjResult(interp, resultPtr);
+ return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
- * TraceExecutionProc --
+ * Tcl_SwitchObjCmd --
*
- * This procedure is invoked whenever code relevant to a
- * 'trace execution' command is executed. It is called in one
- * of two ways in Tcl's core:
- *
- * (i) by the TclCheckExecutionTraces, when an execution trace
- * has been triggered.
- * (ii) by TclCheckInterpTraces, when a prior execution trace has
- * created a trace of the internals of a procedure, passing in
- * this procedure as the one to be called.
+ * This object-based procedure is invoked to process the "switch" Tcl
+ * command. See the user documentation for details on what it does.
*
* Results:
- * The return value is a standard Tcl completion code such as
- * TCL_OK or TCL_ERROR, etc.
+ * A standard Tcl object result.
*
* Side effects:
- * May invoke an arbitrary Tcl procedure, and may create or
- * delete an interpreter-wide trace.
+ * See the user documentation.
*
*----------------------------------------------------------------------
*/
-static int
-TraceExecutionProc(ClientData clientData, Tcl_Interp *interp,
- int level, CONST char* command, Tcl_Command cmdInfo,
- int objc, struct Tcl_Obj *CONST objv[]) {
- int call = 0;
+
+int
+Tcl_SwitchObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
+{
+ int i,j, index, mode, foundmode, result, splitObjs, numMatchesSaved;
+ int noCase, patternLength;
+ char *pattern;
+ Tcl_Obj *stringObj, *indexVarObj, *matchVarObj;
+ Tcl_Obj *CONST *savedObjv = objv;
+ Tcl_RegExp regExpr = NULL;
Interp *iPtr = (Interp *) interp;
- TraceCommandInfo* tcmdPtr = (TraceCommandInfo*)clientData;
- int flags = tcmdPtr->curFlags;
- int code = tcmdPtr->curCode;
- int traceCode = TCL_OK;
-
- if (tcmdPtr->flags & TCL_TRACE_EXEC_IN_PROGRESS) {
- /*
- * Inside any kind of execution trace callback, we do
- * not allow any further execution trace callbacks to
- * be called for the same trace.
- */
- return traceCode;
+ int pc = 0;
+ int bidx = 0; /* Index of body argument. */
+ Tcl_Obj *blist = NULL; /* List obj which is the body */
+ CmdFrame *ctxPtr; /* Copy of the topmost cmdframe, to allow us
+ * to mess with the line information */
+
+ /*
+ * If you add options that make -e and -g not unique prefixes of -exact or
+ * -glob, you *must* fix TclCompileSwitchCmd's option parser as well.
+ */
+
+ static CONST char *options[] = {
+ "-exact", "-glob", "-indexvar", "-matchvar", "-nocase", "-regexp",
+ "--", NULL
+ };
+ enum options {
+ OPT_EXACT, OPT_GLOB, OPT_INDEXV, OPT_MATCHV, OPT_NOCASE, OPT_REGEXP,
+ OPT_LAST
+ };
+ typedef int (*strCmpFn_t)(const char *, const char *);
+ strCmpFn_t strCmpFn = strcmp;
+
+ mode = OPT_EXACT;
+ foundmode = 0;
+ indexVarObj = NULL;
+ matchVarObj = NULL;
+ numMatchesSaved = 0;
+ noCase = 0;
+ for (i = 1; i < objc-2; i++) {
+ if (TclGetString(objv[i])[0] != '-') {
+ break;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0,
+ &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ switch ((enum options) index) {
+ /*
+ * General options.
+ */
+
+ case OPT_LAST:
+ i++;
+ goto finishedOptions;
+ case OPT_NOCASE:
+ strCmpFn = strcasecmp;
+ noCase = 1;
+ break;
+
+ /*
+ * Handle the different switch mode options.
+ */
+
+ default:
+ if (foundmode) {
+ /*
+ * Mode already set via -exact, -glob, or -regexp.
+ */
+
+ Tcl_AppendResult(interp, "bad option \"",
+ TclGetString(objv[i]), "\": ", options[mode],
+ " option already found", NULL);
+ return TCL_ERROR;
+ } else {
+ foundmode = 1;
+ mode = index;
+ break;
+ }
+
+ /*
+ * Check for TIP#75 options specifying the variables to write
+ * regexp information into.
+ */
+
+ case OPT_INDEXV:
+ i++;
+ if (i >= objc-2) {
+ Tcl_AppendResult(interp, "missing variable name argument to ",
+ "-indexvar", " option", NULL);
+ return TCL_ERROR;
+ }
+ indexVarObj = objv[i];
+ numMatchesSaved = -1;
+ break;
+ case OPT_MATCHV:
+ i++;
+ if (i >= objc-2) {
+ Tcl_AppendResult(interp, "missing variable name argument to ",
+ "-matchvar", " option", NULL);
+ return TCL_ERROR;
+ }
+ matchVarObj = objv[i];
+ numMatchesSaved = -1;
+ break;
+ }
}
-
- if (!Tcl_InterpDeleted(interp)) {
+
+ finishedOptions:
+ if (objc - i < 2) {
+ Tcl_WrongNumArgs(interp, 1, objv,
+ "?switches? string pattern body ... ?default body?");
+ return TCL_ERROR;
+ }
+ if (indexVarObj != NULL && mode != OPT_REGEXP) {
+ Tcl_AppendResult(interp,
+ "-indexvar option requires -regexp option", NULL);
+ return TCL_ERROR;
+ }
+ if (matchVarObj != NULL && mode != OPT_REGEXP) {
+ Tcl_AppendResult(interp,
+ "-matchvar option requires -regexp option", NULL);
+ return TCL_ERROR;
+ }
+
+ stringObj = objv[i];
+ objc -= i + 1;
+ objv += i + 1;
+ bidx = i + 1; /* First after the match string. */
+
+ /*
+ * If all of the pattern/command pairs are lumped into a single argument,
+ * split them out again.
+ *
+ * TIP #280: Determine the lines the words in the list start at, based on
+ * the same data for the list word itself. The cmdFramePtr line
+ * information is manipulated directly.
+ */
+
+ splitObjs = 0;
+ if (objc == 1) {
+ Tcl_Obj **listv;
+ blist = objv[0];
+
+ if (TclListObjGetElements(interp, objv[0], &objc, &listv) != TCL_OK){
+ return TCL_ERROR;
+ }
+
/*
- * Check whether the current call is going to eval arbitrary
- * Tcl code with a generated trace, or whether we are only
- * going to setup interpreter-wide traces to implement the
- * 'step' traces. This latter situation can happen if
- * we create a command trace without either before or after
- * operations, but with either of the step operations.
+ * Ensure that the list is non-empty.
*/
- if (flags & TCL_TRACE_EXEC_DIRECT) {
- call = flags & tcmdPtr->flags
- & (TCL_TRACE_ENTER_EXEC | TCL_TRACE_LEAVE_EXEC);
- } else {
- call = 1;
+
+ if (objc < 1) {
+ Tcl_WrongNumArgs(interp, 1, savedObjv,
+ "?switches? string {pattern body ... ?default body?}");
+ return TCL_ERROR;
}
+ objv = listv;
+ splitObjs = 1;
+ }
+
+ /*
+ * Complain if there is an odd number of words in the list of patterns and
+ * bodies.
+ */
+
+ if (objc % 2) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "extra switch pattern with no body", NULL);
+
/*
- * First, if we have returned back to the level at which we
- * created an interpreter trace for enterstep and/or leavestep
- * execution traces, we remove it here.
+ * Check if this can be due to a badly placed comment in the switch
+ * block.
+ *
+ * The following is an heuristic to detect the infamous "comment in
+ * switch" error: just check if a pattern begins with '#'.
*/
- if (flags & TCL_TRACE_LEAVE_EXEC) {
- if ((tcmdPtr->stepTrace != NULL) && (level == tcmdPtr->startLevel)
- && (strcmp(command, tcmdPtr->startCmd) == 0)) {
- Tcl_DeleteTrace(interp, tcmdPtr->stepTrace);
- tcmdPtr->stepTrace = NULL;
- if (tcmdPtr->startCmd != NULL) {
- ckfree((char *)tcmdPtr->startCmd);
- }
+
+ 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);
+ break;
+ }
}
}
-
+
+ return TCL_ERROR;
+ }
+
+ /*
+ * Complain if the last body is a continuation. Note that this check
+ * assumes that the list is non-empty!
+ */
+
+ if (strcmp(TclGetString(objv[objc-1]), "-") == 0) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "no body specified for pattern \"",
+ TclGetString(objv[objc-2]), "\"", NULL);
+ return TCL_ERROR;
+ }
+
+ for (i = 0; i < objc; i += 2) {
/*
- * Second, create the tcl callback, if required.
+ * See if the pattern matches the string.
*/
- if (call) {
- Tcl_SavedResult state;
- int stateCode, i, saveInterpFlags;
- Tcl_DString cmd;
- Tcl_DString sub;
-
- Tcl_DStringInit(&cmd);
- Tcl_DStringAppend(&cmd, tcmdPtr->command, (int)tcmdPtr->length);
- /* Append command with arguments */
- Tcl_DStringInit(&sub);
- for (i = 0; i < objc; i++) {
- char* str;
- int len;
- str = Tcl_GetStringFromObj(objv[i],&len);
- Tcl_DStringAppendElement(&sub, str);
- }
- Tcl_DStringAppendElement(&cmd, Tcl_DStringValue(&sub));
- Tcl_DStringFree(&sub);
- if (flags & TCL_TRACE_ENTER_EXEC) {
- /* Append trace operation */
- if (flags & TCL_TRACE_EXEC_DIRECT) {
- Tcl_DStringAppendElement(&cmd, "enter");
- } else {
- Tcl_DStringAppendElement(&cmd, "enterstep");
+ pattern = TclGetStringFromObj(objv[i], &patternLength);
+
+ if ((i == objc - 2) && (*pattern == 'd')
+ && (strcmp(pattern, "default") == 0)) {
+ Tcl_Obj *emptyObj = NULL;
+
+ /*
+ * If either indexVarObj or matchVarObj are non-NULL, we're in
+ * REGEXP mode but have reached the default clause anyway. TIP#75
+ * specifies that we set the variables to empty lists (== empty
+ * objects) in that case.
+ */
+
+ if (indexVarObj != NULL) {
+ TclNewObj(emptyObj);
+ if (Tcl_ObjSetVar2(interp, indexVarObj, NULL, emptyObj,
+ TCL_LEAVE_ERR_MSG) == NULL) {
+ return TCL_ERROR;
}
- } else if (flags & TCL_TRACE_LEAVE_EXEC) {
- Tcl_Obj* resultCode;
- char* resultCodeStr;
-
- /* Append result code */
- resultCode = Tcl_NewIntObj(code);
- resultCodeStr = Tcl_GetString(resultCode);
- Tcl_DStringAppendElement(&cmd, resultCodeStr);
- Tcl_DecrRefCount(resultCode);
-
- /* Append result string */
- Tcl_DStringAppendElement(&cmd, Tcl_GetStringResult(interp));
- /* Append trace operation */
- if (flags & TCL_TRACE_EXEC_DIRECT) {
- Tcl_DStringAppendElement(&cmd, "leave");
+ }
+ if (matchVarObj != NULL) {
+ if (emptyObj == NULL) {
+ TclNewObj(emptyObj);
+ }
+ if (Tcl_ObjSetVar2(interp, matchVarObj, NULL, emptyObj,
+ TCL_LEAVE_ERR_MSG) == NULL) {
+ return TCL_ERROR;
+ }
+ }
+ goto matchFound;
+ } else {
+ switch (mode) {
+ case OPT_EXACT:
+ if (strCmpFn(TclGetString(stringObj), pattern) == 0) {
+ goto matchFound;
+ }
+ break;
+ case OPT_GLOB:
+ if (Tcl_StringCaseMatch(TclGetString(stringObj), pattern,
+ noCase)) {
+ goto matchFound;
+ }
+ break;
+ case OPT_REGEXP:
+ regExpr = Tcl_GetRegExpFromObj(interp, objv[i],
+ TCL_REG_ADVANCED | (noCase ? TCL_REG_NOCASE : 0));
+ if (regExpr == NULL) {
+ return TCL_ERROR;
} else {
- Tcl_DStringAppendElement(&cmd, "leavestep");
+ int matched = Tcl_RegExpExecObj(interp, regExpr,
+ stringObj, 0, numMatchesSaved, 0);
+
+ if (matched < 0) {
+ return TCL_ERROR;
+ } else if (matched) {
+ goto matchFoundRegexp;
+ }
}
- } else {
- panic("TraceExecutionProc: bad flag combination");
+ break;
}
-
- /*
- * Execute the command. Save the interp's result used for
- * the command, including the value of iPtr->returnCode which
- * may be modified when Tcl_Eval is invoked. We discard any
- * object result the command returns.
- */
+ }
+ }
+ return TCL_OK;
- Tcl_SaveResult(interp, &state);
- stateCode = iPtr->returnCode;
-
- saveInterpFlags = iPtr->flags;
- iPtr->flags |= INTERP_TRACE_IN_PROGRESS;
- tcmdPtr->flags |= TCL_TRACE_EXEC_IN_PROGRESS;
- tcmdPtr->refCount++;
- /*
- * This line can have quite arbitrary side-effects,
- * including deleting the trace, the command being
- * traced, or even the interpreter.
- */
- traceCode = Tcl_Eval(interp, Tcl_DStringValue(&cmd));
- tcmdPtr->flags &= ~TCL_TRACE_EXEC_IN_PROGRESS;
+ matchFoundRegexp:
+ /*
+ * We are operating in REGEXP mode and we need to store information about
+ * what we matched in some user-nominated arrays. So build the lists of
+ * values and indices to write here. [TIP#75]
+ */
- /*
- * Restore the interp tracing flag to prevent cmd traces
- * from affecting interp traces
- */
- iPtr->flags = saveInterpFlags;;
- if (tcmdPtr->flags == 0) {
- flags |= TCL_TRACE_DESTROYED;
+ if (numMatchesSaved) {
+ Tcl_RegExpInfo info;
+ Tcl_Obj *matchesObj, *indicesObj = NULL;
+
+ Tcl_RegExpGetInfo(regExpr, &info);
+ if (matchVarObj != NULL) {
+ TclNewObj(matchesObj);
+ } else {
+ matchesObj = NULL;
+ }
+ if (indexVarObj != NULL) {
+ TclNewObj(indicesObj);
+ }
+
+ for (j=0 ; j<=info.nsubs ; j++) {
+ if (indexVarObj != NULL) {
+ Tcl_Obj *rangeObjAry[2];
+
+ rangeObjAry[0] = Tcl_NewLongObj(info.matches[j].start);
+ rangeObjAry[1] = Tcl_NewLongObj(info.matches[j].end);
+
+ /*
+ * Never fails; the object is always clean at this point.
+ */
+
+ Tcl_ListObjAppendElement(NULL, indicesObj,
+ Tcl_NewListObj(2, rangeObjAry));
}
-
- if (traceCode == TCL_OK) {
- /* Restore result if trace execution was successful */
- Tcl_RestoreResult(interp, &state);
- iPtr->returnCode = stateCode;
- } else {
- Tcl_DiscardResult(&state);
+
+ if (matchVarObj != NULL) {
+ Tcl_Obj *substringObj;
+
+ substringObj = Tcl_GetRange(stringObj,
+ info.matches[j].start, info.matches[j].end-1);
+
+ /*
+ * Never fails; the object is always clean at this point.
+ */
+
+ Tcl_ListObjAppendElement(NULL, matchesObj, substringObj);
}
+ }
- Tcl_DStringFree(&cmd);
+ if (indexVarObj != NULL) {
+ if (Tcl_ObjSetVar2(interp, indexVarObj, NULL, indicesObj,
+ TCL_LEAVE_ERR_MSG) == NULL) {
+ /*
+ * Careful! Check to see if we have allocated the list of
+ * matched strings; if so (but there was an error assigning
+ * the indices list) we have a potential memory leak because
+ * the match list has not been written to a variable. Except
+ * that we'll clean that up right now.
+ */
+
+ if (matchesObj != NULL) {
+ Tcl_DecrRefCount(matchesObj);
+ }
+ return TCL_ERROR;
+ }
+ }
+ if (matchVarObj != NULL) {
+ if (Tcl_ObjSetVar2(interp, matchVarObj, NULL, matchesObj,
+ TCL_LEAVE_ERR_MSG) == NULL) {
+ /*
+ * Unlike above, if indicesObj is non-NULL at this point, it
+ * will have been written to a variable already and will hence
+ * not be leaked.
+ */
+
+ return TCL_ERROR;
+ }
}
-
+ }
+
+ /*
+ * We've got a match. Find a body to execute, skipping bodies that are
+ * "-".
+ */
+
+ matchFound:
+ ctxPtr = (CmdFrame *) TclStackAlloc(interp, sizeof(CmdFrame));
+ *ctxPtr = *iPtr->cmdFramePtr;
+
+ if (splitObjs) {
/*
- * Third, if there are any step execution traces for this proc,
- * we register an interpreter trace to invoke enterstep and/or
- * leavestep traces.
- * We also need to save the current stack level and the proc
- * string in startLevel and startCmd so that we can delete this
- * interpreter trace when it reaches the end of this proc.
+ * We have to perform the GetSrc and other type dependent handling of
+ * the frame here because we are munging with the line numbers,
+ * something the other commands like if, etc. are not doing. Them are
+ * fine with simply passing the CmdFrame through and having the
+ * special handling done in 'info frame', or the bc compiler
*/
- if ((flags & TCL_TRACE_ENTER_EXEC) && (tcmdPtr->stepTrace == NULL)
- && (tcmdPtr->flags & (TCL_TRACE_ENTER_DURING_EXEC |
- TCL_TRACE_LEAVE_DURING_EXEC))) {
- tcmdPtr->startLevel = level;
- tcmdPtr->startCmd =
- (char *) ckalloc((unsigned) (strlen(command) + 1));
- strcpy(tcmdPtr->startCmd, command);
- tcmdPtr->refCount++;
- tcmdPtr->stepTrace = Tcl_CreateObjTrace(interp, 0,
- (tcmdPtr->flags & TCL_TRACE_ANY_EXEC) >> 2,
- TraceExecutionProc, (ClientData)tcmdPtr,
- CommandObjTraceDeleted);
+
+ if (ctxPtr->type == TCL_LOCATION_BC) {
+ /*
+ * Type BC => ctxPtr->data.eval.path is not used.
+ * ctxPtr->data.tebc.codePtr is used instead.
+ */
+
+ TclGetSrcInfoForPc(ctxPtr);
+ pc = 1;
+
+ /*
+ * The line information in the cmdFrame is now a copy we do not
+ * own.
+ */
}
- }
- if (flags & TCL_TRACE_DESTROYED) {
- if (tcmdPtr->stepTrace != NULL) {
- Tcl_DeleteTrace(interp, tcmdPtr->stepTrace);
- tcmdPtr->stepTrace = NULL;
- if (tcmdPtr->startCmd != NULL) {
- ckfree((char *)tcmdPtr->startCmd);
+
+ if (ctxPtr->type == TCL_LOCATION_SOURCE && ctxPtr->line[bidx] >= 0) {
+ int bline = ctxPtr->line[bidx];
+
+ ctxPtr->line = (int *) ckalloc(objc * sizeof(int));
+ ctxPtr->nline = objc;
+ TclListLines(blist, bline, objc, ctxPtr->line, objv);
+ } else {
+ /*
+ * This is either a dynamic code word, when all elements are
+ * relative to themselves, or something else less expected and
+ * where we have no information. The result is the same in both
+ * cases; tell the code to come that it doesn't know where it is,
+ * which triggers reversion to the old behavior.
+ */
+
+ int k;
+
+ ctxPtr->line = (int *) ckalloc(objc * sizeof(int));
+ ctxPtr->nline = objc;
+ for (k=0; k < objc; k++) {
+ ctxPtr->line[k] = -1;
}
}
}
- if (call) {
- tcmdPtr->refCount--;
- if (tcmdPtr->refCount < 0) {
- Tcl_Panic("TraceExecutionProc: negative TraceCommandInfo refCount");
+
+ for (j = i + 1; ; j += 2) {
+ if (j >= objc) {
+ /*
+ * This shouldn't happen since we've checked that the last body is
+ * not a continuation...
+ */
+
+ Tcl_Panic("fall-out when searching for body to match pattern");
}
- if (tcmdPtr->refCount == 0) {
- ckfree((char*)tcmdPtr);
+ if (strcmp(TclGetString(objv[j]), "-") != 0) {
+ break;
}
}
- return traceCode;
+
+ /*
+ * TIP #280: Make invoking context available to switch branch.
+ */
+
+ result = TclEvalObjEx(interp, objv[j], 0, ctxPtr, splitObjs ? j : bidx+j);
+ if (splitObjs) {
+ ckfree((char *) ctxPtr->line);
+ if (pc && (ctxPtr->type == TCL_LOCATION_SOURCE)) {
+ /*
+ * Death of SrcInfo reference.
+ */
+
+ Tcl_DecrRefCount(ctxPtr->data.eval.path);
+ }
+ }
+
+ /*
+ * Generate an error message if necessary.
+ */
+
+ if (result == TCL_ERROR) {
+ int limit = 50;
+ int overflow = (patternLength > limit);
+
+ Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+ "\n (\"%.*s%s\" arm line %d)",
+ (overflow ? limit : patternLength), pattern,
+ (overflow ? "..." : ""), interp->errorLine));
+ }
+ TclStackFree(interp, ctxPtr);
+ return result;
}
/*
*----------------------------------------------------------------------
*
- * TraceVarProc --
+ * Tcl_TimeObjCmd --
*
- * This procedure is called to handle variable accesses that have
- * been traced using the "trace" command.
+ * This object-based procedure is invoked to process the "time" Tcl
+ * command. See the user documentation for details on what it does.
*
* Results:
- * Normally returns NULL. If the trace command returns an error,
- * then this procedure returns an error string.
+ * A standard Tcl object result.
*
* Side effects:
- * Depends on the command associated with the trace.
+ * See the user documentation.
*
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
-static char *
-TraceVarProc(clientData, interp, name1, name2, flags)
- ClientData clientData; /* Information about the variable trace. */
- Tcl_Interp *interp; /* Interpreter containing variable. */
- CONST char *name1; /* Name of variable or array. */
- CONST char *name2; /* Name of element within array; NULL means
- * scalar variable is being referenced. */
- int flags; /* OR-ed bits giving operation and other
- * information. */
+int
+Tcl_TimeObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- Tcl_SavedResult state;
- TraceVarInfo *tvarPtr = (TraceVarInfo *) clientData;
- char *result;
- int code, destroy = 0;
- Tcl_DString cmd;
-
- /*
- * We might call Tcl_Eval() below, and that might evaluate [trace
- * vdelete] which might try to free tvarPtr. However we do not
- * need to protect anything here; it's done by our caller because
- * the TraceVarInfo is really part of a CompoundVarTrace. [Bug 1348775]
- */
+ register Tcl_Obj *objPtr;
+ Tcl_Obj *objs[4];
+ register int i, result;
+ int count;
+ double totalMicroSec;
+#ifndef TCL_WIDE_CLICKS
+ Tcl_Time start, stop;
+#else
+ Tcl_WideInt start, stop;
+#endif
- result = NULL;
- if ((tvarPtr->flags & flags) && !Tcl_InterpDeleted(interp)) {
- if (tvarPtr->length != (size_t) 0) {
- /*
- * Generate a command to execute by appending list elements
- * for the two variable names and the operation.
- */
+ if (objc == 2) {
+ count = 1;
+ } else if (objc == 3) {
+ result = TclGetIntFromObj(interp, objv[2], &count);
+ if (result != TCL_OK) {
+ return result;
+ }
+ } else {
+ Tcl_WrongNumArgs(interp, 1, objv, "command ?count?");
+ return TCL_ERROR;
+ }
- Tcl_DStringInit(&cmd);
- Tcl_DStringAppend(&cmd, tvarPtr->command, (int) tvarPtr->length);
- Tcl_DStringAppendElement(&cmd, name1);
- Tcl_DStringAppendElement(&cmd, (name2 ? name2 : ""));
-#ifndef TCL_REMOVE_OBSOLETE_TRACES
- if (tvarPtr->flags & TCL_TRACE_OLD_STYLE) {
- if (flags & TCL_TRACE_ARRAY) {
- Tcl_DStringAppend(&cmd, " a", 2);
- } else if (flags & TCL_TRACE_READS) {
- Tcl_DStringAppend(&cmd, " r", 2);
- } else if (flags & TCL_TRACE_WRITES) {
- Tcl_DStringAppend(&cmd, " w", 2);
- } else if (flags & TCL_TRACE_UNSETS) {
- Tcl_DStringAppend(&cmd, " u", 2);
- }
- } else {
+ objPtr = objv[1];
+ i = count;
+#ifndef TCL_WIDE_CLICKS
+ Tcl_GetTime(&start);
+#else
+ start = TclpGetWideClicks();
#endif
- if (flags & TCL_TRACE_ARRAY) {
- Tcl_DStringAppend(&cmd, " array", 6);
- } else if (flags & TCL_TRACE_READS) {
- Tcl_DStringAppend(&cmd, " read", 5);
- } else if (flags & TCL_TRACE_WRITES) {
- Tcl_DStringAppend(&cmd, " write", 6);
- } else if (flags & TCL_TRACE_UNSETS) {
- Tcl_DStringAppend(&cmd, " unset", 6);
- }
-#ifndef TCL_REMOVE_OBSOLETE_TRACES
- }
+ while (i-- > 0) {
+ result = Tcl_EvalObjEx(interp, objPtr, 0);
+ if (result != TCL_OK) {
+ return result;
+ }
+ }
+#ifndef TCL_WIDE_CLICKS
+ Tcl_GetTime(&stop);
+ totalMicroSec = ((double) (stop.sec - start.sec)) * 1.0e6
+ + (stop.usec - start.usec);
+#else
+ stop = TclpGetWideClicks();
+ totalMicroSec = ((double) TclpWideClicksToNanoseconds(stop - start))/1.0e3;
#endif
-
- /*
- * Execute the command. Save the interp's result used for
- * the command. We discard any object result the command returns.
- *
- * Add the TCL_TRACE_DESTROYED flag to tvarPtr to indicate to
- * other areas that this will be destroyed by us, otherwise a
- * double-free might occur depending on what the eval does.
- */
- Tcl_SaveResult(interp, &state);
- if ((flags & TCL_TRACE_DESTROYED)
- && !(tvarPtr->flags & TCL_TRACE_DESTROYED)) {
- destroy = 1;
- tvarPtr->flags |= TCL_TRACE_DESTROYED;
- }
+ if (count <= 1) {
+ /*
+ * Use int obj since we know time is not fractional. [Bug 1202178]
+ */
- code = Tcl_EvalEx(interp, Tcl_DStringValue(&cmd),
- Tcl_DStringLength(&cmd), 0);
- if (code != TCL_OK) { /* copy error msg to result */
- register Tcl_Obj *errMsgObj = Tcl_GetObjResult(interp);
- Tcl_IncrRefCount(errMsgObj);
- result = (char *) errMsgObj;
- }
+ objs[0] = Tcl_NewIntObj((count <= 0) ? 0 : (int) totalMicroSec);
+ } else {
+ objs[0] = Tcl_NewDoubleObj(totalMicroSec/count);
+ }
- Tcl_RestoreResult(interp, &state);
+ /*
+ * Construct the result as a list because many programs have always parsed
+ * as such (extracting the first element, typically).
+ */
- Tcl_DStringFree(&cmd);
- }
- }
- if (destroy) {
- if (result != NULL) {
- register Tcl_Obj *errMsgObj = (Tcl_Obj *) result;
+ TclNewLiteralStringObj(objs[1], "microseconds");
+ TclNewLiteralStringObj(objs[2], "per");
+ TclNewLiteralStringObj(objs[3], "iteration");
+ Tcl_SetObjResult(interp, Tcl_NewListObj(4, objs));
- Tcl_DecrRefCount(errMsgObj);
- result = NULL;
- }
- }
- return result;
+ return TCL_OK;
}
/*
@@ -4936,108 +3937,115 @@ TraceVarProc(clientData, interp, name1, name2, flags)
*
* Tcl_WhileObjCmd --
*
- * This procedure is invoked to process the "while" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "while" Tcl command. See the
+ * user documentation for details on what it does.
*
- * With the bytecode compiler, this procedure is only called when
- * a command name is computed at runtime, and is "while" or the name
- * to which "while" was renamed: e.g., "set z while; $z {$i<100} {}"
+ * With the bytecode compiler, this procedure is only called when a
+ * command name is computed at runtime, and is "while" or the name to
+ * which "while" was renamed: e.g., "set z while; $z {$i<100} {}"
*
* Results:
- * A standard Tcl result.
+ * A standard Tcl result.
*
* Side effects:
- * See the user documentation.
+ * See the user documentation.
*
*----------------------------------------------------------------------
*/
- /* ARGSUSED */
int
-Tcl_WhileObjCmd(dummy, interp, objc, objv)
- ClientData dummy; /* Not used. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
+Tcl_WhileObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[]) /* Argument objects. */
{
int result, value;
-#ifdef TCL_TIP280
- Interp* iPtr = (Interp*) interp;
-#endif
+ Interp *iPtr = (Interp *) interp;
if (objc != 3) {
Tcl_WrongNumArgs(interp, 1, objv, "test command");
- return TCL_ERROR;
+ return TCL_ERROR;
}
while (1) {
- result = Tcl_ExprBooleanObj(interp, objv[1], &value);
- if (result != TCL_OK) {
- return result;
- }
- if (!value) {
- break;
- }
-#ifndef TCL_TIP280
- result = Tcl_EvalObjEx(interp, objv[2], 0);
-#else
- /* TIP #280. */
- result = TclEvalObjEx(interp, objv[2], 0, iPtr->cmdFramePtr,2);
-#endif
- if ((result != TCL_OK) && (result != TCL_CONTINUE)) {
- if (result == TCL_ERROR) {
- char msg[32 + TCL_INTEGER_SPACE];
+ result = Tcl_ExprBooleanObj(interp, objv[1], &value);
+ if (result != TCL_OK) {
+ return result;
+ }
+ if (!value) {
+ break;
+ }
- sprintf(msg, "\n (\"while\" body line %d)",
- interp->errorLine);
- Tcl_AddErrorInfo(interp, msg);
- }
- break;
- }
+ /* TIP #280. */
+ result = TclEvalObjEx(interp, objv[2], 0, iPtr->cmdFramePtr, 2);
+ if ((result != TCL_OK) && (result != TCL_CONTINUE)) {
+ if (result == TCL_ERROR) {
+ Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+ "\n (\"while\" body line %d)", interp->errorLine));
+ }
+ break;
+ }
}
if (result == TCL_BREAK) {
- result = TCL_OK;
+ result = TCL_OK;
}
if (result == TCL_OK) {
- Tcl_ResetResult(interp);
+ Tcl_ResetResult(interp);
}
return result;
}
-#ifdef TCL_TIP280
-static void
-ListLines(listObj, line, n, lines, elems)
- Tcl_Obj* listObj; /* Pointer to obj holding a string with list structure.
- * Assumed to be valid. Assumed to contain n elements.
- */
- int line; /* line the list as a whole starts on */
- int n; /* #elements in lines */
- int* lines; /* Array of line numbers, to fill */
- Tcl_Obj* const* elems; /* The list elems as Tcl_Obj*, in need of derived
- * continuation data */
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclListLines --
+ *
+ * ???
+ *
+ * Results:
+ * Filled in array of line numbers?
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclListLines(
+ Tcl_Obj* listObj, /* Pointer to obj holding a string with list
+ * structure. Assumed to be valid. Assumed to
+ * contain n elements.
+ */
+ int line, /* Line the list as a whole starts on. */
+ int n, /* #elements in lines */
+ int *lines, /* Array of line numbers, to fill. */
+ Tcl_Obj* const* elems) /* The list elems as Tcl_Obj*, in need of
+ * derived continuation data */
{
- int i;
CONST char* listStr = Tcl_GetString (listObj);
CONST char* listHead = listStr;
- int length = strlen( listStr);
- CONST char* element = NULL;
- CONST char* next = NULL;
+ int i, length = strlen(listStr);
+ CONST char *element = NULL, *next = NULL;
ContLineLoc* clLocPtr = TclContinuationsGet(listObj);
- int* clNext = (clLocPtr ? &clLocPtr->loc[0] : NULL);
+ int* clNext = (clLocPtr ? &clLocPtr->loc[0] : NULL);
for (i = 0; i < n; i++) {
TclFindElement(NULL, listStr, length, &element, &next, NULL, NULL);
- TclAdvanceLines (&line, listStr, element); /* Leading whitespace */
+ TclAdvanceLines(&line, listStr, element);
+ /* Leading whitespace */
TclAdvanceContinuations (&line, &clNext, element - listHead);
- if (clNext) {
- TclContinuationsEnterDerived (elems[i], element - listHead, clNext);
+ if (elems && clNext) {
+ TclContinuationsEnterDerived (elems[i], element - listHead,
+ clNext);
}
-
- lines [i] = line;
- length -= (next - listStr);
- TclAdvanceLines (&line, element, next); /* Element */
- listStr = next;
+ lines[i] = line;
+ length -= (next - listStr);
+ TclAdvanceLines(&line, element, next);
+ /* Element */
+ listStr = next;
if (*element == 0) {
/* ASSERT i == n */
@@ -5045,7 +4053,6 @@ ListLines(listObj, line, n, lines, elems)
}
}
}
-#endif
/*
* Local Variables:
@@ -5054,4 +4061,3 @@ ListLines(listObj, line, n, lines, elems)
* fill-column: 78
* End:
*/
-
diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c
index a39370e..9eb74f5 100644
--- a/generic/tclCompCmds.c
+++ b/generic/tclCompCmds.c
@@ -1,54 +1,49 @@
-/*
+/*
* tclCompCmds.c --
*
- * This file contains compilation procedures that compile various
- * Tcl commands into a sequence of instructions ("bytecodes").
+ * This file contains compilation procedures that compile various Tcl
+ * commands 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-2006 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.
+ * 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"
/*
- * Prototypes for procedures defined later in this file:
+ * 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);
*/
-static ClientData DupForeachInfo _ANSI_ARGS_((ClientData clientData));
-static void FreeForeachInfo _ANSI_ARGS_((ClientData clientData));
-#ifndef TCL_TIP280
-static int TclPushVarName _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_Token *varTokenPtr, CompileEnv *envPtr, int flags,
- int *localIndexPtr, int *simpleVarNamePtr, int *isScalarPtr));
-
-#define TclPushVarNameWord(i,v,e,f,l,s,sc,word) \
- TclPushVarName (i,v,e,f,l,s,sc) /* ignoring word */
-
-#define DefineLineInformation /**/
-#define SetLineInformation(word) /**/
-#else
-static int TclPushVarName _ANSI_ARGS_((Tcl_Interp *interp,
- Tcl_Token *varTokenPtr, CompileEnv *envPtr, int flags,
- int *localIndexPtr, int *simpleVarNamePtr, int *isScalarPtr,
- int line, int* clNext));
-
-#define TclPushVarNameWord(i,v,e,f,l,s,sc,word) \
- TclPushVarName (i,v,e,f,l,s,sc, \
- mapPtr->loc [eclIndex].line [(word)], \
- mapPtr->loc [eclIndex].next [(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.
+/*
+ * 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.
*
- * Macros to encapsulate the variable definition and setup, and their use.
+ * Macro to encapsulate the variable definition and setup.
*/
+
#define DefineLineInformation \
ExtCmdLoc *mapPtr = envPtr->extCmdMapPtr; \
int eclIndex = mapPtr->nuloc - 1
@@ -56,23 +51,163 @@ static int TclPushVarName _ANSI_ARGS_((Tcl_Interp *interp,
#define SetLineInformation(word) \
envPtr->line = mapPtr->loc [eclIndex].line [(word)]; \
envPtr->clNext = mapPtr->loc [eclIndex].next [(word)]
-#endif
/*
- * Flags bits used by TclPushVarName.
+ * Convenience macro for use when compiling bodies of commands. The ANSI C
+ * "prototype" for this macro is:
+ *
+ * static void CompileBody(CompileEnv *envPtr, Tcl_Token *tokenPtr,
+ * Tcl_Interp *interp);
+ */
+
+#define CompileBody(envPtr, tokenPtr, interp) \
+ TclCompileCmdWord((interp), (tokenPtr)+1, (tokenPtr)->numComponents, \
+ (envPtr))
+
+/*
+ * Convenience macro for use when compiling tokens to be pushed. The ANSI C
+ * "prototype" for this macro is:
+ *
+ * static void CompileTokens(CompileEnv *envPtr, Tcl_Token *tokenPtr,
+ * Tcl_Interp *interp);
+ */
+
+#define CompileTokens(envPtr, tokenPtr, interp) \
+ TclCompileTokens((interp), (tokenPtr)+1, (tokenPtr)->numComponents, \
+ (envPtr));
+/*
+ * Convenience macro for use when pushing literals. The ANSI C "prototype" for
+ * this macro is:
+ *
+ * static void PushLiteral(CompileEnv *envPtr,
+ * const char *string, int length);
+ */
+
+#define PushLiteral(envPtr, string, length) \
+ TclEmitPush(TclRegisterNewLiteral((envPtr), (string), (length)), (envPtr))
+
+/*
+ * Macro to advance to the next token; it is more mnemonic than the address
+ * arithmetic that it replaces. The ANSI C "prototype" for this macro is:
+ *
+ * static Tcl_Token * TokenAfter(Tcl_Token *tokenPtr);
+ */
+
+#define TokenAfter(tokenPtr) \
+ ((tokenPtr) + ((tokenPtr)->numComponents + 1))
+
+/*
+ * Macro to get the offset to the next instruction to be issued. The ANSI C
+ * "prototype" for this macro is:
+ *
+ * static int CurrentOffset(CompileEnv *envPtr);
+ */
+
+#define CurrentOffset(envPtr) \
+ ((envPtr)->codeNext - (envPtr)->codeStart)
+
+/*
+ * Note: the exceptDepth is a bit of a misnomer: TEBC only needs the
+ * maximal depth of nested CATCH ranges in order to alloc runtime
+ * memory. These macros should compute precisely that? OTOH, the nesting depth
+ * 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 = \
+ TclMax((envPtr)->exceptDepth, (envPtr)->maxExceptDepth)), \
+ ((envPtr)->exceptArrayPtr[(index)].codeOffset = CurrentOffset(envPtr)))
+#define ExceptionRangeEnds(envPtr, index) \
+ (((envPtr)->exceptDepth--), \
+ ((envPtr)->exceptArrayPtr[(index)].numCodeBytes = \
+ CurrentOffset(envPtr) - (envPtr)->exceptArrayPtr[(index)].codeOffset))
+#define ExceptionRangeTarget(envPtr, index, targetType) \
+ ((envPtr)->exceptArrayPtr[(index)].targetType = CurrentOffset(envPtr))
+
+/*
+ * Prototypes for procedures defined later in this file:
*/
-#define TCL_CREATE_VAR 1 /* Create a compiled local if none is found */
-#define TCL_NO_LARGE_INDEX 2 /* Do not return localIndex value > 255 */
+static ClientData DupDictUpdateInfo(ClientData clientData);
+static void FreeDictUpdateInfo(ClientData clientData);
+static void PrintDictUpdateInfo(ClientData clientData,
+ Tcl_Obj *appendObj, ByteCode *codePtr,
+ unsigned int pcOffset);
+static ClientData DupForeachInfo(ClientData clientData);
+static void FreeForeachInfo(ClientData clientData);
+static void PrintForeachInfo(ClientData clientData,
+ Tcl_Obj *appendObj, ByteCode *codePtr,
+ unsigned int pcOffset);
+static ClientData DupJumptableInfo(ClientData clientData);
+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);
+static int CompileComparisonOpCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, int instruction,
+ CompileEnv *envPtr);
+static int CompileStrictlyBinaryOpCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, int instruction,
+ CompileEnv *envPtr);
+static int CompileUnaryOpCmd(Tcl_Interp *interp,
+ Tcl_Parse *parsePtr, int instruction,
+ CompileEnv *envPtr);
+static void CompileReturnInternal(CompileEnv *envPtr,
+ unsigned char op, int code, int level,
+ Tcl_Obj *returnOpts);
+
+#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_CREATE_VAR 1 /* Create a compiled local if none is found */
+#define TCL_NO_LARGE_INDEX 2 /* Do not return localIndex value > 255 */
/*
* The structures below define the AuxData types defined in this file.
*/
AuxDataType tclForeachInfoType = {
- "ForeachInfo", /* name */
- DupForeachInfo, /* dupProc */
- FreeForeachInfo /* freeProc */
+ "ForeachInfo", /* name */
+ DupForeachInfo, /* dupProc */
+ FreeForeachInfo, /* freeProc */
+ PrintForeachInfo /* printProc */
+};
+
+AuxDataType tclJumptableInfoType = {
+ "JumptableInfo", /* name */
+ DupJumptableInfo, /* dupProc */
+ FreeJumptableInfo, /* freeProc */
+ PrintJumptableInfo /* printProc */
+};
+
+AuxDataType tclDictUpdateInfoType = {
+ "DictUpdateInfo", /* name */
+ DupDictUpdateInfo, /* dupProc */
+ FreeDictUpdateInfo, /* freeProc */
+ PrintDictUpdateInfo /* printProc */
};
/*
@@ -83,89 +218,68 @@ AuxDataType tclForeachInfoType = {
* Procedure called to compile the "append" command.
*
* Results:
- * The return value is a standard Tcl result, which is normally TCL_OK
- * unless there was an error while parsing string. If an error occurs
- * then the interpreter's result contains a standard error message. If
- * compilation fails because the command requires a second level of
- * substitutions, TCL_OUT_LINE_COMPILE is returned indicating that the
- * command should be compiled "out of line" by emitting code to
- * invoke its command procedure (Tcl_AppendObjCmd) at runtime.
+ * 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 "append" command
- * at runtime.
+ * Instructions are added to envPtr to execute the "append" command at
+ * runtime.
*
*----------------------------------------------------------------------
*/
int
-TclCompileAppendCmd(interp, parsePtr, envPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tcl_Parse *parsePtr; /* Points to a parse structure for the
- * command created by Tcl_ParseCommand. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
+TclCompileAppendCmd(
+ 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 simpleVarName, isScalar, localIndex, numWords;
- int code = TCL_OK;
-
- DefineLineInformation;
+ DefineLineInformation; /* TIP #280 */
numWords = parsePtr->numWords;
if (numWords == 1) {
- Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "wrong # args: should be \"append varName ?value value ...?\"",
- -1);
return TCL_ERROR;
} else if (numWords == 2) {
/*
- * append varName === set varName
+ * append varName == set varName
*/
- return TclCompileSetCmd(interp, parsePtr, envPtr);
+
+ return TclCompileSetCmd(interp, parsePtr, cmdPtr, envPtr);
} else if (numWords > 3) {
/*
- * APPEND instructions currently only handle one value
+ * APPEND instructions currently only handle one value.
*/
- return TCL_OUT_LINE_COMPILE;
+
+ 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.
+ * 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 = parsePtr->tokenPtr
- + (parsePtr->tokenPtr->numComponents + 1);
+ varTokenPtr = TokenAfter(parsePtr->tokenPtr);
- code = TclPushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR,
- &localIndex, &simpleVarName, &isScalar, 1);
- if (code != TCL_OK) {
- goto done;
- }
+ PushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR,
+ &localIndex, &simpleVarName, &isScalar, 1);
/*
- * We are doing an assignment, otherwise TclCompileSetCmd was called,
- * so push the new value. This will need to be extended to push a
- * value for each argument.
+ * We are doing an assignment, otherwise TclCompileSetCmd was called, so
+ * push the new value. This will need to be extended to push a value for
+ * each argument.
*/
if (numWords > 2) {
- valueTokenPtr = varTokenPtr + (varTokenPtr->numComponents + 1);
- if (valueTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
- TclEmitPush(TclRegisterNewLiteral(envPtr,
- valueTokenPtr[1].start, valueTokenPtr[1].size), envPtr);
- } else {
- SetLineInformation (2);
- code = TclCompileTokens(interp, valueTokenPtr+1,
- valueTokenPtr->numComponents, envPtr);
- if (code != TCL_OK) {
- goto done;
- }
- }
+ valueTokenPtr = TokenAfter(varTokenPtr);
+ CompileWord(envPtr, valueTokenPtr, interp, 2);
}
/*
@@ -174,32 +288,27 @@ TclCompileAppendCmd(interp, parsePtr, envPtr)
if (simpleVarName) {
if (isScalar) {
- if (localIndex >= 0) {
- if (localIndex <= 255) {
- TclEmitInstInt1(INST_APPEND_SCALAR1, localIndex, envPtr);
- } else {
- TclEmitInstInt4(INST_APPEND_SCALAR4, localIndex, envPtr);
- }
- } else {
+ 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);
}
} else {
- if (localIndex >= 0) {
- if (localIndex <= 255) {
- TclEmitInstInt1(INST_APPEND_ARRAY1, localIndex, envPtr);
- } else {
- TclEmitInstInt4(INST_APPEND_ARRAY4, 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);
}
}
} else {
TclEmitOpcode(INST_APPEND_STK, envPtr);
}
- done:
- return code;
+ return TCL_OK;
}
/*
@@ -210,28 +319,26 @@ TclCompileAppendCmd(interp, parsePtr, envPtr)
* Procedure called to compile the "break" command.
*
* Results:
- * The return value is a standard Tcl result, which is TCL_OK unless
- * there was an error during compilation. If an error occurs then
- * the interpreter's result contains a standard error message.
+ * 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 "break" command
- * at runtime.
+ * Instructions are added to envPtr to execute the "break" command at
+ * runtime.
*
*----------------------------------------------------------------------
*/
int
-TclCompileBreakCmd(interp, parsePtr, envPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tcl_Parse *parsePtr; /* Points to a parse structure for the
- * command created by Tcl_ParseCommand. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
+TclCompileBreakCmd(
+ 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. */
{
if (parsePtr->numWords != 1) {
- Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "wrong # args: should be \"break\"", -1);
return TCL_ERROR;
}
@@ -251,172 +358,239 @@ TclCompileBreakCmd(interp, parsePtr, envPtr)
* Procedure called to compile the "catch" command.
*
* Results:
- * The return value is a standard Tcl result, which is TCL_OK if
- * compilation was successful. If an error occurs then the
- * interpreter's result contains a standard error message and TCL_ERROR
- * is returned. If the command is too complex for TclCompileCatchCmd,
- * TCL_OUT_LINE_COMPILE is returned indicating that the catch command
- * should be compiled "out of line" by emitting code to invoke its
- * command procedure at runtime.
+ * 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 "catch" command
- * at runtime.
+ * Instructions are added to envPtr to execute the "catch" command at
+ * runtime.
*
*----------------------------------------------------------------------
*/
int
-TclCompileCatchCmd(interp, parsePtr, envPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tcl_Parse *parsePtr; /* Points to a parse structure for the
- * command created by Tcl_ParseCommand. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
+TclCompileCatchCmd(
+ 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. */
{
JumpFixup jumpFixup;
- Tcl_Token *cmdTokenPtr, *nameTokenPtr;
- CONST char *name;
- int localIndex, nameChars, range, startOffset, jumpDist;
- int code;
- int savedStackDepth = envPtr->currStackDepth;
+ Tcl_Token *cmdTokenPtr, *resultNameTokenPtr, *optsNameTokenPtr;
+ const char *name;
+ int resultIndex, optsIndex, nameChars, range;
+ int initStackDepth = envPtr->currStackDepth;
+ int savedStackDepth;
+ DefineLineInformation; /* TIP #280 */
- DefineLineInformation;
+ /*
+ * If syntax does not match what we expect for [catch], do not compile.
+ * Let runtime checks determine if syntax has changed.
+ */
- if ((parsePtr->numWords != 2) && (parsePtr->numWords != 3)) {
- Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "wrong # args: should be \"catch command ?varName?\"", -1);
+ if ((parsePtr->numWords < 2) || (parsePtr->numWords > 4)) {
return TCL_ERROR;
}
/*
- * If a variable was specified and the catch command is at global level
- * (not in a procedure), don't compile it inline: the payoff is
- * too small.
+ * If variables were specified and the catch command is at global level
+ * (not in a procedure), don't compile it inline: the payoff is too small.
*/
- if ((parsePtr->numWords == 3) && (envPtr->procPtr == NULL)) {
- return TCL_OUT_LINE_COMPILE;
+ if ((parsePtr->numWords >= 3) && (envPtr->procPtr == NULL)) {
+ return TCL_ERROR;
}
/*
- * Make sure the variable name, if any, has no substitutions and just
- * refers to a local scaler.
+ * Make sure the variable names, if any, have no substitutions and just
+ * refer to local scalars.
*/
- localIndex = -1;
- cmdTokenPtr = parsePtr->tokenPtr
- + (parsePtr->tokenPtr->numComponents + 1);
- if (parsePtr->numWords == 3) {
- nameTokenPtr = cmdTokenPtr + (cmdTokenPtr->numComponents + 1);
- if (nameTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
- name = nameTokenPtr[1].start;
- nameChars = nameTokenPtr[1].size;
+ resultIndex = optsIndex = -1;
+ cmdTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ 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->procPtr);
+ if (resultIndex < 0) {
+ return TCL_ERROR;
+ }
+
+ /* 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_OUT_LINE_COMPILE;
+ return TCL_ERROR;
+ }
+ optsIndex = TclFindCompiledLocal(optsNameTokenPtr[1].start,
+ optsNameTokenPtr[1].size, /*create*/ 1, envPtr->procPtr);
+ if (optsIndex < 0) {
+ return TCL_ERROR;
}
- localIndex = TclFindCompiledLocal(nameTokenPtr[1].start,
- nameTokenPtr[1].size, /*create*/ 1,
- /*flags*/ VAR_SCALAR, envPtr->procPtr);
- } else {
- return TCL_OUT_LINE_COMPILE;
}
}
/*
- * We will compile the catch command. Emit a beginCatch instruction at
- * the start of the catch body: the subcommand it controls.
+ * We will compile the catch command. Declare the exception range
+ * that it uses.
*/
-
- envPtr->exceptDepth++;
- envPtr->maxExceptDepth =
- TclMax(envPtr->exceptDepth, envPtr->maxExceptDepth);
- range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
- TclEmitInstInt4(INST_BEGIN_CATCH4, range, envPtr);
+
+ range = DeclareExceptionRange(envPtr, CATCH_EXCEPTION_RANGE);
/*
- * If the body is a simple word, compile the instructions to
- * eval it. Otherwise, compile instructions to substitute its
- * text without catching, a catch instruction that resets the
- * stack to what it was before substituting the body, and then
- * an instruction to eval the body. Care has to be taken to
- * register the correct startOffset for the catch range so that
- * errors in the substitution are not catched [Bug 219184]
+ * 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.
+ * [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);
+ SetLineInformation(1);
if (cmdTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
- startOffset = (envPtr->codeNext - envPtr->codeStart);
- code = TclCompileCmdWord(interp, cmdTokenPtr+1, 1, envPtr);
+ savedStackDepth = envPtr->currStackDepth;
+ TclEmitInstInt4(INST_BEGIN_CATCH4, range, envPtr);
+ ExceptionRangeStarts(envPtr, range);
+ CompileBody(envPtr, cmdTokenPtr, interp);
} else {
- code = TclCompileTokens(interp, cmdTokenPtr+1,
- cmdTokenPtr->numComponents, envPtr);
- startOffset = (envPtr->codeNext - envPtr->codeStart);
+ CompileTokens(envPtr, cmdTokenPtr, interp);
+ savedStackDepth = envPtr->currStackDepth;
+ TclEmitInstInt4(INST_BEGIN_CATCH4, range, envPtr);
+ ExceptionRangeStarts(envPtr, range);
+ TclEmitOpcode(INST_DUP, envPtr);
TclEmitOpcode(INST_EVAL_STK, envPtr);
}
- envPtr->exceptArrayPtr[range].codeOffset = startOffset;
+ /* Stack at this point:
+ * nonsimple: script <mark> result
+ * simple: <mark> result
+ */
- if (code != TCL_OK) {
- code = TCL_OUT_LINE_COMPILE;
- goto done;
- }
- envPtr->exceptArrayPtr[range].numCodeBytes =
- (envPtr->codeNext - envPtr->codeStart) - startOffset;
-
/*
- * The "no errors" epilogue code: store the body's result into the
- * variable (if any), push "0" (TCL_OK) as the catch's "no error"
+ * Emit the "no errors" epilogue: push "0" (TCL_OK) as the catch
* result, and jump around the "error case" code.
*/
- if (localIndex != -1) {
- if (localIndex <= 255) {
- TclEmitInstInt1(INST_STORE_SCALAR1, localIndex, envPtr);
+ PushLiteral(envPtr, "0", 1);
+ 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.
+ */
+
+ envPtr->currStackDepth = savedStackDepth;
+ ExceptionRangeTarget(envPtr, range, catchOffset);
+ /* Stack at this point: ?script? */
+ TclEmitOpcode(INST_PUSH_RESULT, envPtr);
+ TclEmitOpcode(INST_PUSH_RETURN_CODE, envPtr);
+
+ /*
+ * Update the target of the jump after the "no errors" code.
+ */
+
+ /* Stack at this point: ?script? 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 */
+
+ if (optsIndex != -1) {
+ TclEmitOpcode(INST_PUSH_RETURN_OPTIONS, envPtr);
+ }
+
+ /*
+ * End the catch
+ */
+
+ ExceptionRangeEnds(envPtr, range);
+ 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.
+ */
+
+ if (optsIndex != -1) {
+ TclEmitInstInt4(INST_REVERSE, 3, envPtr);
+ } else {
+ TclEmitInstInt4(INST_REVERSE, 2, envPtr);
+ }
+
+ /*
+ * Store the result if requested, and remove it from the stack
+ */
+
+ if (resultIndex != -1) {
+ if (resultIndex <= 255) {
+ TclEmitInstInt1(INST_STORE_SCALAR1, resultIndex, envPtr);
} else {
- TclEmitInstInt4(INST_STORE_SCALAR4, localIndex, envPtr);
+ TclEmitInstInt4(INST_STORE_SCALAR4, resultIndex, envPtr);
}
}
TclEmitOpcode(INST_POP, envPtr);
- TclEmitPush(TclRegisterNewLiteral(envPtr, "0", 1), envPtr);
- TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup);
/*
- * The "error case" code: store the body's result into the variable (if
- * any), then push the error result code. The initial PC offset here is
- * the catch's error target.
+ * 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.
*/
- envPtr->currStackDepth = savedStackDepth;
- envPtr->exceptArrayPtr[range].catchOffset =
- (envPtr->codeNext - envPtr->codeStart);
- if (localIndex != -1) {
- TclEmitOpcode(INST_PUSH_RESULT, envPtr);
- if (localIndex <= 255) {
- TclEmitInstInt1(INST_STORE_SCALAR1, localIndex, envPtr);
+ if (optsIndex != -1) {
+ TclEmitInstInt4(INST_REVERSE, 2, envPtr);
+ if (optsIndex <= 255) {
+ TclEmitInstInt1(INST_STORE_SCALAR1, optsIndex, envPtr);
} else {
- TclEmitInstInt4(INST_STORE_SCALAR4, localIndex, envPtr);
+ TclEmitInstInt4(INST_STORE_SCALAR4, optsIndex, envPtr);
}
TclEmitOpcode(INST_POP, envPtr);
}
- TclEmitOpcode(INST_PUSH_RETURN_CODE, envPtr);
-
/*
- * Update the target of the jump after the "no errors" code, then emit
- * an endCatch instruction at the end of the catch command.
+ * Stack is now ?script? result. Get rid of the subst'ed script
+ * if it's hanging arond.
*/
- jumpDist = (envPtr->codeNext - envPtr->codeStart)
- - jumpFixup.codeOffset;
- if (TclFixupForwardJump(envPtr, &jumpFixup, jumpDist, 127)) {
- panic("TclCompileCatchCmd: bad jump distance %d\n", jumpDist);
+ if (cmdTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+ TclEmitInstInt4(INST_REVERSE, 2, envPtr);
+ TclEmitOpcode(INST_POP, envPtr);
}
- TclEmitOpcode(INST_END_CATCH, envPtr);
- done:
- envPtr->currStackDepth = savedStackDepth + 1;
- envPtr->exceptDepth--;
- return code;
+ /*
+ * Result of all this, on either branch, should have been to leave
+ * one operand -- the return code -- on the stack.
+ */
+
+ if (envPtr->currStackDepth != initStackDepth + 1) {
+ Tcl_Panic("in TclCompileCatchCmd, currStackDepth = %d should be %d",
+ envPtr->currStackDepth, initStackDepth+1);
+ }
+ return TCL_OK;
}
/*
@@ -427,32 +601,30 @@ TclCompileCatchCmd(interp, parsePtr, envPtr)
* Procedure called to compile the "continue" command.
*
* Results:
- * The return value is a standard Tcl result, which is TCL_OK unless
- * there was an error while parsing string. If an error occurs then
- * the interpreter's result contains a standard error message.
+ * 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 "continue" command
- * at runtime.
+ * Instructions are added to envPtr to execute the "continue" command at
+ * runtime.
*
*----------------------------------------------------------------------
*/
int
-TclCompileContinueCmd(interp, parsePtr, envPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tcl_Parse *parsePtr; /* Points to a parse structure for the
- * command created by Tcl_ParseCommand. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
+TclCompileContinueCmd(
+ 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. */
{
/*
* There should be no argument after the "continue".
*/
if (parsePtr->numWords != 1) {
- Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "wrong # args: should be \"continue\"", -1);
return TCL_ERROR;
}
@@ -467,45 +639,789 @@ TclCompileContinueCmd(interp, parsePtr, envPtr)
/*
*----------------------------------------------------------------------
*
+ * TclCompileDict*Cmd --
+ *
+ * Functions called to compile "dict" 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 "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!)
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileDictSetCmd(
+ 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 numWords, i;
+ Proc *procPtr = envPtr->procPtr;
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *varTokenPtr;
+ int dictVarIndex, nameChars;
+ const char *name;
+
+ /*
+ * There must be at least one argument after the command.
+ */
+
+ if (parsePtr->numWords < 4 || procPtr == NULL) {
+ 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.
+ */
+
+ 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, procPtr);
+
+ /*
+ * Remaining words (key path and value to set) can be handled normally.
+ */
+
+ tokenPtr = TokenAfter(varTokenPtr);
+ numWords = parsePtr->numWords-1;
+ for (i=1 ; i<numWords ; i++) {
+ CompileWord(envPtr, tokenPtr, interp, i);
+ tokenPtr = TokenAfter(tokenPtr);
+ }
+
+ /*
+ * Now emit the instruction to do the dict manipulation.
+ */
+
+ TclEmitInstInt4( INST_DICT_SET, numWords-2, envPtr);
+ TclEmitInt4( dictVarIndex, envPtr);
+ return TCL_OK;
+}
+
+int
+TclCompileDictIncrCmd(
+ 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. */
+{
+ Proc *procPtr = envPtr->procPtr;
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *varTokenPtr, *keyTokenPtr;
+ int dictVarIndex, nameChars, incrAmount;
+ const char *name;
+
+ /*
+ * There must be at least two arguments after the command.
+ */
+
+ if (parsePtr->numWords < 3 || parsePtr->numWords > 4 || procPtr == NULL) {
+ return TCL_ERROR;
+ }
+ varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ keyTokenPtr = TokenAfter(varTokenPtr);
+
+ /*
+ * Parse the increment amount, if present.
+ */
+
+ if (parsePtr->numWords == 4) {
+ const char *word;
+ int numBytes, code;
+ Tcl_Token *incrTokenPtr;
+ Tcl_Obj *intObj;
+
+ incrTokenPtr = TokenAfter(keyTokenPtr);
+ if (incrTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+ return TCL_ERROR;
+ }
+ word = incrTokenPtr[1].start;
+ numBytes = incrTokenPtr[1].size;
+
+ intObj = Tcl_NewStringObj(word, numBytes);
+ Tcl_IncrRefCount(intObj);
+ code = TclGetIntFromObj(NULL, intObj, &incrAmount);
+ TclDecrRefCount(intObj);
+ if (code != TCL_OK) {
+ return TCL_ERROR;
+ }
+ } else {
+ incrAmount = 1;
+ }
+
+ /*
+ * 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.
+ */
+
+ 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, procPtr);
+
+ /*
+ * Emit the key and the code to actually do the increment.
+ */
+
+ CompileWord(envPtr, keyTokenPtr, interp, 3);
+ TclEmitInstInt4( INST_DICT_INCR_IMM, incrAmount, envPtr);
+ TclEmitInt4( dictVarIndex, envPtr);
+ return TCL_OK;
+}
+
+int
+TclCompileDictGetCmd(
+ 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 numWords, 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).
+ */
+
+ 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++) {
+ CompileWord(envPtr, tokenPtr, interp, i);
+ tokenPtr = TokenAfter(tokenPtr);
+ }
+ TclEmitInstInt4(INST_DICT_GET, numWords-1, envPtr);
+ return TCL_OK;
+}
+
+int
+TclCompileDictForCmd(
+ 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. */
+{
+ Proc *procPtr = envPtr->procPtr;
+ 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. */
+ const char **argv;
+ Tcl_DString buffer;
+
+ /*
+ * There must be at least three argument after the command.
+ */
+
+ if (parsePtr->numWords != 4 || procPtr == NULL) {
+ return TCL_ERROR;
+ }
+
+ varsTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ dictTokenPtr = TokenAfter(varsTokenPtr);
+ bodyTokenPtr = TokenAfter(dictTokenPtr);
+ if (varsTokenPtr->type != TCL_TOKEN_SIMPLE_WORD ||
+ bodyTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Check we've got a pair of variables and that they are local variables.
+ * Then extract their indices in the LVT.
+ */
+
+ Tcl_DStringInit(&buffer);
+ Tcl_DStringAppend(&buffer, varsTokenPtr[1].start, varsTokenPtr[1].size);
+ if (Tcl_SplitList(NULL, Tcl_DStringValue(&buffer), &numVars,
+ &argv) != TCL_OK) {
+ Tcl_DStringFree(&buffer);
+ return TCL_ERROR;
+ }
+ Tcl_DStringFree(&buffer);
+ if (numVars != 2) {
+ ckfree((char *) argv);
+ return TCL_ERROR;
+ }
+
+ nameChars = strlen(argv[0]);
+ if (!TclIsLocalScalar(argv[0], nameChars)) {
+ ckfree((char *) argv);
+ return TCL_ERROR;
+ }
+ keyVarIndex = TclFindCompiledLocal(argv[0], nameChars, 1, procPtr);
+
+ nameChars = strlen(argv[1]);
+ if (!TclIsLocalScalar(argv[1], nameChars)) {
+ ckfree((char *) argv);
+ return TCL_ERROR;
+ }
+ valueVarIndex = TclFindCompiledLocal(argv[1], nameChars, 1, procPtr);
+ ckfree((char *) argv);
+
+ /*
+ * Allocate a temporary variable to store the iterator reference. The
+ * variable will contain a Tcl_DictSearch reference which will be
+ * allocated by INST_DICT_FIRST and disposed when the variable is unset
+ * (at which point it should also have been finished with).
+ */
+
+ infoIndex = TclFindCompiledLocal(NULL, 0, 1, procPtr);
+
+ /*
+ * 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.
+ */
+
+ CompileWord(envPtr, dictTokenPtr, interp, 3);
+ TclEmitInstInt4( INST_DICT_FIRST, infoIndex, envPtr);
+ emptyTargetOffset = CurrentOffset(envPtr);
+ TclEmitInstInt4( INST_JUMP_TRUE4, 0, envPtr);
+
+ /*
+ * 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);
+ ExceptionRangeStarts(envPtr, catchRange);
+
+ /*
+ * 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);
+
+ /*
+ * Set up the loop exception targets.
+ */
+
+ loopRange = DeclareExceptionRange(envPtr, LOOP_EXCEPTION_RANGE);
+ ExceptionRangeStarts(envPtr, loopRange);
+
+ /*
+ * Compile the loop body itself. It should be stack-neutral.
+ */
+
+ SetLineInformation(3);
+ CompileBody(envPtr, bodyTokenPtr, interp);
+ TclEmitOpcode( INST_POP, envPtr);
+
+ /*
+ * Both exception target ranges (error and loop) end here.
+ */
+
+ ExceptionRangeEnds(envPtr, loopRange);
+ ExceptionRangeEnds(envPtr, catchRange);
+
+ /*
+ * Continue (or just normally process) by getting the next pair of items
+ * from the dictionary and jumping back to the code to write them into
+ * variables if there is another pair.
+ */
+
+ ExceptionRangeTarget(envPtr, loopRange, continueOffset);
+ 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);
+ TclEmitInstInt4( INST_DICT_DONE, infoIndex, envPtr);
+ TclEmitOpcode( INST_END_CATCH, envPtr);
+ endTargetOffset = CurrentOffset(envPtr);
+ TclEmitInstInt4( INST_JUMP4, 0, envPtr);
+
+ /*
+ * Error handler "finally" clause, which force-terminates the iteration
+ * and rethrows the error.
+ */
+
+ ExceptionRangeTarget(envPtr, catchRange, catchOffset);
+ TclEmitOpcode( INST_PUSH_RETURN_OPTIONS, envPtr);
+ TclEmitOpcode( INST_PUSH_RESULT, envPtr);
+ TclEmitInstInt4( INST_DICT_DONE, infoIndex, envPtr);
+ TclEmitOpcode( INST_END_CATCH, envPtr);
+ TclEmitOpcode( INST_RETURN_STK, envPtr);
+
+ /*
+ * Otherwise we're done (the jump after the DICT_FIRST points here) and we
+ * need to pop the bogus key/value pair (pushed to keep stack calculations
+ * 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);
+ TclEmitInstInt4( INST_DICT_DONE, infoIndex, 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.
+ */
+
+ jumpDisplacement = CurrentOffset(envPtr) - endTargetOffset;
+ TclUpdateInstInt4AtPc(INST_JUMP4, jumpDisplacement,
+ envPtr->codeStart + endTargetOffset);
+ PushLiteral(envPtr, "", 0);
+ return TCL_OK;
+}
+
+int
+TclCompileDictUpdateCmd(
+ 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. */
+{
+ Proc *procPtr = envPtr->procPtr;
+ DefineLineInformation; /* TIP #280 */
+ const char *name;
+ int i, nameChars, dictIndex, numVars, range, infoIndex;
+ Tcl_Token **keyTokenPtrs, *dictVarTokenPtr, *bodyTokenPtr, *tokenPtr;
+ DictUpdateInfo *duiPtr;
+ JumpFixup jumpFixup;
+
+ /*
+ * There must be at least one argument after the command.
+ */
+
+ if (parsePtr->numWords < 5 || procPtr == NULL) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Parse the command. Expect the following:
+ * dict update <lit(eral)> <any> <lit> ?<any> <lit> ...? <lit>
+ */
+
+ if ((parsePtr->numWords - 1) & 1) {
+ return TCL_ERROR;
+ }
+ numVars = (parsePtr->numWords - 3) / 2;
+
+ /*
+ * 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.
+ */
+
+ 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, procPtr);
+
+ /*
+ * Assemble the instruction metadata. This is complex enough that it is
+ * represented as auxData; it holds an ordered list of variable indices
+ * that are to be used.
+ */
+
+ duiPtr = (DictUpdateInfo *)
+ ckalloc(sizeof(DictUpdateInfo) + sizeof(int) * (numVars - 1));
+ duiPtr->length = numVars;
+ keyTokenPtrs = (Tcl_Token **) TclStackAlloc(interp,
+ sizeof(Tcl_Token *) * numVars);
+ tokenPtr = TokenAfter(dictVarTokenPtr);
+
+ for (i=0 ; i<numVars ; i++) {
+ /*
+ * Put keys to one side for later compilation to bytecode.
+ */
+
+ keyTokenPtrs[i] = tokenPtr;
+
+ /*
+ * Variables first need to be checked for sanity.
+ */
+
+ tokenPtr = TokenAfter(tokenPtr);
+ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+ ckfree((char *) duiPtr);
+ TclStackFree(interp, keyTokenPtrs);
+ return TCL_ERROR;
+ }
+ name = tokenPtr[1].start;
+ nameChars = tokenPtr[1].size;
+ if (!TclIsLocalScalar(name, nameChars)) {
+ ckfree((char *) duiPtr);
+ TclStackFree(interp, keyTokenPtrs);
+ return TCL_ERROR;
+ }
+
+ /*
+ * Stash the index in the auxiliary data.
+ */
+
+ duiPtr->varIndices[i] =
+ TclFindCompiledLocal(name, nameChars, 1, procPtr);
+ tokenPtr = TokenAfter(tokenPtr);
+ }
+ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+ ckfree((char *) duiPtr);
+ TclStackFree(interp, keyTokenPtrs);
+ return TCL_ERROR;
+ }
+ bodyTokenPtr = tokenPtr;
+
+ /*
+ * The list of variables to bind is stored in auxiliary data so that it
+ * can't be snagged by literal sharing and forced to shimmer dangerously.
+ */
+
+ infoIndex = TclCreateAuxData(duiPtr, &tclDictUpdateInfoType, envPtr);
+
+ for (i=0 ; i<numVars ; i++) {
+ CompileWord(envPtr, keyTokenPtrs[i], interp, i);
+ }
+ 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);
+
+ ExceptionRangeStarts(envPtr, range);
+ SetLineInformation(parsePtr->numWords - 1);
+ CompileBody(envPtr, bodyTokenPtr, interp);
+ ExceptionRangeEnds(envPtr, range);
+
+ /*
+ * Normal termination code: the stack has the key list below the result of
+ * 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);
+
+ /*
+ * Jump around the exceptional termination code.
+ */
+
+ TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup);
+
+ /*
+ * Termination code for non-ok returns: stash the result and return
+ * options in the stack, bring up the key list, finish the update code,
+ * and finally return with the catched return data
+ */
+
+ 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);
+
+ TclEmitInstInt4( INST_DICT_UPDATE_END, dictIndex, envPtr);
+ TclEmitInt4( infoIndex, envPtr);
+ TclEmitOpcode( INST_RETURN_STK, envPtr);
+
+ if (TclFixupForwardJumpToHere(envPtr, &jumpFixup, 127)) {
+ Tcl_Panic("TclCompileDictCmd(update): bad jump distance %d",
+ (int) (CurrentOffset(envPtr) - jumpFixup.codeOffset));
+ }
+ TclStackFree(interp, keyTokenPtrs);
+ return TCL_OK;
+}
+
+int
+TclCompileDictAppendCmd(
+ 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. */
+{
+ Proc *procPtr = envPtr->procPtr;
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *tokenPtr;
+ int i, dictVarIndex;
+
+ /*
+ * There must be at least two argument after the command. And we impose an
+ * (arbirary) safe limit; anyone exceeding it should stop worrying about
+ * speed quite so much. ;-)
+ */
+
+ if (parsePtr->numWords<4 || parsePtr->numWords>100 || procPtr==NULL) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Get the index of the local variable that we will be working with.
+ */
+
+ 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, procPtr);
+ }
+
+ /*
+ * Produce the string to concatenate onto the dictionary entry.
+ */
+
+ tokenPtr = TokenAfter(tokenPtr);
+ for (i=2 ; i<parsePtr->numWords ; i++) {
+ CompileWord(envPtr, tokenPtr, interp, i);
+ tokenPtr = TokenAfter(tokenPtr);
+ }
+ if (parsePtr->numWords > 4) {
+ TclEmitInstInt1(INST_CONCAT1, parsePtr->numWords-3, envPtr);
+ }
+
+ /*
+ * Do the concatenation.
+ */
+
+ TclEmitInstInt4(INST_DICT_APPEND, dictVarIndex, envPtr);
+ return TCL_OK;
+}
+
+int
+TclCompileDictLappendCmd(
+ 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. */
+{
+ Proc *procPtr = envPtr->procPtr;
+ DefineLineInformation; /* TIP #280 */
+ Tcl_Token *varTokenPtr, *keyTokenPtr, *valueTokenPtr;
+ int dictVarIndex, nameChars;
+ const char *name;
+
+ /*
+ * There must be three arguments after the command.
+ */
+
+ if (parsePtr->numWords != 4 || procPtr == NULL) {
+ return TCL_ERROR;
+ }
+
+ varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ keyTokenPtr = TokenAfter(varTokenPtr);
+ valueTokenPtr = TokenAfter(keyTokenPtr);
+ 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, procPtr);
+ CompileWord(envPtr, keyTokenPtr, interp, 3);
+ CompileWord(envPtr, valueTokenPtr, interp, 4);
+ TclEmitInstInt4( INST_DICT_LAPPEND, dictVarIndex, envPtr);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DupDictUpdateInfo, FreeDictUpdateInfo --
+ *
+ * Functions to duplicate, release and print the aux data created for use
+ * with the INST_DICT_UPDATE_START and INST_DICT_UPDATE_END instructions.
+ *
+ * Results:
+ * DupDictUpdateInfo: a copy of the auxiliary data
+ * FreeDictUpdateInfo: none
+ * PrintDictUpdateInfo: none
+ *
+ * Side effects:
+ * DupDictUpdateInfo: allocates memory
+ * FreeDictUpdateInfo: releases memory
+ * PrintDictUpdateInfo: none
+ *
+ *----------------------------------------------------------------------
+ */
+
+static ClientData
+DupDictUpdateInfo(
+ ClientData clientData)
+{
+ DictUpdateInfo *dui1Ptr, *dui2Ptr;
+ unsigned len;
+
+ dui1Ptr = clientData;
+ len = sizeof(DictUpdateInfo) + sizeof(int) * (dui1Ptr->length - 1);
+ dui2Ptr = (DictUpdateInfo *) ckalloc(len);
+ memcpy(dui2Ptr, dui1Ptr, len);
+ return dui2Ptr;
+}
+
+static void
+FreeDictUpdateInfo(
+ ClientData clientData)
+{
+ ckfree(clientData);
+}
+
+static void
+PrintDictUpdateInfo(
+ ClientData clientData,
+ Tcl_Obj *appendObj,
+ ByteCode *codePtr,
+ unsigned int pcOffset)
+{
+ DictUpdateInfo *duiPtr = clientData;
+ int i;
+
+ for (i=0 ; i<duiPtr->length ; i++) {
+ if (i) {
+ Tcl_AppendToObj(appendObj, ", ", -1);
+ }
+ Tcl_AppendPrintfToObj(appendObj, "%%v%u", duiPtr->varIndices[i]);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TclCompileExprCmd --
*
* Procedure called to compile the "expr" command.
*
* Results:
- * The return value is a standard Tcl result, which is TCL_OK
- * unless there was an error while parsing string. If an error occurs
- * then the interpreter's result contains a standard error message.
+ * 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 "expr" command
- * at runtime.
+ * Instructions are added to envPtr to execute the "expr" command at
+ * runtime.
*
*----------------------------------------------------------------------
*/
int
-TclCompileExprCmd(interp, parsePtr, envPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tcl_Parse *parsePtr; /* Points to a parse structure for the
- * command created by Tcl_ParseCommand. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
+TclCompileExprCmd(
+ 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 *firstWordPtr;
- DefineLineInformation;
-
if (parsePtr->numWords == 1) {
- Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "wrong # args: should be \"expr arg ?arg ...?\"", -1);
- return TCL_ERROR;
+ return TCL_ERROR;
}
- SetLineInformation (1);
- firstWordPtr = parsePtr->tokenPtr
- + (parsePtr->tokenPtr->numComponents + 1);
- return TclCompileExprWords(interp, firstWordPtr, (parsePtr->numWords-1),
- envPtr);
+ /*
+ * TIP #280: Use the per-word line information of the current command.
+ */
+
+ envPtr->line = envPtr->extCmdMapPtr->loc[
+ envPtr->extCmdMapPtr->nuloc-1].line[1];
+
+ firstWordPtr = TokenAfter(parsePtr->tokenPtr);
+ TclCompileExprWords(interp, firstWordPtr, parsePtr->numWords-1, envPtr);
+ return TCL_OK;
}
/*
@@ -516,36 +1432,33 @@ TclCompileExprCmd(interp, parsePtr, envPtr)
* Procedure called to compile the "for" command.
*
* Results:
- * The return value is a standard Tcl result, which is TCL_OK unless
- * there was an error while parsing string. If an error occurs then
- * the interpreter's result contains a standard error message.
+ * 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 "for" command
- * at runtime.
+ * Instructions are added to envPtr to execute the "for" command at
+ * runtime.
*
*----------------------------------------------------------------------
*/
+
int
-TclCompileForCmd(interp, parsePtr, envPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tcl_Parse *parsePtr; /* Points to a parse structure for the
- * command created by Tcl_ParseCommand. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
+TclCompileForCmd(
+ 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 *startTokenPtr, *testTokenPtr, *nextTokenPtr, *bodyTokenPtr;
JumpFixup jumpEvalCondFixup;
int testCodeOffset, bodyCodeOffset, nextCodeOffset, jumpDist;
- int bodyRange, nextRange, code;
- char buffer[32 + TCL_INTEGER_SPACE];
+ int bodyRange, nextRange;
int savedStackDepth = envPtr->currStackDepth;
-
- DefineLineInformation;
+ DefineLineInformation; /* TIP #280 */
if (parsePtr->numWords != 5) {
- Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "wrong # args: should be \"for start test next command\"", -1);
return TCL_ERROR;
}
@@ -555,11 +1468,10 @@ TclCompileForCmd(interp, parsePtr, envPtr)
* execute or execute forever, as in "for {} "$x > 5" {incr x} {}".
*/
- startTokenPtr = parsePtr->tokenPtr
- + (parsePtr->tokenPtr->numComponents + 1);
- testTokenPtr = startTokenPtr + (startTokenPtr->numComponents + 1);
+ startTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ testTokenPtr = TokenAfter(startTokenPtr);
if (testTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- return TCL_OUT_LINE_COMPILE;
+ return TCL_ERROR;
}
/*
@@ -567,23 +1479,20 @@ TclCompileForCmd(interp, parsePtr, envPtr)
* in order to insure correct behaviour [Bug 219166]
*/
- nextTokenPtr = testTokenPtr + (testTokenPtr->numComponents + 1);
- bodyTokenPtr = nextTokenPtr + (nextTokenPtr->numComponents + 1);
- if ((nextTokenPtr->type != TCL_TOKEN_SIMPLE_WORD)
+ nextTokenPtr = TokenAfter(testTokenPtr);
+ bodyTokenPtr = TokenAfter(nextTokenPtr);
+ if ((nextTokenPtr->type != TCL_TOKEN_SIMPLE_WORD)
|| (bodyTokenPtr->type != TCL_TOKEN_SIMPLE_WORD)) {
- return TCL_OUT_LINE_COMPILE;
+ return TCL_ERROR;
}
/*
- * 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).
+ * 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).
*/
- envPtr->exceptDepth++;
- envPtr->maxExceptDepth =
- TclMax(envPtr->exceptDepth, envPtr->maxExceptDepth);
- bodyRange = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr);
+ bodyRange = DeclareExceptionRange(envPtr, LOOP_EXCEPTION_RANGE);
nextRange = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr);
/*
@@ -591,17 +1500,9 @@ TclCompileForCmd(interp, parsePtr, envPtr)
*/
SetLineInformation (1);
- code = TclCompileCmdWord(interp, startTokenPtr+1,
- startTokenPtr->numComponents, envPtr);
- if (code != TCL_OK) {
- if (code == TCL_ERROR) {
- Tcl_AddObjErrorInfo(interp,
- "\n (\"for\" initial command)", -1);
- }
- goto done;
- }
+ CompileBody(envPtr, startTokenPtr, interp);
TclEmitOpcode(INST_POP, envPtr);
-
+
/*
* Jump to the evaluation of the condition. This code uses the "loop
* rotation" optimisation (which eliminates one branch from the loop).
@@ -620,46 +1521,23 @@ TclCompileForCmd(interp, parsePtr, envPtr)
* Compile the loop body.
*/
- bodyCodeOffset = (envPtr->codeNext - envPtr->codeStart);
-
+ bodyCodeOffset = ExceptionRangeStarts(envPtr, bodyRange);
SetLineInformation (4);
- code = TclCompileCmdWord(interp, bodyTokenPtr+1,
- bodyTokenPtr->numComponents, envPtr);
+ CompileBody(envPtr, bodyTokenPtr, interp);
+ ExceptionRangeEnds(envPtr, bodyRange);
envPtr->currStackDepth = savedStackDepth + 1;
- if (code != TCL_OK) {
- if (code == TCL_ERROR) {
- sprintf(buffer, "\n (\"for\" body line %d)",
- interp->errorLine);
- Tcl_AddObjErrorInfo(interp, buffer, -1);
- }
- goto done;
- }
- envPtr->exceptArrayPtr[bodyRange].numCodeBytes =
- (envPtr->codeNext - envPtr->codeStart) - bodyCodeOffset;
TclEmitOpcode(INST_POP, envPtr);
-
/*
* Compile the "next" subcommand.
*/
- nextCodeOffset = (envPtr->codeNext - envPtr->codeStart);
-
- SetLineInformation (3);
envPtr->currStackDepth = savedStackDepth;
- code = TclCompileCmdWord(interp, nextTokenPtr+1,
- nextTokenPtr->numComponents, envPtr);
+ nextCodeOffset = ExceptionRangeStarts(envPtr, nextRange);
+ SetLineInformation (3);
+ CompileBody(envPtr, nextTokenPtr, interp);
+ ExceptionRangeEnds(envPtr, nextRange);
envPtr->currStackDepth = savedStackDepth + 1;
- if (code != TCL_OK) {
- if (code == TCL_ERROR) {
- Tcl_AddObjErrorInfo(interp,
- "\n (\"for\" loop-end command)", -1);
- }
- goto done;
- }
- envPtr->exceptArrayPtr[nextRange].numCodeBytes =
- (envPtr->codeNext - envPtr->codeStart)
- - nextCodeOffset;
TclEmitOpcode(INST_POP, envPtr);
envPtr->currStackDepth = savedStackDepth;
@@ -668,7 +1546,7 @@ TclCompileForCmd(interp, parsePtr, envPtr)
* terminates the for.
*/
- testCodeOffset = (envPtr->codeNext - envPtr->codeStart);
+ testCodeOffset = CurrentOffset(envPtr);
jumpDist = testCodeOffset - jumpEvalCondFixup.codeOffset;
if (TclFixupForwardJump(envPtr, &jumpEvalCondFixup, jumpDist, 127)) {
@@ -676,27 +1554,22 @@ TclCompileForCmd(interp, parsePtr, envPtr)
nextCodeOffset += 3;
testCodeOffset += 3;
}
+
SetLineInformation (2);
envPtr->currStackDepth = savedStackDepth;
- code = TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
- if (code != TCL_OK) {
- if (code == TCL_ERROR) {
- Tcl_AddObjErrorInfo(interp,
- "\n (\"for\" test expression)", -1);
- }
- goto done;
- }
+ TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
envPtr->currStackDepth = savedStackDepth + 1;
-
- jumpDist = (envPtr->codeNext - envPtr->codeStart) - bodyCodeOffset;
+
+ jumpDist = CurrentOffset(envPtr) - bodyCodeOffset;
if (jumpDist > 127) {
TclEmitInstInt4(INST_JUMP_TRUE4, -jumpDist, envPtr);
} else {
TclEmitInstInt1(INST_JUMP_TRUE1, -jumpDist, envPtr);
}
-
+
/*
- * Set the loop's offsets and break target.
+ * Fix the starting points of the exception ranges (may have moved due to
+ * jump type modification) and set where the exceptions target.
*/
envPtr->exceptArrayPtr[bodyRange].codeOffset = bodyCodeOffset;
@@ -704,21 +1577,17 @@ TclCompileForCmd(interp, parsePtr, envPtr)
envPtr->exceptArrayPtr[nextRange].codeOffset = nextCodeOffset;
- envPtr->exceptArrayPtr[bodyRange].breakOffset =
- envPtr->exceptArrayPtr[nextRange].breakOffset =
- (envPtr->codeNext - envPtr->codeStart);
-
+ ExceptionRangeTarget(envPtr, bodyRange, breakOffset);
+ ExceptionRangeTarget(envPtr, nextRange, breakOffset);
+
/*
* The for command's result is an empty string.
*/
envPtr->currStackDepth = savedStackDepth;
- TclEmitPush(TclRegisterNewLiteral(envPtr, "", 0), envPtr);
- code = TCL_OK;
+ PushLiteral(envPtr, "", 0);
- done:
- envPtr->exceptDepth--;
- return code;
+ return TCL_OK;
}
/*
@@ -729,27 +1598,24 @@ TclCompileForCmd(interp, parsePtr, envPtr)
* Procedure called to compile the "foreach" command.
*
* Results:
- * The return value is a standard Tcl result, which is TCL_OK if
- * compilation was successful. If an error occurs then the
- * interpreter's result contains a standard error message and TCL_ERROR
- * is returned. If the command is too complex for TclCompileForeachCmd,
- * TCL_OUT_LINE_COMPILE is returned indicating that the foreach command
- * should be compiled "out of line" by emitting code to invoke its
- * command procedure at runtime.
+ * 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.
+ * Instructions are added to envPtr to execute the "foreach" command at
+ * runtime.
*
-n*----------------------------------------------------------------------
+ *----------------------------------------------------------------------
*/
int
-TclCompileForeachCmd(interp, parsePtr, envPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tcl_Parse *parsePtr; /* Points to a parse structure for the
- * command created by Tcl_ParseCommand. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
+TclCompileForeachCmd(
+ 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. */
{
Proc *procPtr = envPtr->procPtr;
ForeachInfo *infoPtr; /* Points to the structure describing this
@@ -762,28 +1628,19 @@ TclCompileForeachCmd(interp, parsePtr, envPtr)
Tcl_Token *tokenPtr, *bodyTokenPtr;
unsigned char *jumpPc;
JumpFixup jumpFalseFixup;
- int jumpDist, jumpBackDist, jumpBackOffset, infoIndex, range;
+ int jumpBackDist, jumpBackOffset, infoIndex, range, bodyIndex;
int numWords, numLists, numVars, loopIndex, tempVar, i, j, code;
- char buffer[32 + TCL_INTEGER_SPACE];
int savedStackDepth = envPtr->currStackDepth;
-
-#ifdef TCL_TIP280
- int bodyIndex;
-#endif
+ DefineLineInformation; /* TIP #280 */
/*
* We parse the variable list argument words and create two arrays:
- * varcList[i] is number of variables in i-th var list
- * varvList[i] points to array of var names in i-th var list
+ * varcList[i] is number of variables in i-th var list.
+ * varvList[i] points to array of var names in i-th var list.
*/
-#define STATIC_VAR_LIST_SIZE 5
- int varcListStaticSpace[STATIC_VAR_LIST_SIZE];
- CONST char **varvListStaticSpace[STATIC_VAR_LIST_SIZE];
- int *varcList = varcListStaticSpace;
- CONST char ***varvList = varvListStaticSpace;
-
- DefineLineInformation;
+ int *varcList;
+ const char ***varvList;
/*
* If the foreach command isn't in a procedure, don't compile it inline:
@@ -791,129 +1648,120 @@ TclCompileForeachCmd(interp, parsePtr, envPtr)
*/
if (procPtr == NULL) {
- return TCL_OUT_LINE_COMPILE;
+ return TCL_ERROR;
}
numWords = parsePtr->numWords;
if ((numWords < 4) || (numWords%2 != 0)) {
- Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "wrong # args: should be \"foreach varList list ?varList list ...? command\"", -1);
- return TCL_ERROR;
+ return TCL_ERROR;
}
/*
- * Bail out if the body requires substitutions
- * in order to insure correct behaviour [Bug 219166]
+ * Bail out if the body requires substitutions in order to insure correct
+ * behaviour. [Bug 219166]
*/
- for (i = 0, tokenPtr = parsePtr->tokenPtr;
- i < numWords-1;
- i++, tokenPtr += (tokenPtr->numComponents + 1)) {
+
+ for (i = 0, tokenPtr = parsePtr->tokenPtr; i < numWords-1; i++) {
+ tokenPtr = TokenAfter(tokenPtr);
}
bodyTokenPtr = tokenPtr;
if (bodyTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- return TCL_OUT_LINE_COMPILE;
+ return TCL_ERROR;
}
-#ifdef TCL_TIP280
+
bodyIndex = i-1;
-#endif
/*
* Allocate storage for the varcList and varvList arrays if necessary.
*/
numLists = (numWords - 2)/2;
- if (numLists > STATIC_VAR_LIST_SIZE) {
- varcList = (int *) ckalloc(numLists * sizeof(int));
- varvList = (CONST char ***) ckalloc(numLists * sizeof(CONST char **));
- }
- for (loopIndex = 0; loopIndex < numLists; loopIndex++) {
- varcList[loopIndex] = 0;
- varvList[loopIndex] = NULL;
- }
-
- /*
- * Set the exception stack depth.
- */
-
- envPtr->exceptDepth++;
- envPtr->maxExceptDepth =
- TclMax(envPtr->exceptDepth, envPtr->maxExceptDepth);
+ varcList = (int *) TclStackAlloc(interp, numLists * sizeof(int));
+ memset(varcList, 0, numLists * sizeof(int));
+ varvList = (const char ***) TclStackAlloc(interp,
+ numLists * sizeof(const char **));
+ memset((char*) varvList, 0, numLists * sizeof(const char **));
/*
- * Break up each var list and set the varcList and varvList arrays.
- * Don't compile the foreach inline if any var name needs substitutions
- * or isn't a scalar, or if any var list needs substitutions.
+ * Break up each var list and set the varcList and varvList arrays. Don't
+ * compile the foreach inline if any var name needs substitutions or isn't
+ * a scalar, or if any var list needs substitutions.
*/
loopIndex = 0;
for (i = 0, tokenPtr = parsePtr->tokenPtr;
i < numWords-1;
- i++, tokenPtr += (tokenPtr->numComponents + 1)) {
- if (i%2 == 1) {
- if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- code = TCL_OUT_LINE_COMPILE;
- goto done;
- } else {
- /* Lots of copying going on here. Need a ListObj wizard
- * to show a better way. */
-
- Tcl_DString varList;
-
- Tcl_DStringInit(&varList);
- Tcl_DStringAppend(&varList, tokenPtr[1].start,
- tokenPtr[1].size);
- code = Tcl_SplitList(interp, Tcl_DStringValue(&varList),
- &varcList[loopIndex], &varvList[loopIndex]);
- Tcl_DStringFree(&varList);
- if (code != TCL_OK) {
- goto done;
- }
- numVars = varcList[loopIndex];
+ i++, tokenPtr = TokenAfter(tokenPtr)) {
+ Tcl_DString varList;
- /*
- * If the variable list is empty, we can enter an infinite
- * loop when the interpreted version would not. Take care to
- * ensure this does not happen. [Bug 1671138]
- */
+ if (i%2 != 1) {
+ continue;
+ }
+ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+ code = TCL_ERROR;
+ goto done;
+ }
- if (numVars == 0) {
- code = TCL_OUT_LINE_COMPILE;
- goto done;
- }
+ /*
+ * Lots of copying going on here. Need a ListObj wizard to show a
+ * better way.
+ */
- for (j = 0; j < numVars; j++) {
- CONST char *varName = varvList[loopIndex][j];
- if (!TclIsLocalScalar(varName, (int) strlen(varName))) {
- code = TCL_OUT_LINE_COMPILE;
- goto done;
- }
- }
+ Tcl_DStringInit(&varList);
+ Tcl_DStringAppend(&varList, tokenPtr[1].start, tokenPtr[1].size);
+ code = Tcl_SplitList(interp, Tcl_DStringValue(&varList),
+ &varcList[loopIndex], &varvList[loopIndex]);
+ Tcl_DStringFree(&varList);
+ if (code != TCL_OK) {
+ code = TCL_ERROR;
+ goto done;
+ }
+ numVars = varcList[loopIndex];
+
+ /*
+ * If the variable list is empty, we can enter an infinite loop when
+ * the interpreted version would not. Take care to ensure this does
+ * not happen. [Bug 1671138]
+ */
+
+ if (numVars == 0) {
+ code = TCL_ERROR;
+ goto done;
+ }
+
+ for (j = 0; j < numVars; j++) {
+ const char *varName = varvList[loopIndex][j];
+
+ if (!TclIsLocalScalar(varName, (int) strlen(varName))) {
+ code = TCL_ERROR;
+ goto done;
}
- loopIndex++;
}
+ loopIndex++;
}
/*
- * We will compile the foreach command.
- * Reserve (numLists + 1) temporary variables:
+ * 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.
*/
+ code = TCL_OK;
firstValueTemp = -1;
for (loopIndex = 0; loopIndex < numLists; loopIndex++) {
tempVar = TclFindCompiledLocal(NULL, /*nameChars*/ 0,
- /*create*/ 1, /*flags*/ VAR_SCALAR, procPtr);
+ /*create*/ 1, procPtr);
if (loopIndex == 0) {
firstValueTemp = tempVar;
}
}
loopCtTemp = TclFindCompiledLocal(NULL, /*nameChars*/ 0,
- /*create*/ 1, /*flags*/ VAR_SCALAR, procPtr);
-
+ /*create*/ 1, procPtr);
+
/*
* Create and initialize the ForeachInfo and ForeachVarList data
* structures describing this command. Then create a AuxData record
@@ -921,7 +1769,7 @@ TclCompileForeachCmd(interp, parsePtr, envPtr)
*/
infoPtr = (ForeachInfo *) ckalloc((unsigned)
- (sizeof(ForeachInfo) + (numLists * sizeof(ForeachVarList *))));
+ sizeof(ForeachInfo) + numLists*sizeof(ForeachVarList *));
infoPtr->numLists = numLists;
infoPtr->firstValueTemp = firstValueTemp;
infoPtr->loopCtTemp = loopCtTemp;
@@ -929,36 +1777,36 @@ TclCompileForeachCmd(interp, parsePtr, envPtr)
ForeachVarList *varListPtr;
numVars = varcList[loopIndex];
varListPtr = (ForeachVarList *) ckalloc((unsigned)
- sizeof(ForeachVarList) + (numVars * sizeof(int)));
+ sizeof(ForeachVarList) + numVars*sizeof(int));
varListPtr->numVars = numVars;
for (j = 0; j < numVars; j++) {
- CONST char *varName = varvList[loopIndex][j];
+ const char *varName = varvList[loopIndex][j];
int nameChars = strlen(varName);
+
varListPtr->varIndexes[j] = TclFindCompiledLocal(varName,
- nameChars, /*create*/ 1, /*flags*/ VAR_SCALAR, procPtr);
+ nameChars, /*create*/ 1, procPtr);
}
infoPtr->varLists[loopIndex] = varListPtr;
}
- infoIndex = TclCreateAuxData((ClientData) infoPtr, &tclForeachInfoType, envPtr);
+ infoIndex = TclCreateAuxData(infoPtr, &tclForeachInfoType, envPtr);
+
+ /*
+ * Create an exception record to handle [break] and [continue].
+ */
+
+ range = DeclareExceptionRange(envPtr, LOOP_EXCEPTION_RANGE);
/*
* Evaluate then store each value list in the associated temporary.
*/
- range = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr);
-
loopIndex = 0;
for (i = 0, tokenPtr = parsePtr->tokenPtr;
i < numWords-1;
- i++, tokenPtr += (tokenPtr->numComponents + 1)) {
+ i++, tokenPtr = TokenAfter(tokenPtr)) {
if ((i%2 == 0) && (i > 0)) {
SetLineInformation (i);
- code = TclCompileTokens(interp, tokenPtr+1,
- tokenPtr->numComponents, envPtr);
- if (code != TCL_OK) {
- goto done;
- }
-
+ CompileTokens(envPtr, tokenPtr, interp);
tempVar = (firstValueTemp + loopIndex);
if (tempVar <= 255) {
TclEmitInstInt1(INST_STORE_SCALAR1, tempVar, envPtr);
@@ -975,50 +1823,36 @@ TclCompileForeachCmd(interp, parsePtr, envPtr)
*/
TclEmitInstInt4(INST_FOREACH_START4, infoIndex, envPtr);
-
+
/*
* Top of loop code: assign each loop variable and check whether
* to terminate the loop.
*/
- envPtr->exceptArrayPtr[range].continueOffset =
- (envPtr->codeNext - envPtr->codeStart);
+ ExceptionRangeTarget(envPtr, range, continueOffset);
TclEmitInstInt4(INST_FOREACH_STEP4, infoIndex, envPtr);
TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &jumpFalseFixup);
-
+
/*
* Inline compile the loop body.
*/
SetLineInformation (bodyIndex);
- envPtr->exceptArrayPtr[range].codeOffset =
- (envPtr->codeNext - envPtr->codeStart);
- code = TclCompileCmdWord(interp, bodyTokenPtr+1,
- bodyTokenPtr->numComponents, envPtr);
+ ExceptionRangeStarts(envPtr, range);
+ CompileBody(envPtr, bodyTokenPtr, interp);
+ ExceptionRangeEnds(envPtr, range);
envPtr->currStackDepth = savedStackDepth + 1;
- if (code != TCL_OK) {
- if (code == TCL_ERROR) {
- sprintf(buffer, "\n (\"foreach\" body line %d)",
- interp->errorLine);
- Tcl_AddObjErrorInfo(interp, buffer, -1);
- }
- goto done;
- }
- envPtr->exceptArrayPtr[range].numCodeBytes =
- (envPtr->codeNext - envPtr->codeStart)
- - envPtr->exceptArrayPtr[range].codeOffset;
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
+ * 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 = (envPtr->codeNext - envPtr->codeStart);
- jumpBackDist =
- (jumpBackOffset - envPtr->exceptArrayPtr[range].continueOffset);
+ jumpBackOffset = CurrentOffset(envPtr);
+ jumpBackDist = jumpBackOffset-envPtr->exceptArrayPtr[range].continueOffset;
if (jumpBackDist > 120) {
TclEmitInstInt4(INST_JUMP4, -jumpBackDist, envPtr);
} else {
@@ -1029,9 +1863,7 @@ TclCompileForeachCmd(interp, parsePtr, envPtr)
* Fix the target of the jump after the foreach_step test.
*/
- jumpDist = (envPtr->codeNext - envPtr->codeStart)
- - jumpFalseFixup.codeOffset;
- if (TclFixupForwardJump(envPtr, &jumpFalseFixup, jumpDist, 127)) {
+ if (TclFixupForwardJumpToHere(envPtr, &jumpFalseFixup, 127)) {
/*
* Update the loop body's starting PC offset since it moved down.
*/
@@ -1057,28 +1889,24 @@ TclCompileForeachCmd(interp, parsePtr, envPtr)
* Set the loop's break target.
*/
- envPtr->exceptArrayPtr[range].breakOffset =
- (envPtr->codeNext - envPtr->codeStart);
-
+ ExceptionRangeTarget(envPtr, range, breakOffset);
+
/*
* The foreach command's result is an empty string.
*/
envPtr->currStackDepth = savedStackDepth;
- TclEmitPush(TclRegisterNewLiteral(envPtr, "", 0), envPtr);
+ PushLiteral(envPtr, "", 0);
envPtr->currStackDepth = savedStackDepth + 1;
- done:
+ done:
for (loopIndex = 0; loopIndex < numLists; loopIndex++) {
- if (varvList[loopIndex] != (CONST char **) NULL) {
+ if (varvList[loopIndex] != NULL) {
ckfree((char *) varvList[loopIndex]);
}
}
- if (varcList != varcListStaticSpace) {
- ckfree((char *) varcList);
- ckfree((char *) varvList);
- }
- envPtr->exceptDepth--;
+ TclStackFree(interp, (void *)varvList);
+ TclStackFree(interp, varcList);
return code;
}
@@ -1087,8 +1915,8 @@ TclCompileForeachCmd(interp, parsePtr, envPtr)
*
* DupForeachInfo --
*
- * This procedure duplicates a ForeachInfo structure created as
- * auxiliary data during the compilation of a foreach command.
+ * This procedure duplicates a ForeachInfo structure created as auxiliary
+ * data during the compilation of a foreach command.
*
* Results:
* A pointer to a newly allocated copy of the existing ForeachInfo
@@ -1096,42 +1924,41 @@ TclCompileForeachCmd(interp, parsePtr, envPtr)
*
* Side effects:
* Storage for the copied ForeachInfo record is allocated. If the
- * original ForeachInfo structure pointed to any ForeachVarList
- * records, these structures are also copied and pointers to them
- * are stored in the new ForeachInfo record.
+ * original ForeachInfo structure pointed to any ForeachVarList records,
+ * these structures are also copied and pointers to them are stored in
+ * the new ForeachInfo record.
*
*----------------------------------------------------------------------
*/
static ClientData
-DupForeachInfo(clientData)
- ClientData clientData; /* The foreach command's compilation
- * auxiliary data to duplicate. */
+DupForeachInfo(
+ ClientData clientData) /* The foreach command's compilation auxiliary
+ * data to duplicate. */
{
- register ForeachInfo *srcPtr = (ForeachInfo *) clientData;
+ register ForeachInfo *srcPtr = clientData;
ForeachInfo *dupPtr;
register ForeachVarList *srcListPtr, *dupListPtr;
- int numLists = srcPtr->numLists;
- int numVars, i, j;
-
+ int numVars, i, j, numLists = srcPtr->numLists;
+
dupPtr = (ForeachInfo *) ckalloc((unsigned)
- (sizeof(ForeachInfo) + (numLists * sizeof(ForeachVarList *))));
+ sizeof(ForeachInfo) + numLists*sizeof(ForeachVarList *));
dupPtr->numLists = numLists;
dupPtr->firstValueTemp = srcPtr->firstValueTemp;
dupPtr->loopCtTemp = srcPtr->loopCtTemp;
-
+
for (i = 0; i < numLists; i++) {
srcListPtr = srcPtr->varLists[i];
numVars = srcListPtr->numVars;
dupListPtr = (ForeachVarList *) ckalloc((unsigned)
- sizeof(ForeachVarList) + numVars*sizeof(int));
+ sizeof(ForeachVarList) + numVars*sizeof(int));
dupListPtr->numVars = numVars;
for (j = 0; j < numVars; j++) {
dupListPtr->varIndexes[j] = srcListPtr->varIndexes[j];
}
dupPtr->varLists[i] = dupListPtr;
}
- return (ClientData) dupPtr;
+ return dupPtr;
}
/*
@@ -1154,11 +1981,11 @@ DupForeachInfo(clientData)
*/
static void
-FreeForeachInfo(clientData)
- ClientData clientData; /* The foreach command's compilation
- * auxiliary data to free. */
+FreeForeachInfo(
+ ClientData clientData) /* The foreach command's compilation auxiliary
+ * data to free. */
{
- register ForeachInfo *infoPtr = (ForeachInfo *) clientData;
+ register ForeachInfo *infoPtr = clientData;
register ForeachVarList *listPtr;
int numLists = infoPtr->numLists;
register int i;
@@ -1173,58 +2000,111 @@ FreeForeachInfo(clientData)
/*
*----------------------------------------------------------------------
*
+ * PrintForeachInfo --
+ *
+ * Function to write a human-readable representation of a ForeachInfo
+ * structure to stdout for debugging.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+PrintForeachInfo(
+ ClientData clientData,
+ Tcl_Obj *appendObj,
+ ByteCode *codePtr,
+ unsigned int pcOffset)
+{
+ register ForeachInfo *infoPtr = clientData;
+ register ForeachVarList *varsPtr;
+ int i, j;
+
+ Tcl_AppendToObj(appendObj, "data=[", -1);
+
+ for (i=0 ; i<infoPtr->numLists ; i++) {
+ if (i) {
+ Tcl_AppendToObj(appendObj, ", ", -1);
+ }
+ Tcl_AppendPrintfToObj(appendObj, "%%v%u",
+ (unsigned) (infoPtr->firstValueTemp + i));
+ }
+ Tcl_AppendPrintfToObj(appendObj, "], loop=%%v%u",
+ (unsigned) infoPtr->loopCtTemp);
+ for (i=0 ; i<infoPtr->numLists ; i++) {
+ if (i) {
+ Tcl_AppendToObj(appendObj, ",", -1);
+ }
+ Tcl_AppendPrintfToObj(appendObj, "\n\t\t it%%v%u\t[",
+ (unsigned) (infoPtr->firstValueTemp + i));
+ 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]);
+ }
+ Tcl_AppendToObj(appendObj, "]", -1);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TclCompileIfCmd --
*
* Procedure called to compile the "if" command.
*
* Results:
- * The return value is a standard Tcl result, which is TCL_OK if
- * compilation was successful. If an error occurs then the
- * interpreter's result contains a standard error message and TCL_ERROR
- * is returned. If the command is too complex for TclCompileIfCmd,
- * TCL_OUT_LINE_COMPILE is returned indicating that the if command
- * should be compiled "out of line" by emitting code to invoke its
- * command procedure at runtime.
+ * 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.
+ * Instructions are added to envPtr to execute the "if" command at
+ * runtime.
*
*----------------------------------------------------------------------
*/
+
int
-TclCompileIfCmd(interp, parsePtr, envPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tcl_Parse *parsePtr; /* Points to a parse structure for the
- * command created by Tcl_ParseCommand. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
+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. */
+ /* 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 jumpDist, jumpFalseDist;
- int jumpIndex = 0; /* avoid compiler warning. */
- int numWords, wordIdx, numBytes, j, code;
- CONST char *word;
- char buffer[100];
+ 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
+ /* 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;
+ 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]
+ * Only compile the "if" command if all arguments are simple words, in
+ * order to insure correct substitution [Bug 219166]
*/
tokenPtr = parsePtr->tokenPtr;
@@ -1233,19 +2113,18 @@ TclCompileIfCmd(interp, parsePtr, envPtr)
for (wordIdx = 0; wordIdx < numWords; wordIdx++) {
if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- return TCL_OUT_LINE_COMPILE;
+ return TCL_ERROR;
}
- tokenPtr += 2;
+ 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.
+ * Each iteration of this loop compiles one "if expr ?then? body" or
+ * "elseif expr ?then? body" clause.
*/
tokenPtr = parsePtr->tokenPtr;
@@ -1258,84 +2137,66 @@ TclCompileIfCmd(interp, parsePtr, envPtr)
word = tokenPtr[1].start;
numBytes = tokenPtr[1].size;
if ((tokenPtr == parsePtr->tokenPtr)
- || ((numBytes == 6) && (strncmp(word, "elseif", 6) == 0))) {
- tokenPtr += (tokenPtr->numComponents + 1);
+ || ((numBytes == 6) && (strncmp(word, "elseif", 6) == 0))) {
+ tokenPtr = TokenAfter(tokenPtr);
wordIdx++;
} else {
break;
}
if (wordIdx >= numWords) {
- sprintf(buffer,
- "wrong # args: no expression after \"%.*s\" argument",
- (numBytes > 50 ? 50 : numBytes), word);
- Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp), buffer, -1);
code = TCL_ERROR;
goto done;
}
/*
- * Compile the test expression then emit the conditional jump
- * around the "then" part.
+ * 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.
+ * 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);
- Tcl_DecrRefCount(boolObj);
+ TclDecrRefCount(boolObj);
if (code == TCL_OK) {
/*
- * A static condition
+ * A static condition.
*/
+
realCond = 0;
if (!boolVal) {
compileScripts = 0;
}
} else {
- Tcl_ResetResult(interp);
SetLineInformation (wordIdx);
- code = TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
- if (code != TCL_OK) {
- if (code == TCL_ERROR) {
- Tcl_AddObjErrorInfo(interp,
- "\n (\"if\" test expression)", -1);
- }
- goto done;
- }
+ 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]));
+ jumpFalseFixupArray.fixup+jumpIndex);
}
+ code = TCL_OK;
}
-
/*
* Skip over the optional "then" before the then clause.
*/
- tokenPtr = testTokenPtr + (testTokenPtr->numComponents + 1);
+ tokenPtr = TokenAfter(testTokenPtr);
wordIdx++;
if (wordIdx >= numWords) {
- sprintf(buffer,
- "wrong # args: no script following \"%.*s\" argument",
- (testTokenPtr->size > 50 ? 50 : testTokenPtr->size),
- testTokenPtr->start);
- Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp), buffer, -1);
code = TCL_ERROR;
goto done;
}
@@ -1343,12 +2204,9 @@ TclCompileIfCmd(interp, parsePtr, envPtr)
word = tokenPtr[1].start;
numBytes = tokenPtr[1].size;
if ((numBytes == 4) && (strncmp(word, "then", 4) == 0)) {
- tokenPtr += (tokenPtr->numComponents + 1);
+ tokenPtr = TokenAfter(tokenPtr);
wordIdx++;
if (wordIdx >= numWords) {
- Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "wrong # args: no script following \"then\" argument", -1);
code = TCL_ERROR;
goto done;
}
@@ -1362,85 +2220,72 @@ TclCompileIfCmd(interp, parsePtr, envPtr)
if (compileScripts) {
SetLineInformation (wordIdx);
envPtr->currStackDepth = savedStackDepth;
- code = TclCompileCmdWord(interp, tokenPtr+1,
- tokenPtr->numComponents, envPtr);
- if (code != TCL_OK) {
- if (code == TCL_ERROR) {
- sprintf(buffer, "\n (\"if\" then script line %d)",
- interp->errorLine);
- Tcl_AddObjErrorInfo(interp, buffer, -1);
- }
- goto done;
- }
+ CompileBody(envPtr, tokenPtr, interp);
}
if (realCond) {
/*
- * Jump to the end of the "if" command. Both jumpFalseFixupArray and
- * jumpEndFixupArray are indexed by "jumpIndex".
+ * 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]));
-
+ 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.
+ * 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.
*/
- jumpDist = (envPtr->codeNext - envPtr->codeStart)
- - jumpFalseFixupArray.fixup[jumpIndex].codeOffset;
- if (TclFixupForwardJump(envPtr,
- &(jumpFalseFixupArray.fixup[jumpIndex]), jumpDist, 120)) {
+ 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
+ /*
+ * 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
+ /*
+ * We were processing an "if 0 {...}"; reset so that the rest
+ * (elseif, else) is compiled correctly.
*/
realCond = 1;
compileScripts = 1;
- }
+ }
- tokenPtr += (tokenPtr->numComponents + 1);
+ tokenPtr = TokenAfter(tokenPtr);
wordIdx++;
}
/*
- * Restore the current stack depth in the environment; the
- * "else" clause (or its default) will add 1 to this.
+ * 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.
+ * 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)) {
+ if ((wordIdx < numWords) && (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD)) {
/*
* There is an else clause. Skip over the optional "else" word.
*/
@@ -1448,12 +2293,9 @@ TclCompileIfCmd(interp, parsePtr, envPtr)
word = tokenPtr[1].start;
numBytes = tokenPtr[1].size;
if ((numBytes == 4) && (strncmp(word, "else", 4) == 0)) {
- tokenPtr += (tokenPtr->numComponents + 1);
+ tokenPtr = TokenAfter(tokenPtr);
wordIdx++;
if (wordIdx >= numWords) {
- Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "wrong # args: no script following \"else\" argument", -1);
code = TCL_ERROR;
goto done;
}
@@ -1463,28 +2305,17 @@ TclCompileIfCmd(interp, parsePtr, envPtr)
/*
* Compile the else command body.
*/
+
SetLineInformation (wordIdx);
- code = TclCompileCmdWord(interp, tokenPtr+1,
- tokenPtr->numComponents, envPtr);
- if (code != TCL_OK) {
- if (code == TCL_ERROR) {
- sprintf(buffer, "\n (\"if\" else script line %d)",
- interp->errorLine);
- Tcl_AddObjErrorInfo(interp, buffer, -1);
- }
- goto done;
- }
+ CompileBody(envPtr, tokenPtr, interp);
}
/*
* Make sure there are no words after the else clause.
*/
-
+
wordIdx++;
if (wordIdx < numWords) {
- Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "wrong # args: extra words after \"else\" clause in \"if\" command", -1);
code = TCL_ERROR;
goto done;
}
@@ -1494,28 +2325,27 @@ TclCompileIfCmd(interp, parsePtr, envPtr)
*/
if (compileScripts) {
- TclEmitPush(TclRegisterNewLiteral(envPtr, "", 0), envPtr);
+ 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 */
- jumpDist = (envPtr->codeNext - envPtr->codeStart)
- - jumpEndFixupArray.fixup[jumpIndex].codeOffset;
- if (TclFixupForwardJump(envPtr,
- &(jumpEndFixupArray.fixup[jumpIndex]), jumpDist, 127)) {
+ 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.
+ * 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;
+ + jumpFalseFixupArray.fixup[jumpIndex].codeOffset;
unsigned char opCode = *ifFalsePc;
+
if (opCode == INST_JUMP_FALSE1) {
jumpFalseDist = TclGetInt1AtPtr(ifFalsePc + 1);
jumpFalseDist += 3;
@@ -1525,7 +2355,7 @@ TclCompileIfCmd(interp, parsePtr, envPtr)
jumpFalseDist += 3;
TclStoreInt4AtPtr(jumpFalseDist, (ifFalsePc + 1));
} else {
- panic("TclCompileIfCmd: unexpected opcode updating ifFalse jump");
+ Tcl_Panic("TclCompileIfCmd: unexpected opcode \"%d\" updating ifFalse jump", (int) opCode);
}
}
}
@@ -1534,7 +2364,7 @@ TclCompileIfCmd(interp, parsePtr, envPtr)
* Free the jumpFixupArray array if malloc'ed storage was used.
*/
- done:
+ done:
envPtr->currStackDepth = savedStackDepth + 1;
TclFreeJumpFixupArray(&jumpFalseFixupArray);
TclFreeJumpFixupArray(&jumpEndFixupArray);
@@ -1549,50 +2379,37 @@ TclCompileIfCmd(interp, parsePtr, envPtr)
* Procedure called to compile the "incr" command.
*
* Results:
- * The return value is a standard Tcl result, which is TCL_OK if
- * compilation was successful. If an error occurs then the
- * interpreter's result contains a standard error message and TCL_ERROR
- * is returned. If the command is too complex for TclCompileIncrCmd,
- * TCL_OUT_LINE_COMPILE is returned indicating that the incr command
- * should be compiled "out of line" by emitting code to invoke its
- * command procedure at runtime.
+ * 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.
+ * Instructions are added to envPtr to execute the "incr" command at
+ * runtime.
*
*----------------------------------------------------------------------
*/
int
-TclCompileIncrCmd(interp, parsePtr, envPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tcl_Parse *parsePtr; /* Points to a parse structure for the
- * command created by Tcl_ParseCommand. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
+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 simpleVarName, isScalar, localIndex, haveImmValue, immValue;
- int code = TCL_OK;
-
- DefineLineInformation;
+ DefineLineInformation; /* TIP #280 */
if ((parsePtr->numWords != 2) && (parsePtr->numWords != 3)) {
- Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "wrong # args: should be \"incr varName ?increment?\"", -1);
return TCL_ERROR;
}
- varTokenPtr = parsePtr->tokenPtr
- + (parsePtr->tokenPtr->numComponents + 1);
+ varTokenPtr = TokenAfter(parsePtr->tokenPtr);
- code = TclPushVarNameWord(interp, varTokenPtr, envPtr,
- (TCL_NO_LARGE_INDEX | TCL_CREATE_VAR),
- &localIndex, &simpleVarName, &isScalar, 1);
- if (code != TCL_OK) {
- goto done;
- }
+ PushVarNameWord(interp, varTokenPtr, envPtr, TCL_NO_LARGE_INDEX|TCL_CREATE_VAR,
+ &localIndex, &simpleVarName, &isScalar, 1);
/*
* If an increment is given, push it, but see first if it's a small
@@ -1602,44 +2419,29 @@ TclCompileIncrCmd(interp, parsePtr, envPtr)
haveImmValue = 0;
immValue = 1;
if (parsePtr->numWords == 3) {
- incrTokenPtr = varTokenPtr + (varTokenPtr->numComponents + 1);
+ incrTokenPtr = TokenAfter(varTokenPtr);
if (incrTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
- CONST char *word = incrTokenPtr[1].start;
+ const char *word = incrTokenPtr[1].start;
int numBytes = incrTokenPtr[1].size;
-
- /*
- * Note there is a danger that modifying the string could have
- * undesirable side effects. In this case, TclLooksLikeInt has
- * no dependencies on shared strings so we should be safe.
- */
-
- if (TclLooksLikeInt(word, numBytes)) {
- int code;
- Tcl_Obj *intObj = Tcl_NewStringObj(word, numBytes);
- Tcl_IncrRefCount(intObj);
- code = Tcl_GetIntFromObj(NULL, intObj, &immValue);
- Tcl_DecrRefCount(intObj);
- if ((code == TCL_OK)
- && (-127 <= immValue) && (immValue <= 127)) {
- haveImmValue = 1;
- }
+ 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) {
- TclEmitPush(
- TclRegisterNewLiteral(envPtr, word, numBytes), envPtr);
+ PushLiteral(envPtr, word, numBytes);
}
} else {
SetLineInformation (2);
- code = TclCompileTokens(interp, incrTokenPtr+1,
- incrTokenPtr->numComponents, envPtr);
- if (code != TCL_OK) {
- goto done;
- }
+ CompileTokens(envPtr, incrTokenPtr, interp);
}
- } else { /* no incr amount given so use 1 */
+ } else { /* No incr amount given so use 1. */
haveImmValue = 1;
}
-
+
/*
* Emit the instruction to increment the variable.
*/
@@ -1676,16 +2478,15 @@ TclCompileIncrCmd(interp, parsePtr, envPtr)
}
}
}
- } else { /* non-simple variable name */
+ } else { /* Non-simple variable name. */
if (haveImmValue) {
TclEmitInstInt1(INST_INCR_STK_IMM, immValue, envPtr);
} else {
TclEmitOpcode(INST_INCR_STK, envPtr);
}
}
-
- done:
- return code;
+
+ return TCL_OK;
}
/*
@@ -1696,53 +2497,47 @@ TclCompileIncrCmd(interp, parsePtr, envPtr)
* Procedure called to compile the "lappend" command.
*
* Results:
- * The return value is a standard Tcl result, which is normally TCL_OK
- * unless there was an error while parsing string. If an error occurs
- * then the interpreter's result contains a standard error message. If
- * compilation fails because the command requires a second level of
- * substitutions, TCL_OUT_LINE_COMPILE is returned indicating that the
- * command should be compiled "out of line" by emitting code to
- * invoke its command procedure (Tcl_LappendObjCmd) at runtime.
+ * 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.
+ * Instructions are added to envPtr to execute the "lappend" command at
+ * runtime.
*
*----------------------------------------------------------------------
*/
int
-TclCompileLappendCmd(interp, parsePtr, envPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tcl_Parse *parsePtr; /* Points to a parse structure for the
- * command created by Tcl_ParseCommand. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
+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;
+ Tcl_Token *varTokenPtr;
int simpleVarName, isScalar, localIndex, numWords;
- int code = TCL_OK;
-
- DefineLineInformation;
+ DefineLineInformation; /* TIP #280 */
/*
* If we're not in a procedure, don't compile.
*/
+
if (envPtr->procPtr == NULL) {
- return TCL_OUT_LINE_COMPILE;
+ return TCL_ERROR;
}
numWords = parsePtr->numWords;
if (numWords == 1) {
- Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "wrong # args: should be \"lappend varName ?value value ...?\"", -1);
return TCL_ERROR;
}
if (numWords != 3) {
/*
- * LAPPEND instructions currently only handle one value appends
+ * LAPPEND instructions currently only handle one value appends.
*/
- return TCL_OUT_LINE_COMPILE;
+
+ return TCL_ERROR;
}
/*
@@ -1750,36 +2545,22 @@ TclCompileLappendCmd(interp, parsePtr, envPtr)
* 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.
+ * namespace qualifiers.
*/
- varTokenPtr = parsePtr->tokenPtr
- + (parsePtr->tokenPtr->numComponents + 1);
+ varTokenPtr = TokenAfter(parsePtr->tokenPtr);
- code = TclPushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR,
- &localIndex, &simpleVarName, &isScalar, 1);
- if (code != TCL_OK) {
- goto done;
- }
+ PushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR,
+ &localIndex, &simpleVarName, &isScalar, 1);
/*
- * If we are doing an assignment, push the new value.
- * In the no values case, create an empty object.
+ * If we are doing an assignment, push the new value. In the no values
+ * case, create an empty object.
*/
if (numWords > 2) {
- valueTokenPtr = varTokenPtr + (varTokenPtr->numComponents + 1);
- if (valueTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
- TclEmitPush(TclRegisterNewLiteral(envPtr,
- valueTokenPtr[1].start, valueTokenPtr[1].size), envPtr);
- } else {
- SetLineInformation (2);
- code = TclCompileTokens(interp, valueTokenPtr+1,
- valueTokenPtr->numComponents, envPtr);
- if (code != TCL_OK) {
- goto done;
- }
- }
+ Tcl_Token *valueTokenPtr = TokenAfter(varTokenPtr);
+ CompileWord(envPtr, valueTokenPtr, interp, 2);
}
/*
@@ -1790,112 +2571,239 @@ TclCompileLappendCmd(interp, parsePtr, envPtr)
* The *_STK opcodes should be refactored to make better use of existing
* LOAD/STORE instructions.
*/
+
if (simpleVarName) {
if (isScalar) {
- if (localIndex >= 0) {
- if (localIndex <= 255) {
- TclEmitInstInt1(INST_LAPPEND_SCALAR1, localIndex, envPtr);
- } else {
- TclEmitInstInt4(INST_LAPPEND_SCALAR4, localIndex, envPtr);
- }
- } else {
+ 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) {
- if (localIndex <= 255) {
- TclEmitInstInt1(INST_LAPPEND_ARRAY1, localIndex, envPtr);
- } else {
- TclEmitInstInt4(INST_LAPPEND_ARRAY4, 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);
}
- done:
- return code;
+ return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
- * TclCompileLindexCmd --
+ * TclCompileLassignCmd --
*
- * Procedure called to compile the "lindex" command.
+ * Procedure called to compile the "lassign" command.
*
* Results:
- * The return value is a standard Tcl result, which is TCL_OK if the
- * compilation was successful. If the command cannot be byte-compiled,
- * TCL_OUT_LINE_COMPILE is returned. If an error occurs then the
- * interpreter's result contains an error message, and TCL_ERROR is
- * returned.
+ * 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.
+ * Instructions are added to envPtr to execute the "lassign" command at
+ * runtime.
*
*----------------------------------------------------------------------
*/
int
-TclCompileLindexCmd(interp, parsePtr, envPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tcl_Parse *parsePtr; /* Points to a parse structure for the
- * command created by Tcl_ParseCommand. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
+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 *varTokenPtr;
- int code, i;
- int numWords;
-
- DefineLineInformation;
+ Tcl_Token *tokenPtr;
+ int simpleVarName, isScalar, localIndex, numWords, idx;
+ DefineLineInformation; /* TIP #280 */
numWords = parsePtr->numWords;
/*
- * Quit if too few args
+ * Check for command syntax error, but we'll punt that to runtime.
*/
- if ( numWords <= 1 ) {
- return TCL_OUT_LINE_COMPILE;
+ if (numWords < 3) {
+ return TCL_ERROR;
}
- varTokenPtr = parsePtr->tokenPtr
- + (parsePtr->tokenPtr->numComponents + 1);
-
/*
- * Push the operands onto the stack.
+ * Generate code to push list being taken apart by [lassign].
*/
-
- for ( i = 1 ; i < numWords ; i++ ) {
- if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
- TclEmitPush(
- TclRegisterNewLiteral( envPtr, varTokenPtr[1].start,
- varTokenPtr[1].size), envPtr);
- } else {
- SetLineInformation (i);
- code = TclCompileTokens(interp, varTokenPtr+1,
- varTokenPtr->numComponents, envPtr);
- if (code != TCL_OK) {
- return code;
+
+ 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, TCL_CREATE_VAR, &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);
}
- varTokenPtr = varTokenPtr + (varTokenPtr->numComponents + 1);
+ TclEmitOpcode(INST_POP, envPtr);
}
-
+
/*
- * Emit INST_LIST_INDEX if objc==3, or INST_LIST_INDEX_MULTI
- * if there are multiple index args.
+ * Generate code to leave the rest of the list on the stack.
*/
- if ( numWords == 3 ) {
- TclEmitOpcode( INST_LIST_INDEX, envPtr );
+ 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 );
+ TclEmitInstInt4(INST_LIST_INDEX_MULTI, numWords-1, envPtr);
}
return TCL_OK;
@@ -1909,67 +2817,55 @@ TclCompileLindexCmd(interp, parsePtr, envPtr)
* Procedure called to compile the "list" command.
*
* Results:
- * The return value is a standard Tcl result, which is normally TCL_OK
- * unless there was an error while parsing string. If an error occurs
- * then the interpreter's result contains a standard error message. If
- * compilation fails because the command requires a second level of
- * substitutions, TCL_OUT_LINE_COMPILE is returned indicating that the
- * command should be compiled "out of line" by emitting code to
- * invoke its command procedure (Tcl_ListObjCmd) at runtime.
+ * 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.
+ * Instructions are added to envPtr to execute the "list" command at
+ * runtime.
*
*----------------------------------------------------------------------
*/
int
-TclCompileListCmd(interp, parsePtr, envPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tcl_Parse *parsePtr; /* Points to a parse structure for the
- * command created by Tcl_ParseCommand. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
+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;
+ DefineLineInformation; /* TIP #280 */
/*
* If we're not in a procedure, don't compile.
*/
+
if (envPtr->procPtr == NULL) {
- return TCL_OUT_LINE_COMPILE;
+ return TCL_ERROR;
}
if (parsePtr->numWords == 1) {
/*
- * Empty args case
+ * [list] without arguments just pushes an empty object.
*/
- TclEmitPush(TclRegisterNewLiteral(envPtr, "", 0), envPtr);
+ PushLiteral(envPtr, "", 0);
} else {
/*
* Push the all values onto the stack.
*/
+
Tcl_Token *valueTokenPtr;
- int i, code, numWords;
+ int i, numWords;
numWords = parsePtr->numWords;
- valueTokenPtr = parsePtr->tokenPtr
- + (parsePtr->tokenPtr->numComponents + 1);
+ valueTokenPtr = TokenAfter(parsePtr->tokenPtr);
for (i = 1; i < numWords; i++) {
- if (valueTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
- TclEmitPush(TclRegisterNewLiteral(envPtr,
- valueTokenPtr[1].start, valueTokenPtr[1].size), envPtr);
- } else {
- SetLineInformation (i);
- code = TclCompileTokens(interp, valueTokenPtr+1,
- valueTokenPtr->numComponents, envPtr);
- if (code != TCL_OK) {
- return code;
- }
- }
- valueTokenPtr = valueTokenPtr + (valueTokenPtr->numComponents + 1);
+ CompileWord(envPtr, valueTokenPtr, interp, i);
+ valueTokenPtr = TokenAfter(valueTokenPtr);
}
TclEmitInstInt4(INST_LIST, numWords - 1, envPtr);
}
@@ -1985,54 +2881,34 @@ TclCompileListCmd(interp, parsePtr, envPtr)
* Procedure called to compile the "llength" command.
*
* Results:
- * The return value is a standard Tcl result, which is TCL_OK if the
- * compilation was successful. If the command cannot be byte-compiled,
- * TCL_OUT_LINE_COMPILE is returned. If an error occurs then the
- * interpreter's result contains an error message, and TCL_ERROR is
- * returned.
+ * 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.
+ * Instructions are added to envPtr to execute the "llength" command at
+ * runtime.
*
*----------------------------------------------------------------------
*/
int
-TclCompileLlengthCmd(interp, parsePtr, envPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tcl_Parse *parsePtr; /* Points to a parse structure for the
- * command created by Tcl_ParseCommand. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
+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;
- int code;
-
- DefineLineInformation;
+ DefineLineInformation; /* TIP #280 */
if (parsePtr->numWords != 2) {
- Tcl_SetResult(interp, "wrong # args: should be \"llength list\"",
- TCL_STATIC);
return TCL_ERROR;
}
- varTokenPtr = parsePtr->tokenPtr
- + (parsePtr->tokenPtr->numComponents + 1);
+ varTokenPtr = TokenAfter(parsePtr->tokenPtr);
- if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
- /*
- * We could simply count the number of elements here and push
- * that value, but that is too rare a case to waste the code space.
- */
- TclEmitPush(TclRegisterNewLiteral(envPtr, varTokenPtr[1].start,
- varTokenPtr[1].size), envPtr);
- } else {
- SetLineInformation (1);
- code = TclCompileTokens(interp, varTokenPtr+1,
- varTokenPtr->numComponents, envPtr);
- if (code != TCL_OK) {
- return code;
- }
- }
+ CompileWord(envPtr, varTokenPtr, interp, 1);
TclEmitOpcode(INST_LIST_LENGTH, envPtr);
return TCL_OK;
}
@@ -2045,197 +2921,175 @@ TclCompileLlengthCmd(interp, parsePtr, envPtr)
* Procedure called to compile the "lset" command.
*
* Results:
- * The return value is a standard Tcl result, which is TCL_OK if
- * the compilation was successful. If the "lset" command is too
- * complex for this function, then TCL_OUT_LINE_COMPILE is returned,
- * indicating that the command should be compiled "out of line"
- * (that is, not byte-compiled). If an error occurs, TCL_ERROR is
- * returned, and the interpreter result contains an error message.
+ * 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.
+ * 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.
+ * (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
+ * 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.
+ * 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( interp, parsePtr, envPtr )
- Tcl_Interp* interp; /* Tcl interpreter for error reporting */
- Tcl_Parse* parsePtr; /* Points to a parse structure for
- * the command */
- CompileEnv* envPtr; /* Holds the resulting instructions */
+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 result; /* Status return from library calls */
-
- 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 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 */
- DefineLineInformation;
+ /*
+ * Check argument count.
+ */
- /* Check argument count */
+ if (parsePtr->numWords < 3) {
+ /*
+ * Fail at run time, not in compilation.
+ */
- if ( parsePtr->numWords < 3 ) {
- /* Fail at run time, not in compilation */
- return TCL_OUT_LINE_COMPILE;
+ 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.
+ * 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 = parsePtr->tokenPtr
- + (parsePtr->tokenPtr->numComponents + 1);
- result = TclPushVarNameWord( interp, varTokenPtr, envPtr,
- TCL_CREATE_VAR, &localIndex, &simpleVarName, &isScalar, 1);
- if (result != TCL_OK) {
- return result;
- }
+ varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ PushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR,
+ &localIndex, &simpleVarName, &isScalar, 1);
- /* Push the "index" args and the new element value. */
-
- for ( i = 2; i < parsePtr->numWords; ++i ) {
-
- /* Advance to next arg */
-
- varTokenPtr = varTokenPtr + (varTokenPtr->numComponents + 1);
-
- /* Push an arg */
+ /*
+ * Push the "index" args and the new element value.
+ */
- if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
- TclEmitPush(TclRegisterNewLiteral( envPtr, varTokenPtr[1].start,
- varTokenPtr[1].size), envPtr);
- } else {
- SetLineInformation (i);
- result = TclCompileTokens(interp, varTokenPtr+1,
- varTokenPtr->numComponents, envPtr);
- if ( result != TCL_OK ) {
- return result;
- }
- }
+ for (i=2 ; i<parsePtr->numWords ; ++i) {
+ varTokenPtr = TokenAfter(varTokenPtr);
+ CompileWord(envPtr, varTokenPtr, interp, i);
}
/*
- * Duplicate the variable name if it's been pushed.
+ * Duplicate the variable name if it's been pushed.
*/
- if ( !simpleVarName || localIndex < 0 ) {
- if ( !simpleVarName || isScalar ) {
+ if (!simpleVarName || localIndex < 0) {
+ if (!simpleVarName || isScalar) {
tempDepth = parsePtr->numWords - 2;
} else {
tempDepth = parsePtr->numWords - 1;
}
- TclEmitInstInt4( INST_OVER, tempDepth, envPtr );
+ TclEmitInstInt4(INST_OVER, tempDepth, envPtr);
}
/*
- * Duplicate an array index if one's been pushed
+ * Duplicate an array index if one's been pushed.
*/
- if ( simpleVarName && !isScalar ) {
- if ( localIndex < 0 ) {
+ if (simpleVarName && !isScalar) {
+ if (localIndex < 0) {
tempDepth = parsePtr->numWords - 1;
} else {
tempDepth = parsePtr->numWords - 2;
}
- TclEmitInstInt4( INST_OVER, tempDepth, envPtr );
+ TclEmitInstInt4(INST_OVER, tempDepth, envPtr);
}
/*
* 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 );
+ 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 );
+ 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 );
+ 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 );
+ TclEmitInstInt4(INST_LOAD_ARRAY4, localIndex, envPtr);
}
}
/*
- * Emit the correct variety of 'lset' instruction
+ * Emit the correct variety of 'lset' instruction.
*/
- if ( parsePtr->numWords == 4 ) {
- TclEmitOpcode( INST_LSET_LIST, envPtr );
+ if (parsePtr->numWords == 4) {
+ TclEmitOpcode(INST_LSET_LIST, envPtr);
} else {
- TclEmitInstInt4( INST_LSET_FLAT, (parsePtr->numWords - 1), envPtr );
+ TclEmitInstInt4(INST_LSET_FLAT, parsePtr->numWords-1, envPtr);
}
/*
- * Emit code to put the value back in the variable
+ * Emit code to put the value back in the variable.
*/
- 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 );
+ 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 );
+ 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 );
+ 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 );
+ TclEmitInstInt4(INST_STORE_ARRAY4, localIndex, envPtr);
}
}
-
- return TCL_OK;
+ return TCL_OK;
}
/*
@@ -2246,193 +3100,155 @@ TclCompileLsetCmd( interp, parsePtr, envPtr )
* Procedure called to compile the "regexp" command.
*
* Results:
- * The return value is a standard Tcl result, which is TCL_OK if
- * the compilation was successful. If the "regexp" command is too
- * complex for this function, then TCL_OUT_LINE_COMPILE is returned,
- * indicating that the command should be compiled "out of line"
- * (that is, not byte-compiled). If an error occurs, TCL_ERROR is
- * returned, and the interpreter result contains an error message.
+ * 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.
+ * Instructions are added to envPtr to execute the "regexp" command at
+ * runtime.
*
*----------------------------------------------------------------------
*/
int
-TclCompileRegexpCmd(interp, parsePtr, envPtr)
- Tcl_Interp* interp; /* Tcl interpreter for error reporting */
- Tcl_Parse* parsePtr; /* Points to a parse structure for
- * the command */
- 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, code, nocase, anchorLeft, anchorRight, start;
+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;
char *str;
-
- DefineLineInformation;
+ DefineLineInformation; /* TIP #280 */
/*
- * We are only interested in compiling simple regexp cases.
- * Currently supported compile cases are:
+ * 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_OUT_LINE_COMPILE;
+ 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.
+ * 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 = varTokenPtr + (varTokenPtr->numComponents + 1);
+ varTokenPtr = TokenAfter(varTokenPtr);
if (varTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- /* Not a simple string - punt to runtime. */
- return TCL_OUT_LINE_COMPILE;
+ /*
+ * Not a simple string, so punt to runtime.
+ */
+
+ return TCL_ERROR;
}
str = (char *) 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)) {
+ } else if ((len > 1) && (strncmp(str,"-nocase",(unsigned)len) == 0)) {
nocase = 1;
} else {
- /* Not an option we recognize. */
- return TCL_OUT_LINE_COMPILE;
+ /*
+ * Not an option we recognize.
+ */
+
+ return TCL_ERROR;
}
}
if ((parsePtr->numWords - i) != 2) {
- /* We don't support capturing to variables */
- return TCL_OUT_LINE_COMPILE;
+ /*
+ * We don't support capturing to variables.
+ */
+
+ return TCL_ERROR;
}
/*
- * Get the regexp string. If it is not a simple string, punt to runtime.
- * If it has a '-', it could be an incorrectly formed regexp command.
+ * 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 = varTokenPtr + (varTokenPtr->numComponents + 1);
- str = (char *) varTokenPtr[1].start;
- len = varTokenPtr[1].size;
- if ((varTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) || (*str == '-')) {
- return TCL_OUT_LINE_COMPILE;
- }
- if (len == 0) {
+ varTokenPtr = TokenAfter(varTokenPtr);
+
+ if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
+ Tcl_DString ds;
+
+ str = (char *) varTokenPtr[1].start;
+ len = varTokenPtr[1].size;
/*
- * The semantics of regexp are always match on re == "".
+ * If it has a '-', it could be an incorrectly formed regexp command.
*/
- TclEmitPush(TclRegisterNewLiteral(envPtr, "1", 1), envPtr);
- return TCL_OK;
- }
-
- /*
- * Make a copy of the string that is null-terminated for checks which
- * require such.
- */
- str = (char *) ckalloc((unsigned) len + 1);
- strncpy(str, varTokenPtr[1].start, (size_t) len);
- str[len] = '\0';
- start = 0;
- /*
- * Check for anchored REs (ie ^foo$), so we can use string equal if
- * possible. Do not alter the start of str so we can free it correctly.
- */
- if (str[0] == '^') {
- start++;
- anchorLeft = 1;
- } else {
- anchorLeft = 0;
- }
- if ((str[len-1] == '$') && ((len == 1) || (str[len-2] != '\\'))) {
- anchorRight = 1;
- str[--len] = '\0';
- } else {
- anchorRight = 0;
- }
+ if ((*str == '-') && !sawLast) {
+ return TCL_ERROR;
+ }
- /*
- * On the first (pattern) arg, check to see if any RE special characters
- * are in the word. If not, this is the same as 'string equal'.
- */
- if ((len > (1+start)) && (str[start] == '.') && (str[start+1] == '*')) {
- start += 2;
- anchorLeft = 0;
- }
- if ((len > (2+start)) && (str[len-3] != '\\')
- && (str[len-2] == '.') && (str[len-1] == '*')) {
- len -= 2;
- str[len] = '\0';
- anchorRight = 0;
- }
+ if (len == 0) {
+ /*
+ * The semantics of regexp are always match on re == "".
+ */
- /*
- * Don't do anything with REs with other special chars. Also check if
- * this is a bad RE (do this at the end because it can be expensive).
- * If so, let it complain at runtime.
- */
- if ((strpbrk(str + start, "*+?{}()[].\\|^$") != NULL)
- || (Tcl_RegExpCompile(NULL, str) == NULL)) {
- ckfree((char *) str);
- return TCL_OUT_LINE_COMPILE;
- }
+ PushLiteral(envPtr, "1", 1);
+ return TCL_OK;
+ }
- if (anchorLeft && anchorRight) {
- TclEmitPush(TclRegisterNewLiteral(envPtr, str+start, len-start),
- envPtr);
- } else {
/*
- * This needs to find the substring anywhere in the string, so
- * use string match and *foo*, with appropriate anchoring.
+ * Attempt to convert pattern to glob. If successful, push the
+ * converted pattern as a literal.
*/
- char *newStr = ckalloc((unsigned) len + 3);
- len -= start;
- if (anchorLeft) {
- strncpy(newStr, str + start, (size_t) len);
- } else {
- newStr[0] = '*';
- strncpy(newStr + 1, str + start, (size_t) len++);
- }
- if (!anchorRight) {
- newStr[len++] = '*';
+
+ if (TclReToGlob(NULL, varTokenPtr[1].start, len, &ds, &exact)
+ == TCL_OK) {
+ simple = 1;
+ PushLiteral(envPtr, Tcl_DStringValue(&ds),Tcl_DStringLength(&ds));
+ Tcl_DStringFree(&ds);
}
- newStr[len] = '\0';
- TclEmitPush(TclRegisterNewLiteral(envPtr, newStr, len), envPtr);
- ckfree((char *) newStr);
}
- ckfree((char *) str);
+
+ if (!simple) {
+ CompileWord(envPtr, varTokenPtr, interp, parsePtr->numWords-2);
+ }
/*
- * Push the string arg
+ * Push the string arg.
*/
- varTokenPtr = varTokenPtr + (varTokenPtr->numComponents + 1);
- if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
- TclEmitPush(TclRegisterNewLiteral(envPtr,
- varTokenPtr[1].start, varTokenPtr[1].size), envPtr);
- } else {
- SetLineInformation (parsePtr->numWords-1);
- code = TclCompileTokens(interp, varTokenPtr+1,
- varTokenPtr->numComponents, envPtr);
- if (code != TCL_OK) {
- return code;
- }
- }
- if (anchorLeft && anchorRight && !nocase) {
- TclEmitOpcode(INST_STR_EQ, envPtr);
+ 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 {
- TclEmitInstInt1(INST_STR_MATCH, nocase, envPtr);
+ /*
+ * 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;
@@ -2446,117 +3262,191 @@ TclCompileRegexpCmd(interp, parsePtr, envPtr)
* Procedure called to compile the "return" command.
*
* Results:
- * The return value is a standard Tcl result, which is TCL_OK if the
- * compilation was successful. If the particular return command is
- * too complex for this function (ie, return with any flags like "-code"
- * or "-errorinfo"), TCL_OUT_LINE_COMPILE is returned, indicating that
- * the command should be compiled "out of line" (eg, not byte compiled).
- * If an error occurs then the interpreter's result contains a standard
- * error message.
+ * 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.
+ * Instructions are added to envPtr to execute the "return" command at
+ * runtime.
*
*----------------------------------------------------------------------
*/
int
-TclCompileReturnCmd(interp, parsePtr, envPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tcl_Parse *parsePtr; /* Points to a parse structure for the
- * command created by Tcl_ParseCommand. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
+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. */
{
- Tcl_Token *varTokenPtr;
- int code;
- int index = envPtr->exceptArrayNext - 1;
-
- DefineLineInformation;
+ /*
+ * 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 */
/*
- * If we're not in a procedure, don't compile.
+ * 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 (envPtr->procPtr == NULL) {
- return TCL_OUT_LINE_COMPILE;
+ 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;
}
/*
- * Look back through the ExceptionRanges of the current CompileEnv,
- * from exceptArrayPtr[(exceptArrayNext - 1)] down to
- * exceptArrayPtr[0] to see if any of them is an enclosing [catch].
- * If there's an enclosing [catch], don't compile.
+ * Allocate some working space.
+ */
+
+ objv = (Tcl_Obj **) 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.
*/
- while (index >= 0) {
- ExceptionRange range = envPtr->exceptArrayPtr[index];
- if ((range.type == CATCH_EXCEPTION_RANGE)
- && (range.catchOffset == -1)) {
- return TCL_OUT_LINE_COMPILE;
+ 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;
}
- index--;
+ 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.
+ */
- switch (parsePtr->numWords) {
- case 1: {
- /*
- * Simple case: [return]
- * Just push the literal string "".
- */
- TclEmitPush(TclRegisterNewLiteral(envPtr, "", 0), envPtr);
- break;
- }
- case 2: {
- /*
- * More complex cases:
- * [return "foo"]
- * [return $value]
- * [return [otherCmd]]
- */
- varTokenPtr = parsePtr->tokenPtr
- + (parsePtr->tokenPtr->numComponents + 1);
- if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
- /*
- * [return "foo"] case: the parse token is a simple word,
- * so just push it.
- */
- TclEmitPush(TclRegisterNewLiteral(envPtr, varTokenPtr[1].start,
- varTokenPtr[1].size), envPtr);
- } else {
- /*
- * Parse token is more complex, so compile it; this handles the
- * variable reference and nested command cases. If the
- * parse token can be byte-compiled, then this instance of
- * "return" will be byte-compiled; otherwise it will be
- * out line compiled.
- */
- SetLineInformation (1);
- code = TclCompileTokens(interp, varTokenPtr+1,
- varTokenPtr->numComponents, envPtr);
- if (code != TCL_OK) {
- return code;
- }
+ 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.
+ */
+
+ 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;
}
- break;
+ index--;
}
- default: {
+ if (!enclosingCatch) {
/*
- * Most complex return cases: everything else, including
- * [return -code error], etc.
+ * ... and there is no enclosing catch. Issue the maximally
+ * efficient exit instruction.
*/
- return TCL_OUT_LINE_COMPILE;
+
+ 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;
+ }
+
/*
- * The INST_DONE opcode actually causes the branching out of the
- * subroutine, and takes the top stack item as the return result
- * (which is why we pushed the value above).
+ * 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.
*/
- TclEmitOpcode(INST_DONE, envPtr);
+
+ 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);
+
+ TclEmitPush(TclRegisterNewLiteral(envPtr, bytes, numBytes), envPtr);
+ CompileReturnInternal(envPtr, INST_SYNTAX, TCL_ERROR, 0,
+ Tcl_GetReturnOptions(interp, TCL_ERROR));
+}
/*
*----------------------------------------------------------------------
@@ -2566,77 +3456,54 @@ TclCompileReturnCmd(interp, parsePtr, envPtr)
* Procedure called to compile the "set" command.
*
* Results:
- * The return value is a standard Tcl result, which is normally TCL_OK
- * unless there was an error while parsing string. If an error occurs
- * then the interpreter's result contains a standard error message. If
- * compilation fails because the set command requires a second level of
- * substitutions, TCL_OUT_LINE_COMPILE is returned indicating that the
- * set command should be compiled "out of line" by emitting code to
- * invoke its command procedure (Tcl_SetCmd) at runtime.
+ * 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 runtime.
+ * Instructions are added to envPtr to execute the "set" command at
+ * runtime.
*
*----------------------------------------------------------------------
*/
int
-TclCompileSetCmd(interp, parsePtr, envPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tcl_Parse *parsePtr; /* Points to a parse structure for the
- * command created by Tcl_ParseCommand. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
+TclCompileSetCmd(
+ 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 isAssignment, isScalar, simpleVarName, localIndex, numWords;
- int code = TCL_OK;
-
- DefineLineInformation;
+ DefineLineInformation; /* TIP #280 */
numWords = parsePtr->numWords;
if ((numWords != 2) && (numWords != 3)) {
- Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "wrong # args: should be \"set varName ?newValue?\"", -1);
- return TCL_ERROR;
+ return TCL_ERROR;
}
isAssignment = (numWords == 3);
/*
- * 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.
+ * 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 = parsePtr->tokenPtr
- + (parsePtr->tokenPtr->numComponents + 1);
-
- code = TclPushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR,
- &localIndex, &simpleVarName, &isScalar, 1);
- if (code != TCL_OK) {
- goto done;
- }
+ varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ PushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR,
+ &localIndex, &simpleVarName, &isScalar, 1);
/*
* If we are doing an assignment, push the new value.
*/
if (isAssignment) {
- valueTokenPtr = varTokenPtr + (varTokenPtr->numComponents + 1);
- if (valueTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
- TclEmitPush(TclRegisterNewLiteral(envPtr, valueTokenPtr[1].start,
- valueTokenPtr[1].size), envPtr);
- } else {
- SetLineInformation (2);
- code = TclCompileTokens(interp, valueTokenPtr+1,
- valueTokenPtr->numComponents, envPtr);
- if (code != TCL_OK) {
- goto done;
- }
- }
+ valueTokenPtr = TokenAfter(varTokenPtr);
+ CompileWord(envPtr, valueTokenPtr, interp, 2);
}
/*
@@ -2645,351 +3512,1158 @@ TclCompileSetCmd(interp, parsePtr, envPtr)
if (simpleVarName) {
if (isScalar) {
- if (localIndex >= 0) {
- if (localIndex <= 255) {
- TclEmitInstInt1((isAssignment?
- INST_STORE_SCALAR1 : INST_LOAD_SCALAR1),
- localIndex, envPtr);
- } else {
- TclEmitInstInt4((isAssignment?
- INST_STORE_SCALAR4 : INST_LOAD_SCALAR4),
- localIndex, envPtr);
- }
- } else {
+ if (localIndex < 0) {
TclEmitOpcode((isAssignment?
- INST_STORE_SCALAR_STK : INST_LOAD_SCALAR_STK), envPtr);
+ INST_STORE_SCALAR_STK : INST_LOAD_SCALAR_STK), envPtr);
+ } else if (localIndex <= 255) {
+ TclEmitInstInt1((isAssignment?
+ INST_STORE_SCALAR1 : INST_LOAD_SCALAR1),
+ localIndex, envPtr);
+ } else {
+ TclEmitInstInt4((isAssignment?
+ INST_STORE_SCALAR4 : INST_LOAD_SCALAR4),
+ localIndex, envPtr);
}
} else {
- if (localIndex >= 0) {
- if (localIndex <= 255) {
- TclEmitInstInt1((isAssignment?
- INST_STORE_ARRAY1 : INST_LOAD_ARRAY1),
- localIndex, envPtr);
- } else {
- TclEmitInstInt4((isAssignment?
- INST_STORE_ARRAY4 : INST_LOAD_ARRAY4),
- localIndex, envPtr);
- }
- } else {
+ if (localIndex < 0) {
TclEmitOpcode((isAssignment?
- INST_STORE_ARRAY_STK : INST_LOAD_ARRAY_STK), envPtr);
+ INST_STORE_ARRAY_STK : INST_LOAD_ARRAY_STK), envPtr);
+ } else if (localIndex <= 255) {
+ TclEmitInstInt1((isAssignment?
+ INST_STORE_ARRAY1 : INST_LOAD_ARRAY1),
+ localIndex, envPtr);
+ } else {
+ TclEmitInstInt4((isAssignment?
+ INST_STORE_ARRAY4 : INST_LOAD_ARRAY4),
+ localIndex, envPtr);
}
}
} else {
TclEmitOpcode((isAssignment? INST_STORE_STK : INST_LOAD_STK), envPtr);
}
-
- done:
- return code;
+
+ return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
- * TclCompileStringCmd --
+ * TclCompileStringCmpCmd --
*
- * Procedure called to compile the "string" command.
+ * Procedure called to compile the simplest and most common form of the
+ * "string compare" command.
*
* Results:
- * The return value is a standard Tcl result, which is TCL_OK if the
- * compilation was successful. If the command cannot be byte-compiled,
- * TCL_OUT_LINE_COMPILE is returned. If an error occurs then the
- * interpreter's result contains an error message, and TCL_ERROR is
- * returned.
+ * 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" command
+ * Instructions are added to envPtr to execute the "string compare"
+ * command at runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileStringCmpCmd(
+ 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);
+ 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
-TclCompileStringCmd(interp, parsePtr, envPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tcl_Parse *parsePtr; /* Points to a parse structure for the
- * command created by Tcl_ParseCommand. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
-{
- Tcl_Token *opTokenPtr, *varTokenPtr;
- Tcl_Obj *opObj;
- int index;
- int code;
-
- static CONST char *options[] = {
- "bytelength", "compare", "equal", "first",
- "index", "is", "last", "length",
- "map", "match", "range", "repeat",
- "replace", "tolower", "toupper", "totitle",
- "trim", "trimleft", "trimright",
- "wordend", "wordstart", (char *) NULL
- };
- enum options {
- STR_BYTELENGTH, STR_COMPARE, STR_EQUAL, STR_FIRST,
- STR_INDEX, STR_IS, STR_LAST, STR_LENGTH,
- STR_MAP, STR_MATCH, STR_RANGE, STR_REPEAT,
- STR_REPLACE, STR_TOLOWER, STR_TOUPPER, STR_TOTITLE,
- STR_TRIM, STR_TRIMLEFT, STR_TRIMRIGHT,
- STR_WORDEND, STR_WORDSTART
- };
-
- DefineLineInformation;
+TclCompileStringEqualCmd(
+ 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) {
- /* Fail at run time, not in compilation */
- return TCL_OUT_LINE_COMPILE;
+ /*
+ * We don't support any flags; the bytecode isn't that sophisticated.
+ */
+
+ if (parsePtr->numWords != 3) {
+ return TCL_ERROR;
}
- opTokenPtr = parsePtr->tokenPtr
- + (parsePtr->tokenPtr->numComponents + 1);
- opObj = Tcl_NewStringObj(opTokenPtr->start, opTokenPtr->size);
- if (Tcl_GetIndexFromObj(interp, opObj, options, "option", 0,
- &index) != TCL_OK) {
- Tcl_DecrRefCount(opObj);
- Tcl_ResetResult(interp);
- return TCL_OUT_LINE_COMPILE;
- }
- Tcl_DecrRefCount(opObj);
-
- varTokenPtr = opTokenPtr + (opTokenPtr->numComponents + 1);
-
- switch ((enum options) index) {
- case STR_BYTELENGTH:
- case STR_FIRST:
- case STR_IS:
- case STR_LAST:
- case STR_MAP:
- case STR_RANGE:
- case STR_REPEAT:
- case STR_REPLACE:
- case STR_TOLOWER:
- case STR_TOUPPER:
- case STR_TOTITLE:
- case STR_TRIM:
- case STR_TRIMLEFT:
- case STR_TRIMRIGHT:
- case STR_WORDEND:
- case STR_WORDSTART:
+ /*
+ * 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);
+ 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
+TclCompileStringIndexCmd(
+ 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 != 3) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Push the two operands onto the stack and then the index operation.
+ */
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 1);
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 2);
+ 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
+TclCompileStringMatchCmd(
+ 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;
+ int i, length, exactMatch = 0, nocase = 0;
+ const char *str;
+
+ if (parsePtr->numWords < 3 || parsePtr->numWords > 4) {
+ return TCL_ERROR;
+ }
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+ /*
+ * Check if we have a -nocase flag.
+ */
+
+ if (parsePtr->numWords == 4) {
+ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+ return TCL_ERROR;
+ }
+ str = tokenPtr[1].start;
+ length = tokenPtr[1].size;
+ if ((length <= 1) || strncmp(str, "-nocase", (size_t) length)) {
+ /*
+ * Fail at run time, not in compilation.
+ */
+
+ return TCL_ERROR;
+ }
+ nocase = 1;
+ tokenPtr = TokenAfter(tokenPtr);
+ }
+
+ /*
+ * Push the strings to match against each other.
+ */
+
+ for (i = 0; i < 2; i++) {
+ if (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
+ str = tokenPtr[1].start;
+ length = tokenPtr[1].size;
+ if (!nocase && (i == 0)) {
+ /*
+ * Trivial matches can be done by 'string equal'. If -nocase
+ * was specified, we can't do this because INST_STR_EQ has no
+ * support for nocase.
+ */
+
+ Tcl_Obj *copy = Tcl_NewStringObj(str, length);
+
+ Tcl_IncrRefCount(copy);
+ exactMatch = TclMatchIsTrivial(TclGetString(copy));
+ TclDecrRefCount(copy);
+ }
+ PushLiteral(envPtr, str, length);
+ } else {
+ SetLineInformation (i+1+nocase);
+ CompileTokens(envPtr, tokenPtr, interp);
+ }
+ tokenPtr = TokenAfter(tokenPtr);
+ }
+
+ /*
+ * Push the matcher.
+ */
+
+ if (exactMatch) {
+ TclEmitOpcode(INST_STR_EQ, envPtr);
+ } else {
+ TclEmitInstInt1(INST_STR_MATCH, nocase, envPtr);
+ }
+ 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(
+ 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 TCL_ERROR;
+ }
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ if (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
+ /*
+ * Here someone is asking for the length of a static string. Just push
+ * the actual character (not byte) length.
+ */
+
+ char buf[TCL_INTEGER_SPACE];
+ int len = Tcl_NumUtfChars(tokenPtr[1].start, tokenPtr[1].size);
+
+ len = sprintf(buf, "%d", len);
+ PushLiteral(envPtr, buf, len);
+ } else {
+ SetLineInformation (1);
+ CompileTokens(envPtr, tokenPtr, interp);
+ TclEmitOpcode(INST_STR_LEN, envPtr);
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileSwitchCmd --
+ *
+ * Procedure called to compile the "switch" command.
+ *
+ * Results:
+ * Returns TCL_OK for successful compile, or TCL_ERROR to defer
+ * evaluation to runtime (either when it is too complex to get the
+ * semantics right, or when we know for sure that it is an error but need
+ * the error to happen at the right time).
+ *
+ * Side effects:
+ * Instructions are added to envPtr to execute the "switch" command at
+ * runtime.
+ *
+ * FIXME:
+ * Stack depths are probably not calculated correctly.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileSwitchCmd(
+ 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; /* Pointer to tokens in command. */
+ int numWords; /* Number of words in command. */
+
+ Tcl_Token *valueTokenPtr; /* Token for the value to switch on. */
+ enum {Switch_Exact, Switch_Glob, Switch_Regexp} mode;
+ /* What kind of switch are we doing? */
+
+ Tcl_Token *bodyTokenArray; /* Array of real pattern list items. */
+ Tcl_Token **bodyToken; /* Array of pointers to pattern list items. */
+ int *bodyLines; /* Array of line numbers for body list
+ * items. */
+ int** bodyNext;
+ int foundDefault; /* Flag to indicate whether a "default" clause
+ * is present. */
+
+ JumpFixup *fixupArray; /* Array of forward-jump fixup records. */
+ int *fixupTargetArray; /* Array of places for fixups to point at. */
+ int fixupCount; /* Number of places to fix up. */
+ int contFixIndex; /* Where the first of the jumps due to a group
+ * of continuation bodies starts, or -1 if
+ * there aren't any. */
+ int contFixCount; /* Number of continuation bodies pointing to
+ * the current (or next) real body. */
+
+ int savedStackDepth = envPtr->currStackDepth;
+ int noCase; /* Has the -nocase flag been given? */
+ int foundMode = 0; /* Have we seen a mode flag yet? */
+ int i, valueIndex;
+ DefineLineInformation; /* TIP #280 */
+ int* clNext = envPtr->clNext;
+
+ /*
+ * Only handle the following versions:
+ * switch ?--? word {pattern body ...}
+ * switch -exact ?--? word {pattern body ...}
+ * switch -glob ?--? word {pattern body ...}
+ * switch -regexp ?--? word {pattern body ...}
+ * switch -- word simpleWordPattern simpleWordBody ...
+ * switch -exact -- word simpleWordPattern simpleWordBody ...
+ * switch -glob -- word simpleWordPattern simpleWordBody ...
+ * switch -regexp -- word simpleWordPattern simpleWordBody ...
+ * When the mode is -glob, can also handle a -nocase flag.
+ *
+ * First off, we don't care how the command's word was generated; we're
+ * compiling it anyway! So skip it...
+ */
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ valueIndex = 1;
+ numWords = parsePtr->numWords-1;
+
+ /*
+ * Check for options.
+ */
+
+ noCase = 0;
+ mode = Switch_Exact;
+ if (numWords == 2) {
+ /*
+ * There's just the switch value and the bodies list. In that case, we
+ * can skip all option parsing and move on to consider switch values
+ * and the body list.
+ */
+
+ goto finishedOptionParse;
+ }
+
+ /*
+ * There must be at least one option, --, because without that there is no
+ * way to statically avoid the problems you get from strings-to-be-matched
+ * that start with a - (the interpreted code falls apart if it encounters
+ * them, so we punt if we *might* encounter them as that is the easiest
+ * way of emulating the behaviour).
+ */
+
+ for (; numWords>=3 ; tokenPtr=TokenAfter(tokenPtr),numWords--) {
+ register unsigned size = tokenPtr[1].size;
+ register const char *chrs = tokenPtr[1].start;
+
+ /*
+ * We only process literal options, and we assume that -e, -g and -n
+ * are unique prefixes of -exact, -glob and -nocase respectively (true
+ * at time of writing). Note that -exact and -glob may only be given
+ * at most once or we bail out (error case).
+ */
+
+ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD || size < 2) {
+ return TCL_ERROR;
+ }
+
+ if ((size <= 6) && !memcmp(chrs, "-exact", size)) {
+ if (foundMode) {
+ return TCL_ERROR;
+ }
+ mode = Switch_Exact;
+ foundMode = 1;
+ valueIndex++;
+ continue;
+ } else if ((size <= 5) && !memcmp(chrs, "-glob", size)) {
+ if (foundMode) {
+ return TCL_ERROR;
+ }
+ mode = Switch_Glob;
+ foundMode = 1;
+ valueIndex++;
+ continue;
+ } else if ((size <= 7) && !memcmp(chrs, "-regexp", size)) {
+ if (foundMode) {
+ return TCL_ERROR;
+ }
+ mode = Switch_Regexp;
+ foundMode = 1;
+ valueIndex++;
+ continue;
+ } else if ((size <= 7) && !memcmp(chrs, "-nocase", size)) {
+ noCase = 1;
+ valueIndex++;
+ continue;
+ } else if ((size == 2) && !memcmp(chrs, "--", 2)) {
+ valueIndex++;
+ break;
+ }
+
+ /*
+ * The switch command has many flags we cannot compile at all (e.g.
+ * all the RE-related ones) which we must have encountered. Either
+ * that or we have run off the end. The action here is the same: punt
+ * to interpreted version.
+ */
+
+ return TCL_ERROR;
+ }
+ if (numWords < 3) {
+ return TCL_ERROR;
+ }
+ tokenPtr = TokenAfter(tokenPtr);
+ numWords--;
+ if (noCase && (mode == Switch_Exact)) {
+ /*
+ * Can't compile this case; no opcode for case-insensitive equality!
+ */
+
+ return TCL_ERROR;
+ }
+
+ /*
+ * The value to test against is going to always get pushed on the stack.
+ * But not yet; we need to verify that the rest of the command is
+ * compilable too.
+ */
+
+ finishedOptionParse:
+ valueTokenPtr = tokenPtr;
+ /* For valueIndex, see previous loop. */
+ tokenPtr = TokenAfter(tokenPtr);
+ numWords--;
+
+ /*
+ * Build an array of tokens for the matcher terms and script bodies. Note
+ * that in the case of the quoted bodies, this is tricky as we cannot use
+ * copies of the string from the input token for the generated tokens (it
+ * causes a crash during exception handling). When multiple tokens are
+ * available at this point, this is pretty easy.
+ */
+
+ if (numWords == 1) {
+ CONST char *bytes;
+ int maxLen, numBytes;
+ int bline; /* TIP #280: line of the pattern/action list,
+ * and start of list for when tracking the
+ * location. This list comes immediately after
+ * the value we switch on. */
+
+ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+ return TCL_ERROR;
+ }
+ bytes = tokenPtr[1].start;
+ numBytes = tokenPtr[1].size;
+
+ /* Allocate enough space to work in. */
+ maxLen = TclMaxListLength(bytes, numBytes, NULL);
+ if (maxLen < 2) {
+ return TCL_ERROR;
+ }
+ bodyTokenArray = (Tcl_Token *) ckalloc(sizeof(Tcl_Token) * maxLen);
+ bodyToken = (Tcl_Token **) ckalloc(sizeof(Tcl_Token *) * maxLen);
+ bodyLines = (int *) ckalloc(sizeof(int) * maxLen);
+ bodyNext = (int **) ckalloc(sizeof(int*) * maxLen);
+
+ bline = mapPtr->loc[eclIndex].line[valueIndex+1];
+ numWords = 0;
+
+ while (numBytes > 0) {
+ CONST char *prevBytes = bytes;
+ int literal;
+
+ 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 *) bodyNext);
+ return TCL_ERROR;
+ }
+
+ bodyTokenArray[numWords].type = TCL_TOKEN_TEXT;
+ bodyTokenArray[numWords].numComponents = 0;
+ bodyToken[numWords] = bodyTokenArray + numWords;
+
/*
- * All other cases: compile out of line.
+ * TIP #280: Now determine the line the list element starts on
+ * (there is no need to do it earlier, due to the possibility of
+ * aborting, see above).
*/
- return TCL_OUT_LINE_COMPILE;
- case STR_COMPARE:
- case STR_EQUAL: {
- int i;
+ TclAdvanceLines(&bline, prevBytes, bodyTokenArray[numWords].start);
+ TclAdvanceContinuations (&bline, &clNext,
+ bodyTokenArray[numWords].start - envPtr->source);
+ bodyLines[numWords] = bline;
+ bodyNext[numWords] = clNext;
+ TclAdvanceLines(&bline, bodyTokenArray[numWords].start, bytes);
+ TclAdvanceContinuations (&bline, &clNext, bytes - envPtr->source);
+
+ numBytes -= (bytes - prevBytes);
+ numWords++;
+ }
+ if (numWords % 2) {
+ goto abort;
+ }
+ } else if (numWords % 2 || numWords == 0) {
+ /*
+ * Odd number of words (>1) available, or no words at all available.
+ * Both are error cases, so punt and let the interpreted-version
+ * generate the error message. Note that the second case probably
+ * should get caught earlier, but it's easy to check here again anyway
+ * because it'd cause a nasty crash otherwise.
+ */
+
+ return TCL_ERROR;
+ } else {
+ /*
+ * Multi-word definition of patterns & actions.
+ */
+
+ bodyToken = (Tcl_Token **) ckalloc(sizeof(Tcl_Token *) * numWords);
+ bodyLines = (int *) ckalloc(sizeof(int) * numWords);
+ bodyNext = (int **) ckalloc(sizeof(int*) * numWords);
+ bodyTokenArray = NULL;
+ for (i=0 ; i<numWords ; i++) {
/*
- * If there are any flags to the command, we can't byte compile it
- * because the INST_STR_EQ bytecode doesn't support flags.
+ * We only handle the very simplest case. Anything more complex is
+ * a good reason to go to the interpreted case anyway due to
+ * traces, etc.
*/
- if (parsePtr->numWords != 4) {
- return TCL_OUT_LINE_COMPILE;
+ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+ ckfree((char *) bodyToken);
+ ckfree((char *) bodyLines);
+ ckfree((char *) bodyNext);
+ return TCL_ERROR;
}
+ bodyToken[i] = tokenPtr+1;
/*
- * Push the two operands onto the stack.
+ * TIP #280: Copy line information from regular cmd info.
*/
- for (i = 0; i < 2; i++) {
- if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
- TclEmitPush(TclRegisterNewLiteral(envPtr,
- varTokenPtr[1].start, varTokenPtr[1].size), envPtr);
- } else {
- SetLineInformation (i);
- code = TclCompileTokens(interp, varTokenPtr+1,
- varTokenPtr->numComponents, envPtr);
- if (code != TCL_OK) {
- return code;
- }
- }
- varTokenPtr = varTokenPtr + (varTokenPtr->numComponents + 1);
- }
+ bodyLines[i] = mapPtr->loc[eclIndex].line[valueIndex+1+i];
+ bodyNext[i] = mapPtr->loc[eclIndex].next[valueIndex+1+i];
+ tokenPtr = TokenAfter(tokenPtr);
+ }
+ }
- TclEmitOpcode(((((enum options) index) == STR_COMPARE) ?
- INST_STR_CMP : INST_STR_EQ), envPtr);
- return TCL_OK;
+ /*
+ * Fall back to interpreted if the last body is a continuation (it's
+ * illegal, but this makes the error happen at the right time).
+ */
+
+ if (bodyToken[numWords-1]->size == 1 &&
+ bodyToken[numWords-1]->start[0] == '-') {
+ ckfree((char *) bodyToken);
+ ckfree((char *) bodyLines);
+ ckfree((char *) bodyNext);
+ if (bodyTokenArray != NULL) {
+ ckfree((char *) bodyTokenArray);
}
- case STR_INDEX: {
- int i;
+ return TCL_ERROR;
+ }
- if (parsePtr->numWords != 4) {
- /* Fail at run time, not in compilation */
- return TCL_OUT_LINE_COMPILE;
- }
+ /*
+ * Now we commit to generating code; the parsing stage per se is done.
+ * First, we push the value we're matching against on the stack.
+ */
+
+ SetLineInformation (valueIndex);
+ CompileTokens(envPtr, valueTokenPtr, interp);
+
+ /*
+ * Check if we can generate a jump table, since if so that's faster than
+ * doing an explicit compare with each body. Note that we're definitely
+ * over-conservative with determining whether we can do the jump table,
+ * but it handles the most common case well enough.
+ */
+
+ if (mode == Switch_Exact) {
+ JumptableInfo *jtPtr;
+ int infoIndex, isNew, *finalFixups, numRealBodies = 0, jumpLocation;
+ int mustGenerate, jumpToDefault;
+ Tcl_DString buffer;
+ Tcl_HashEntry *hPtr;
+ /*
+ * 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 table itself is independent of any invokation of the
+ * bytecode, and as such is stored in an auxData block.
+ *
+ * Start by allocating the jump table itself, plus some workspace.
+ */
+
+ jtPtr = (JumptableInfo *) ckalloc(sizeof(JumptableInfo));
+ Tcl_InitHashTable(&jtPtr->hashTable, TCL_STRING_KEYS);
+ infoIndex = TclCreateAuxData(jtPtr, &tclJumptableInfoType, envPtr);
+ finalFixups = (int *) ckalloc(sizeof(int) * (numWords/2));
+ foundDefault = 0;
+ mustGenerate = 1;
+
+ /*
+ * Next, issue the instruction to do the jump, together with what we
+ * want to do if things do not work out (jump to either the default
+ * clause or the "default" default, which just sets the result to
+ * empty). Note that we will come back and rewrite the jump's offset
+ * parameter when we know what it should be, and that all jumps we
+ * issue are of the wide kind because that makes the code much easier
+ * to debug!
+ */
+
+ jumpLocation = CurrentOffset(envPtr);
+ TclEmitInstInt4(INST_JUMP_TABLE, infoIndex, envPtr);
+ jumpToDefault = CurrentOffset(envPtr);
+ TclEmitInstInt4(INST_JUMP4, 0, envPtr);
+
+ for (i=0 ; i<numWords ; i+=2) {
/*
- * Push the two operands onto the stack.
+ * For each arm, we must first work out what to do with the match
+ * term.
*/
- for (i = 0; i < 2; i++) {
- if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
- TclEmitPush(TclRegisterNewLiteral(envPtr,
- varTokenPtr[1].start, varTokenPtr[1].size), envPtr);
- } else {
- SetLineInformation (i);
- code = TclCompileTokens(interp, varTokenPtr+1,
- varTokenPtr->numComponents, envPtr);
- if (code != TCL_OK) {
- return code;
- }
+ if (i!=numWords-2 || bodyToken[numWords-2]->size != 7 ||
+ memcmp(bodyToken[numWords-2]->start, "default", 7)) {
+ /*
+ * This is not a default clause, so insert the current
+ * location as a target in the jump table (assuming it isn't
+ * already there, which would indicate that this clause is
+ * probably masked by an earlier one). Note that we use a
+ * Tcl_DString here simply because the hash API does not let
+ * us specify the string length.
+ */
+
+ Tcl_DStringInit(&buffer);
+ Tcl_DStringAppend(&buffer, bodyToken[i]->start,
+ bodyToken[i]->size);
+ hPtr = Tcl_CreateHashEntry(&jtPtr->hashTable,
+ Tcl_DStringValue(&buffer), &isNew);
+ if (isNew) {
+ /*
+ * First time we've encountered this match clause, so it
+ * must point to here.
+ */
+
+ Tcl_SetHashValue(hPtr, (ClientData)
+ (CurrentOffset(envPtr) - jumpLocation));
}
- varTokenPtr = varTokenPtr + (varTokenPtr->numComponents + 1);
+ Tcl_DStringFree(&buffer);
+ } else {
+ /*
+ * This is a default clause, so patch up the fallthrough from
+ * the INST_JUMP_TABLE instruction to here.
+ */
+
+ foundDefault = 1;
+ isNew = 1;
+ TclStoreInt4AtPtr(CurrentOffset(envPtr)-jumpToDefault,
+ envPtr->codeStart+jumpToDefault+1);
}
- TclEmitOpcode(INST_STR_INDEX, envPtr);
- return TCL_OK;
- }
- case STR_LENGTH: {
- if (parsePtr->numWords != 3) {
- /* Fail at run time, not in compilation */
- return TCL_OUT_LINE_COMPILE;
+ /*
+ * Now, for each arm we must deal with the body of the clause.
+ *
+ * If this is a continuation body (never true of a final clause,
+ * whether default or not) we're done because the next jump target
+ * will also point here, so we advance to the next clause.
+ */
+
+ if (bodyToken[i+1]->size == 1 && bodyToken[i+1]->start[0] == '-') {
+ mustGenerate = 1;
+ continue;
+ }
+
+ /*
+ * Also skip this arm if its only match clause is masked. (We
+ * could probably be more aggressive about this, but that would be
+ * much more difficult to get right.)
+ */
+
+ if (!isNew && !mustGenerate) {
+ continue;
}
+ mustGenerate = 0;
+
+ /*
+ * Compile the body of the arm.
+ */
+
+ envPtr->line = bodyLines[i+1]; /* TIP #280 */
+ envPtr->clNext = bodyNext[i+1]; /* TIP #280 */
+ TclCompileCmdWord(interp, bodyToken[i+1], 1, envPtr);
+
+ /*
+ * Compile a jump in to the end of the command if this body is
+ * anything other than a user-supplied default arm (to either skip
+ * over the remaining bodies or the code that generates an empty
+ * result).
+ */
+
+ if (i+2 < numWords || !foundDefault) {
+ finalFixups[numRealBodies++] = CurrentOffset(envPtr);
- if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
/*
- * Here someone is asking for the length of a static string.
- * Just push the actual character (not byte) length.
+ * Easier by far to issue this jump as a fixed-width jump.
+ * Otherwise we'd need to do a lot more (and more awkward)
+ * rewriting when we fixed this all up.
*/
- char buf[TCL_INTEGER_SPACE];
- int len = Tcl_NumUtfChars(varTokenPtr[1].start,
- varTokenPtr[1].size);
- len = sprintf(buf, "%d", len);
- TclEmitPush(TclRegisterNewLiteral(envPtr, buf, len), envPtr);
- return TCL_OK;
- } else {
- SetLineInformation (2);
- code = TclCompileTokens(interp, varTokenPtr+1,
- varTokenPtr->numComponents, envPtr);
- if (code != TCL_OK) {
- return code;
- }
+
+ TclEmitInstInt4(INST_JUMP4, 0, envPtr);
}
- TclEmitOpcode(INST_STR_LEN, envPtr);
- return TCL_OK;
}
- case STR_MATCH: {
- int i, length, exactMatch = 0, nocase = 0;
- CONST char *str;
- if (parsePtr->numWords < 4 || parsePtr->numWords > 5) {
- /* Fail at run time, not in compilation */
- return TCL_OUT_LINE_COMPILE;
- }
+ /*
+ * We're at the end. If we've not already done so through the
+ * processing of a user-supplied default clause, add in a "default"
+ * default clause now.
+ */
- if (parsePtr->numWords == 5) {
- if (varTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- return TCL_OUT_LINE_COMPILE;
- }
- str = varTokenPtr[1].start;
- length = varTokenPtr[1].size;
- if ((length > 1) &&
- strncmp(str, "-nocase", (size_t) length) == 0) {
- nocase = 1;
- } else {
- /* Fail at run time, not in compilation */
- return TCL_OUT_LINE_COMPILE;
- }
- varTokenPtr = varTokenPtr + (varTokenPtr->numComponents + 1);
- }
+ if (!foundDefault) {
+ TclStoreInt4AtPtr(CurrentOffset(envPtr)-jumpToDefault,
+ envPtr->codeStart+jumpToDefault+1);
+ PushLiteral(envPtr, "", 0);
+ }
- for (i = 0; i < 2; i++) {
- if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
- str = varTokenPtr[1].start;
- length = varTokenPtr[1].size;
- if (!nocase && (i == 0)) {
+ /*
+ * No more instructions to be issued; everything that needs to jump to
+ * the end of the command is fixed up at this point.
+ */
+
+ for (i=0 ; i<numRealBodies ; i++) {
+ TclStoreInt4AtPtr(CurrentOffset(envPtr)-finalFixups[i],
+ envPtr->codeStart+finalFixups[i]+1);
+ }
+
+ /*
+ * Clean up all our temporary space and return.
+ */
+
+ ckfree((char *) finalFixups);
+ ckfree((char *) bodyToken);
+ ckfree((char *) bodyLines);
+ ckfree((char *) bodyNext);
+ if (bodyTokenArray != NULL) {
+ ckfree((char *) bodyTokenArray);
+ }
+ return TCL_OK;
+ }
+
+ /*
+ * Generate a test for each arm.
+ */
+
+ contFixIndex = -1;
+ contFixCount = 0;
+ fixupArray = (JumpFixup *) ckalloc(sizeof(JumpFixup) * numWords);
+ fixupTargetArray = (int *) ckalloc(sizeof(int) * numWords);
+ memset(fixupTargetArray, 0, numWords * sizeof(int));
+ fixupCount = 0;
+ foundDefault = 0;
+ for (i=0 ; i<numWords ; i+=2) {
+ int nextArmFixupIndex = -1;
+
+ envPtr->currStackDepth = savedStackDepth + 1;
+ if (i!=numWords-2 || bodyToken[numWords-2]->size != 7 ||
+ memcmp(bodyToken[numWords-2]->start, "default", 7)) {
+ /*
+ * Generate the test for the arm.
+ */
+
+ switch (mode) {
+ case Switch_Exact:
+ TclEmitOpcode(INST_DUP, envPtr);
+ TclCompileTokens(interp, bodyToken[i], 1, envPtr);
+ TclEmitOpcode(INST_STR_EQ, envPtr);
+ break;
+ case Switch_Glob:
+ TclCompileTokens(interp, bodyToken[i], 1, envPtr);
+ TclEmitInstInt4(INST_OVER, 1, envPtr);
+ TclEmitInstInt1(INST_STR_MATCH, noCase, envPtr);
+ break;
+ case Switch_Regexp: {
+ int simple = 0, exact = 0;
+
+ /*
+ * Keep in sync with TclCompileRegexpCmd.
+ */
+
+ if (bodyToken[i]->type == TCL_TOKEN_TEXT) {
+ Tcl_DString ds;
+
+ if (bodyToken[i]->size == 0) {
/*
- * On the first (pattern) arg, check to see if any
- * glob special characters are in the word '*[]?\\'.
- * If not, this is the same as 'string equal'. We
- * can use strpbrk here because the glob chars are all
- * in the ascii-7 range. If -nocase was specified,
- * we can't do this because INST_STR_EQ has no support
- * for nocase.
+ * The semantics of regexps are that they always match
+ * when the RE == "".
*/
- Tcl_Obj *copy = Tcl_NewStringObj(str, length);
- Tcl_IncrRefCount(copy);
- exactMatch = (strpbrk(Tcl_GetString(copy),
- "*[]?\\") == NULL);
- Tcl_DecrRefCount(copy);
+
+ PushLiteral(envPtr, "1", 1);
+ break;
}
- TclEmitPush(
- TclRegisterNewLiteral(envPtr, str, length), envPtr);
- } else {
- SetLineInformation (i);
- code = TclCompileTokens(interp, varTokenPtr+1,
- varTokenPtr->numComponents, envPtr);
- if (code != TCL_OK) {
- return code;
+
+ /*
+ * Attempt to convert pattern to glob. If successful, push
+ * the converted pattern.
+ */
+
+ if (TclReToGlob(NULL, bodyToken[i]->start,
+ bodyToken[i]->size, &ds, &exact) == TCL_OK) {
+ simple = 1;
+ PushLiteral(envPtr, Tcl_DStringValue(&ds),
+ Tcl_DStringLength(&ds));
+ Tcl_DStringFree(&ds);
+ }
+ }
+ if (!simple) {
+ TclCompileTokens(interp, bodyToken[i], 1, envPtr);
+ }
+
+ TclEmitInstInt4(INST_OVER, 1, envPtr);
+ 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
+ * or capture vars.
+ */
+
+ int cflags = TCL_REG_ADVANCED
+ | (noCase ? TCL_REG_NOCASE : 0);
+
+ TclEmitInstInt1(INST_REGEXP, cflags, envPtr);
}
- varTokenPtr = varTokenPtr + (varTokenPtr->numComponents + 1);
+ break;
+ }
+ default:
+ Tcl_Panic("unknown switch mode: %d", mode);
}
- if (exactMatch) {
- TclEmitOpcode(INST_STR_EQ, envPtr);
- } else {
- TclEmitInstInt1(INST_STR_MATCH, nocase, envPtr);
+ /*
+ * In a fall-through case, we will jump on _true_ to the place
+ * where the body starts (generated later, with guarantee of this
+ * ensured earlier; the final body is never a fall-through).
+ */
+
+ if (bodyToken[i+1]->size==1 && bodyToken[i+1]->start[0]=='-') {
+ if (contFixIndex == -1) {
+ contFixIndex = fixupCount;
+ contFixCount = 0;
+ }
+ TclEmitForwardJump(envPtr, TCL_TRUE_JUMP,
+ fixupArray+contFixIndex+contFixCount);
+ fixupCount++;
+ contFixCount++;
+ continue;
}
- return TCL_OK;
+
+ TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, fixupArray+fixupCount);
+ nextArmFixupIndex = fixupCount;
+ fixupCount++;
+ } else {
+ /*
+ * Got a default clause; set a flag to inhibit the generation of
+ * the jump after the body and the cleanup of the intermediate
+ * value that we are switching against.
+ *
+ * Note that default clauses (which are always terminal clauses)
+ * cannot be fall-through clauses as well, since the last clause
+ * is never a fall-through clause (which we have already
+ * verified).
+ */
+
+ foundDefault = 1;
+ }
+
+ /*
+ * Generate the body for the arm. This is guaranteed not to be a
+ * fall-through case, but it might have preceding fall-through cases,
+ * so we must process those first.
+ */
+
+ if (contFixIndex != -1) {
+ int j;
+
+ for (j=0 ; j<contFixCount ; j++) {
+ fixupTargetArray[contFixIndex+j] = CurrentOffset(envPtr);
+ }
+ contFixIndex = -1;
+ }
+
+ /*
+ * Now do the actual compilation. Note that we do not use CompileBody
+ * because we may have synthesized the tokens in a non-standard
+ * pattern.
+ */
+
+ TclEmitOpcode(INST_POP, envPtr);
+ envPtr->currStackDepth = savedStackDepth + 1;
+ envPtr->line = bodyLines[i+1]; /* TIP #280 */
+ envPtr->clNext = bodyNext[i+1]; /* TIP #280 */
+ TclCompileCmdWord(interp, bodyToken[i+1], 1, envPtr);
+
+ if (!foundDefault) {
+ TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP,
+ fixupArray+fixupCount);
+ fixupCount++;
+ fixupTargetArray[nextArmFixupIndex] = CurrentOffset(envPtr);
+ }
+ }
+
+ /*
+ * Clean up all our temporary space and return.
+ */
+
+ ckfree((char *) bodyToken);
+ ckfree((char *) bodyLines);
+ ckfree((char *) bodyNext);
+ if (bodyTokenArray != NULL) {
+ ckfree((char *) bodyTokenArray);
+ }
+
+ /*
+ * Discard the value we are matching against unless we've had a default
+ * clause (in which case it will already be gone due to the code at the
+ * start of processing an arm, guaranteed) and make the result of the
+ * command an empty string.
+ */
+
+ if (!foundDefault) {
+ TclEmitOpcode(INST_POP, envPtr);
+ PushLiteral(envPtr, "", 0);
+ }
+
+ /*
+ * Do jump fixups for arms that were executed. First, fill in the jumps of
+ * all jumps that don't point elsewhere to point to here.
+ */
+
+ for (i=0 ; i<fixupCount ; i++) {
+ if (fixupTargetArray[i] == 0) {
+ fixupTargetArray[i] = envPtr->codeNext-envPtr->codeStart;
}
}
+ /*
+ * Now scan backwards over all the jumps (all of which are forward jumps)
+ * doing each one. When we do one and there is a size changes, we must
+ * scan back over all the previous ones and see if they need adjusting
+ * before proceeding with further jump fixups (the interleaved nature of
+ * all the jumps makes this impossible to do without nested loops).
+ */
+
+ for (i=fixupCount-1 ; i>=0 ; i--) {
+ if (TclFixupForwardJump(envPtr, &fixupArray[i],
+ fixupTargetArray[i] - fixupArray[i].codeOffset, 127)) {
+ int j;
+
+ for (j=i-1 ; j>=0 ; j--) {
+ if (fixupTargetArray[j] > fixupArray[i].codeOffset) {
+ fixupTargetArray[j] += 3;
+ }
+ }
+ }
+ }
+ ckfree((char *) fixupArray);
+ ckfree((char *) fixupTargetArray);
+
+ envPtr->currStackDepth = savedStackDepth + 1;
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
- * TclCompileVariableCmd --
+ * DupJumptableInfo, FreeJumptableInfo --
*
- * Procedure called to reserve the local variables for the
- * "variable" command. The command itself is *not* compiled.
+ * Functions to duplicate, release and print a jump-table created for use
+ * with the INST_JUMP_TABLE instruction.
*
* Results:
- * Always returns TCL_OUT_LINE_COMPILE.
+ * DupJumptableInfo: a copy of the jump-table
+ * FreeJumptableInfo: none
+ * PrintJumptableInfo: none
*
* Side effects:
- * Indexed local variables are added to the environment.
+ * DupJumptableInfo: allocates memory
+ * FreeJumptableInfo: releases memory
+ * PrintJumptableInfo: none
*
*----------------------------------------------------------------------
*/
-int
-TclCompileVariableCmd(interp, parsePtr, envPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tcl_Parse *parsePtr; /* Points to a parse structure for the
- * command created by Tcl_ParseCommand. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
+
+static ClientData
+DupJumptableInfo(
+ ClientData clientData)
{
- Tcl_Token *varTokenPtr;
- int i, numWords;
- CONST char *varName, *tail;
-
- if (envPtr->procPtr == NULL) {
- return TCL_OUT_LINE_COMPILE;
+ JumptableInfo *jtPtr = clientData;
+ JumptableInfo *newJtPtr = (JumptableInfo *)
+ ckalloc(sizeof(JumptableInfo));
+ Tcl_HashEntry *hPtr, *newHPtr;
+ Tcl_HashSearch search;
+ int isNew;
+
+ Tcl_InitHashTable(&newJtPtr->hashTable, TCL_STRING_KEYS);
+ hPtr = Tcl_FirstHashEntry(&jtPtr->hashTable, &search);
+ while (hPtr != NULL) {
+ newHPtr = Tcl_CreateHashEntry(&newJtPtr->hashTable,
+ Tcl_GetHashKey(&jtPtr->hashTable, hPtr), &isNew);
+ Tcl_SetHashValue(newHPtr, Tcl_GetHashValue(hPtr));
}
+ return newJtPtr;
+}
- numWords = parsePtr->numWords;
-
- varTokenPtr = parsePtr->tokenPtr
- + (parsePtr->tokenPtr->numComponents + 1);
- for (i = 1; i < numWords; i += 2) {
- if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
- varName = varTokenPtr[1].start;
- tail = varName + varTokenPtr[1].size - 1;
- if ((*tail == ')') || (tail < varName)) continue;
- while ((tail > varName) && ((*tail != ':') || (*(tail-1) != ':'))) {
- tail--;
- }
- if ((*tail == ':') && (tail > varName)) {
- tail++;
+static void
+FreeJumptableInfo(
+ ClientData clientData)
+{
+ JumptableInfo *jtPtr = clientData;
+
+ Tcl_DeleteHashTable(&jtPtr->hashTable);
+ ckfree((char *) jtPtr);
+}
+
+static void
+PrintJumptableInfo(
+ ClientData clientData,
+ Tcl_Obj *appendObj,
+ ByteCode *codePtr,
+ unsigned int pcOffset)
+{
+ register JumptableInfo *jtPtr = clientData;
+ Tcl_HashEntry *hPtr;
+ Tcl_HashSearch search;
+ const char *keyPtr;
+ int offset, i = 0;
+
+ hPtr = Tcl_FirstHashEntry(&jtPtr->hashTable, &search);
+ for (; hPtr ; hPtr = Tcl_NextHashEntry(&search)) {
+ keyPtr = Tcl_GetHashKey(&jtPtr->hashTable, hPtr);
+ offset = PTR2INT(Tcl_GetHashValue(hPtr));
+
+ if (i++) {
+ Tcl_AppendToObj(appendObj, ", ", -1);
+ if (i%4==0) {
+ Tcl_AppendToObj(appendObj, "\n\t\t", -1);
}
- (void) TclFindCompiledLocal(tail, (tail-varName+1),
- /*create*/ 1, /*flags*/ 0, envPtr->procPtr);
- varTokenPtr = varTokenPtr + (varTokenPtr->numComponents + 1);
}
+ Tcl_AppendPrintfToObj(appendObj, "\"%s\"->pc %d",
+ keyPtr, pcOffset + offset);
}
- return TCL_OUT_LINE_COMPILE;
}
/*
@@ -3000,99 +4674,87 @@ TclCompileVariableCmd(interp, parsePtr, envPtr)
* Procedure called to compile the "while" command.
*
* Results:
- * The return value is a standard Tcl result, which is TCL_OK if
- * compilation was successful. If an error occurs then the
- * interpreter's result contains a standard error message and TCL_ERROR
- * is returned. If compilation failed because the command is too
- * complex for TclCompileWhileCmd, TCL_OUT_LINE_COMPILE is returned
- * indicating that the while command should be compiled "out of line"
- * by emitting code to invoke its command procedure at runtime.
+ * 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 "while" command
- * at runtime.
+ * Instructions are added to envPtr to execute the "while" command at
+ * runtime.
*
*----------------------------------------------------------------------
*/
int
-TclCompileWhileCmd(interp, parsePtr, envPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- Tcl_Parse *parsePtr; /* Points to a parse structure for the
- * command created by Tcl_ParseCommand. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
+TclCompileWhileCmd(
+ 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 *testTokenPtr, *bodyTokenPtr;
JumpFixup jumpEvalCondFixup;
- int testCodeOffset, bodyCodeOffset, jumpDist;
- int range, code;
- char buffer[32 + TCL_INTEGER_SPACE];
+ 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. */
+ int loopMayEnd = 1; /* This is set to 0 if it is recognized as an
+ * infinite loop. */
Tcl_Obj *boolObj;
- int boolVal;
-
- DefineLineInformation;
+ DefineLineInformation; /* TIP #280 */
if (parsePtr->numWords != 3) {
- Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "wrong # args: should be \"while test command\"", -1);
return TCL_ERROR;
}
/*
- * If the test expression requires substitutions, don't compile the
- * while command inline. E.g., the expression might cause the loop to
- * never execute or execute forever, as in "while "$x < 5" {}".
+ * If the test expression requires substitutions, don't compile the while
+ * command inline. E.g., the expression might cause the loop to never
+ * execute or execute forever, as in "while "$x < 5" {}".
*
- * Bail out also if the body expression requires substitutions
- * in order to insure correct behaviour [Bug 219166]
+ * Bail out also if the body expression requires substitutions in order to
+ * insure correct behaviour [Bug 219166]
*/
- testTokenPtr = parsePtr->tokenPtr
- + (parsePtr->tokenPtr->numComponents + 1);
- bodyTokenPtr = testTokenPtr + (testTokenPtr->numComponents + 1);
+ testTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ bodyTokenPtr = TokenAfter(testTokenPtr);
+
if ((testTokenPtr->type != TCL_TOKEN_SIMPLE_WORD)
|| (bodyTokenPtr->type != TCL_TOKEN_SIMPLE_WORD)) {
- return TCL_OUT_LINE_COMPILE;
+ return TCL_ERROR;
}
/*
- * Find out if the condition is a constant.
+ * Find out if the condition is a constant.
*/
boolObj = Tcl_NewStringObj(testTokenPtr[1].start, testTokenPtr[1].size);
Tcl_IncrRefCount(boolObj);
code = Tcl_GetBooleanFromObj(NULL, boolObj, &boolVal);
- Tcl_DecrRefCount(boolObj);
+ TclDecrRefCount(boolObj);
if (code == TCL_OK) {
if (boolVal) {
/*
- * it is an infinite loop
+ * It is an infinite loop; flag it so that we generate a more
+ * efficient body.
*/
- loopMayEnd = 0;
+ loopMayEnd = 0;
} else {
/*
- * This is an empty loop: "while 0 {...}" or such.
- * Compile no bytecodes.
+ * This is an empty loop: "while 0 {...}" or such. Compile no
+ * bytecodes.
*/
goto pushResult;
}
}
- /*
+ /*
* Create a ExceptionRange record for the loop body. This is used to
* implement break and continue.
*/
- envPtr->exceptDepth++;
- envPtr->maxExceptDepth =
- TclMax(envPtr->exceptDepth, envPtr->maxExceptDepth);
- range = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr);
+ range = DeclareExceptionRange(envPtr, LOOP_EXCEPTION_RANGE);
/*
* Jump to the evaluation of the condition. This code uses the "loop
@@ -3110,31 +4772,26 @@ TclCompileWhileCmd(interp, parsePtr, envPtr)
if (loopMayEnd) {
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpEvalCondFixup);
- testCodeOffset = 0; /* avoid compiler warning */
+ testCodeOffset = 0; /* Avoid compiler warning. */
} else {
- testCodeOffset = (envPtr->codeNext - envPtr->codeStart);
+ /*
+ * Make sure that the first command in the body is preceded by an
+ * INST_START_CMD, and hence counted properly. [Bug 1752146]
+ */
+
+ envPtr->atCmdStart = 0;
+ testCodeOffset = CurrentOffset(envPtr);
}
-
/*
* Compile the loop body.
*/
SetLineInformation (2);
- bodyCodeOffset = (envPtr->codeNext - envPtr->codeStart);
- code = TclCompileCmdWord(interp, bodyTokenPtr+1,
- bodyTokenPtr->numComponents, envPtr);
+ bodyCodeOffset = ExceptionRangeStarts(envPtr, range);
+ CompileBody(envPtr, bodyTokenPtr, interp);
+ ExceptionRangeEnds(envPtr, range);
envPtr->currStackDepth = savedStackDepth + 1;
- if (code != TCL_OK) {
- if (code == TCL_ERROR) {
- sprintf(buffer, "\n (\"while\" body line %d)",
- interp->errorLine);
- Tcl_AddObjErrorInfo(interp, buffer, -1);
- }
- goto error;
- }
- envPtr->exceptArrayPtr[range].numCodeBytes =
- (envPtr->codeNext - envPtr->codeStart) - bodyCodeOffset;
TclEmitOpcode(INST_POP, envPtr);
/*
@@ -3143,7 +4800,7 @@ TclCompileWhileCmd(interp, parsePtr, envPtr)
*/
if (loopMayEnd) {
- testCodeOffset = (envPtr->codeNext - envPtr->codeStart);
+ testCodeOffset = CurrentOffset(envPtr);
jumpDist = testCodeOffset - jumpEvalCondFixup.codeOffset;
if (TclFixupForwardJump(envPtr, &jumpEvalCondFixup, jumpDist, 127)) {
bodyCodeOffset += 3;
@@ -3151,113 +4808,86 @@ TclCompileWhileCmd(interp, parsePtr, envPtr)
}
envPtr->currStackDepth = savedStackDepth;
SetLineInformation (1);
- code = TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
- if (code != TCL_OK) {
- if (code == TCL_ERROR) {
- Tcl_AddObjErrorInfo(interp,
- "\n (\"while\" test expression)", -1);
- }
- goto error;
- }
+ TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
envPtr->currStackDepth = savedStackDepth + 1;
-
- jumpDist = (envPtr->codeNext - envPtr->codeStart) - bodyCodeOffset;
+
+ jumpDist = CurrentOffset(envPtr) - bodyCodeOffset;
if (jumpDist > 127) {
TclEmitInstInt4(INST_JUMP_TRUE4, -jumpDist, envPtr);
} else {
TclEmitInstInt1(INST_JUMP_TRUE1, -jumpDist, envPtr);
}
} else {
- jumpDist = (envPtr->codeNext - envPtr->codeStart) - bodyCodeOffset;
+ jumpDist = CurrentOffset(envPtr) - bodyCodeOffset;
if (jumpDist > 127) {
TclEmitInstInt4(INST_JUMP4, -jumpDist, envPtr);
} else {
TclEmitInstInt1(INST_JUMP1, -jumpDist, envPtr);
- }
+ }
}
-
/*
* Set the loop's body, continue and break offsets.
*/
envPtr->exceptArrayPtr[range].continueOffset = testCodeOffset;
envPtr->exceptArrayPtr[range].codeOffset = bodyCodeOffset;
- envPtr->exceptArrayPtr[range].breakOffset =
- (envPtr->codeNext - envPtr->codeStart);
-
+ ExceptionRangeTarget(envPtr, range, breakOffset);
+
/*
* The while command's result is an empty string.
*/
- pushResult:
+ pushResult:
envPtr->currStackDepth = savedStackDepth;
- TclEmitPush(TclRegisterNewLiteral(envPtr, "", 0), envPtr);
- envPtr->exceptDepth--;
+ PushLiteral(envPtr, "", 0);
return TCL_OK;
-
- error:
- envPtr->exceptDepth--;
- return code;
}
/*
*----------------------------------------------------------------------
*
- * TclPushVarName --
+ * PushVarName --
*
- * Procedure used in the compiling where pushing a variable name
- * is necessary (append, lappend, set).
+ * Procedure used in the compiling where pushing a variable name is
+ * necessary (append, lappend, set).
*
* Results:
- * The return value is a standard Tcl result, which is normally TCL_OK
- * unless there was an error while parsing string. If an error occurs
- * then the interpreter's result contains a standard error message.
+ * 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 runtime.
+ * Instructions are added to envPtr to execute the "set" command at
+ * runtime.
*
*----------------------------------------------------------------------
*/
static int
-TclPushVarName(interp, varTokenPtr, envPtr, flags, localIndexPtr,
-#ifndef TCL_TIP280
- simpleVarNamePtr, isScalarPtr)
-#else
- simpleVarNamePtr, isScalarPtr, line, clNext)
-#endif
- Tcl_Interp *interp; /* Used for error reporting. */
- Tcl_Token *varTokenPtr; /* Points to a variable token. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
- int flags; /* takes TCL_CREATE_VAR or
- * TCL_NO_LARGE_INDEX */
- int *localIndexPtr; /* must not be NULL */
- int *simpleVarNamePtr; /* must not be NULL */
- int *isScalarPtr; /* must not be NULL */
-#ifdef TCL_TIP280
- int line; /* line the token starts on */
- int* clNext;
-#endif
-{
- register CONST char *p;
- CONST char *name, *elName;
+PushVarName(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ Tcl_Token *varTokenPtr, /* Points to a variable token. */
+ CompileEnv *envPtr, /* Holds resulting instructions. */
+ int flags, /* TCL_CREATE_VAR or 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;
- int nameChars, elNameChars, simpleVarName, localIndex;
- int code = TCL_OK;
-
Tcl_Token *elemTokenPtr = NULL;
- int elemTokenCount = 0;
- int allocedTokens = 0;
- int removedParen = 0;
+ 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.
+ * 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;
@@ -3267,8 +4897,8 @@ TclPushVarName(interp, varTokenPtr, envPtr, flags, localIndexPtr,
/*
* 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
+ * 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.
*/
@@ -3279,31 +4909,33 @@ TclPushVarName(interp, varTokenPtr, envPtr, flags, localIndexPtr,
* 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) == ')') {
- /*
+ if (name[nameChars-1] == ')') {
+ /*
* last char is ')' => potential array reference.
*/
- for (i = 0, p = name; i < nameChars; i++, p++) {
+ for (i=0,p=name ; i<nameChars ; i++,p++) {
if (*p == '(') {
elName = p + 1;
elNameChars = nameChars - i - 2;
- nameChars = i ;
+ nameChars = i;
break;
}
}
if ((elName != NULL) && elNameChars) {
/*
- * An array element, the element name is a simple
- * string: assemble the corresponding token.
+ * An array element, the element name is a simple string:
+ * assemble the corresponding token.
*/
- elemTokenPtr = (Tcl_Token *) ckalloc(sizeof(Tcl_Token));
+ elemTokenPtr = (Tcl_Token *) TclStackAlloc(interp,
+ sizeof(Tcl_Token));
allocedTokens = 1;
elemTokenPtr->type = TCL_TOKEN_TEXT;
elemTokenPtr->start = elName;
@@ -3314,28 +4946,28 @@ TclPushVarName(interp, varTokenPtr, envPtr, flags, localIndexPtr,
}
} 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] == ')')) {
+ && (varTokenPtr[n].type == TCL_TOKEN_TEXT)
+ && (varTokenPtr[n].start[varTokenPtr[n].size - 1] == ')')) {
- /*
- * Check for parentheses inside first token
+ /*
+ * 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) {
+ 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.
+ * 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) {
@@ -3345,39 +4977,40 @@ TclPushVarName(interp, varTokenPtr, envPtr, flags, localIndexPtr,
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;
+ 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
+ * Make a first token with the extra characters in the first
* token.
*/
- elemTokenPtr = (Tcl_Token *) ckalloc(n * sizeof(Tcl_Token));
+ elemTokenPtr = (Tcl_Token *) 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((void *) (elemTokenPtr+1), (void *) (&varTokenPtr[2]),
- ((n-1) * sizeof(Tcl_Token)));
+
+ memcpy(elemTokenPtr+1, varTokenPtr+2,
+ (n-1) * sizeof(Tcl_Token));
} else {
/*
* Use the already available tokens.
*/
-
+
elemTokenPtr = &varTokenPtr[2];
- elemTokenCount = n - 1;
+ elemTokenCount = n - 1;
}
}
}
@@ -3396,23 +5029,25 @@ TclPushVarName(interp, varTokenPtr, envPtr, flags, localIndexPtr,
}
/*
- * 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.
+ * 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 ((envPtr->procPtr != NULL) && !hasNsQualifiers) {
localIndex = TclFindCompiledLocal(name, nameChars,
- /*create*/ (flags & TCL_CREATE_VAR),
- /*flags*/ ((elName==NULL)? VAR_SCALAR : VAR_ARRAY),
+ /*create*/ flags & TCL_CREATE_VAR,
envPtr->procPtr);
if ((flags & TCL_NO_LARGE_INDEX) && (localIndex > 255)) {
- /* we'll push the name */
+ /*
+ * We'll push the name.
+ */
+
localIndex = -1;
}
}
if (localIndex < 0) {
- TclEmitPush(TclRegisterNewLiteral(envPtr, name, nameChars), envPtr);
+ PushLiteral(envPtr, name, nameChars);
}
/*
@@ -3421,17 +5056,11 @@ TclPushVarName(interp, varTokenPtr, envPtr, flags, localIndexPtr,
if (elName != NULL) {
if (elNameChars) {
-#ifdef TCL_TIP280
- envPtr->line = line;
- envPtr->clNext = clNext;
-#endif
- code = TclCompileTokens(interp, elemTokenPtr,
- elemTokenCount, envPtr);
- if (code != TCL_OK) {
- goto done;
- }
+ envPtr->line = line;
+ envPtr->clNext = clNext;
+ TclCompileTokens(interp, elemTokenPtr, elemTokenCount, envPtr);
} else {
- TclEmitPush(TclRegisterNewLiteral(envPtr, "", 0), envPtr);
+ PushLiteral(envPtr, "", 0);
}
}
} else {
@@ -3439,28 +5068,1406 @@ TclPushVarName(interp, varTokenPtr, envPtr, flags, localIndexPtr,
* The var name isn't simple: compile and push it.
*/
-#ifdef TCL_TIP280
- envPtr->line = line;
- envPtr->clNext = clNext;
-#endif
- code = TclCompileTokens(interp, varTokenPtr+1,
- varTokenPtr->numComponents, envPtr);
- if (code != TCL_OK) {
- goto done;
- }
+ envPtr->line = line;
+ envPtr->clNext = clNext;
+ CompileTokens(envPtr, varTokenPtr, interp);
}
- done:
if (removedParen) {
++varTokenPtr[removedParen].size;
}
if (allocedTokens) {
- ckfree((char *) elemTokenPtr);
+ TclStackFree(interp, elemTokenPtr);
}
- *localIndexPtr = localIndex;
- *simpleVarNamePtr = simpleVarName;
- *isScalarPtr = (elName == NULL);
- return code;
+ *localIndexPtr = localIndex;
+ *simpleVarNamePtr = simpleVarName;
+ *isScalarPtr = (elName == NULL);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CompileUnaryOpCmd --
+ *
+ * Utility routine to compile the unary operator 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 compiled command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CompileUnaryOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ int instruction,
+ CompileEnv *envPtr)
+{
+ Tcl_Token *tokenPtr;
+ DefineLineInformation; /* TIP #280 */
+
+ if (parsePtr->numWords != 2) {
+ return TCL_ERROR;
+ }
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 1);
+ TclEmitOpcode(instruction, envPtr);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CompileAssociativeBinaryOpCmd --
+ *
+ * Utility routine to compile the binary operator commands that accept an
+ * arbitrary number of arguments, and that are associative operations.
+ * Because of the associativity, we may combine operations from right to
+ * left, saving us any effort of re-ordering the arguments on the stack
+ * after substitutions are completed.
+ *
+ * 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 compiled command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CompileAssociativeBinaryOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ const char *identity,
+ int instruction,
+ CompileEnv *envPtr)
+{
+ Tcl_Token *tokenPtr = parsePtr->tokenPtr;
+ DefineLineInformation; /* TIP #280 */
+ int words;
+
+ for (words=1 ; words<parsePtr->numWords ; words++) {
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, words);
+ }
+ if (parsePtr->numWords <= 2) {
+ PushLiteral(envPtr, identity, -1);
+ words++;
+ }
+ if (words > 3) {
+ /*
+ * Reverse order of arguments to get precise agreement with
+ * [expr] in calcuations, including roundoff errors.
+ */
+ TclEmitInstInt4(INST_REVERSE, words-1, envPtr);
+ }
+ while (--words > 1) {
+ TclEmitOpcode(instruction, envPtr);
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CompileStrictlyBinaryOpCmd --
+ *
+ * Utility routine to compile the binary operator commands, that strictly
+ * accept exactly two arguments.
+ *
+ * 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 compiled command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CompileStrictlyBinaryOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ int instruction,
+ CompileEnv *envPtr)
+{
+ if (parsePtr->numWords != 3) {
+ return TCL_ERROR;
+ }
+ return CompileAssociativeBinaryOpCmd(interp, parsePtr,
+ NULL, instruction, envPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CompileComparisonOpCmd --
+ *
+ * Utility routine to compile the n-ary comparison operator 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 compiled command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CompileComparisonOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ int instruction,
+ CompileEnv *envPtr)
+{
+ Tcl_Token *tokenPtr;
+ DefineLineInformation; /* TIP #280 */
+
+ if (parsePtr->numWords < 3) {
+ PushLiteral(envPtr, "1", 1);
+ } else if (parsePtr->numWords == 3) {
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 1);
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, 2);
+ TclEmitOpcode(instruction, envPtr);
+ } else if (envPtr->procPtr == NULL) {
+ /*
+ * No local variable space!
+ */
+
+ return TCL_ERROR;
+ } else {
+ int tmpIndex = TclFindCompiledLocal(NULL, 0, 1, envPtr->procPtr);
+ 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);
+ }
+ 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);
+ }
+ 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);
+ }
+ }
+ TclEmitOpcode(instruction, envPtr);
+ }
+ for (; words>3 ; words--) {
+ TclEmitOpcode(INST_BITAND, envPtr);
+ }
+
+ /*
+ * Drop the value from the temp variable; retaining that reference
+ * 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);
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompile*OpCmd --
+ *
+ * Procedures called to compile the corresponding "::tcl::mathop::*"
+ * commands. These are all wrappers around the utility operator command
+ * compiler functions, except for the compilers for subtraction and
+ * division, which are special.
+ *
+ * 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 compiled command at
+ * runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileInvertOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileUnaryOpCmd(interp, parsePtr, INST_BITNOT, envPtr);
+}
+
+int
+TclCompileNotOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileUnaryOpCmd(interp, parsePtr, INST_LNOT, envPtr);
+}
+
+int
+TclCompileAddOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileAssociativeBinaryOpCmd(interp, parsePtr, "0", INST_ADD,
+ envPtr);
+}
+
+int
+TclCompileMulOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileAssociativeBinaryOpCmd(interp, parsePtr, "1", INST_MULT,
+ envPtr);
+}
+
+int
+TclCompileAndOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileAssociativeBinaryOpCmd(interp, parsePtr, "-1", INST_BITAND,
+ envPtr);
+}
+
+int
+TclCompileOrOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileAssociativeBinaryOpCmd(interp, parsePtr, "0", INST_BITOR,
+ envPtr);
+}
+
+int
+TclCompileXorOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileAssociativeBinaryOpCmd(interp, parsePtr, "0", INST_BITXOR,
+ envPtr);
+}
+
+int
+TclCompilePowOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ /*
+ * This one has its own implementation because the ** operator is
+ * the only one with right associativity.
+ */
+ Tcl_Token *tokenPtr = parsePtr->tokenPtr;
+ DefineLineInformation; /* TIP #280 */
+ int words;
+
+ for (words=1 ; words<parsePtr->numWords ; words++) {
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, words);
+ }
+ if (parsePtr->numWords <= 2) {
+ PushLiteral(envPtr, "1", 1);
+ words++;
+ }
+ while (--words > 1) {
+ TclEmitOpcode(INST_EXPON, envPtr);
+ }
+ return TCL_OK;
+}
+
+int
+TclCompileLshiftOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileStrictlyBinaryOpCmd(interp, parsePtr, INST_LSHIFT, envPtr);
+}
+
+int
+TclCompileRshiftOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileStrictlyBinaryOpCmd(interp, parsePtr, INST_RSHIFT, envPtr);
+}
+
+int
+TclCompileModOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileStrictlyBinaryOpCmd(interp, parsePtr, INST_MOD, envPtr);
+}
+
+int
+TclCompileNeqOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileStrictlyBinaryOpCmd(interp, parsePtr, INST_NEQ, envPtr);
+}
+
+int
+TclCompileStrneqOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileStrictlyBinaryOpCmd(interp, parsePtr, INST_STR_NEQ, envPtr);
+}
+
+int
+TclCompileInOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileStrictlyBinaryOpCmd(interp, parsePtr, INST_LIST_IN, envPtr);
+}
+
+int
+TclCompileNiOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileStrictlyBinaryOpCmd(interp, parsePtr, INST_LIST_NOT_IN,
+ envPtr);
+}
+
+int
+TclCompileLessOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileComparisonOpCmd(interp, parsePtr, INST_LT, envPtr);
+}
+
+int
+TclCompileLeqOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileComparisonOpCmd(interp, parsePtr, INST_LE, envPtr);
+}
+
+int
+TclCompileGreaterOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileComparisonOpCmd(interp, parsePtr, INST_GT, envPtr);
+}
+
+int
+TclCompileGeqOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileComparisonOpCmd(interp, parsePtr, INST_GE, envPtr);
+}
+
+int
+TclCompileEqOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileComparisonOpCmd(interp, parsePtr, INST_EQ, envPtr);
+}
+
+int
+TclCompileStreqOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ return CompileComparisonOpCmd(interp, parsePtr, INST_STR_EQ, envPtr);
+}
+
+int
+TclCompileMinusOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ Tcl_Token *tokenPtr = parsePtr->tokenPtr;
+ DefineLineInformation; /* TIP #280 */
+ int words;
+
+ if (parsePtr->numWords == 1) {
+ /* Fallback to direct eval to report syntax error */
+ return TCL_ERROR;
+ }
+ for (words=1 ; words<parsePtr->numWords ; words++) {
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, words);
+ }
+ if (words == 2) {
+ TclEmitOpcode(INST_UMINUS, envPtr);
+ return TCL_OK;
+ }
+ if (words == 3) {
+ TclEmitOpcode(INST_SUB, envPtr);
+ return TCL_OK;
+ }
+ /*
+ * Reverse order of arguments to get precise agreement with
+ * [expr] in calcuations, including roundoff errors.
+ */
+ TclEmitInstInt4(INST_REVERSE, words-1, envPtr);
+ while (--words > 1) {
+ TclEmitInstInt4(INST_REVERSE, 2, envPtr);
+ TclEmitOpcode(INST_SUB, envPtr);
+ }
+ return TCL_OK;
+}
+
+int
+TclCompileDivOpCmd(
+ Tcl_Interp *interp,
+ Tcl_Parse *parsePtr,
+ Command *cmdPtr, /* Points to defintion of command being
+ * compiled. */
+ CompileEnv *envPtr)
+{
+ Tcl_Token *tokenPtr = parsePtr->tokenPtr;
+ DefineLineInformation; /* TIP #280 */
+ int words;
+
+ if (parsePtr->numWords == 1) {
+ /* Fallback to direct eval to report syntax error */
+ return TCL_ERROR;
+ }
+ if (parsePtr->numWords == 2) {
+ PushLiteral(envPtr, "1.0", 3);
+ }
+ for (words=1 ; words<parsePtr->numWords ; words++) {
+ tokenPtr = TokenAfter(tokenPtr);
+ CompileWord(envPtr, tokenPtr, interp, words);
+ }
+ if (words <= 3) {
+ TclEmitOpcode(INST_DIV, envPtr);
+ return TCL_OK;
+ }
+ /*
+ * Reverse order of arguments to get precise agreement with
+ * [expr] in calcuations, including roundoff errors.
+ */
+ TclEmitInstInt4(INST_REVERSE, words-1, envPtr);
+ while (--words > 1) {
+ TclEmitInstInt4(INST_REVERSE, 2, envPtr);
+ TclEmitOpcode(INST_DIV, 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 (envPtr->procPtr == NULL) {
+ 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,
+ /*create*/ TCL_CREATE_VAR,
+ envPtr->procPtr);
+ Tcl_DecrRefCount(tailPtr);
+ return localIndex;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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;
+ }
+
+ /*
+ * Push the frame index if it is known at compile time
+ */
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ if(TclWordKnownAtCompileTime(tokenPtr, objPtr)) {
+ CallFrame *framePtr;
+ 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;
+ }
+ 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;
+ }
+ } 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, TCL_CREATE_VAR,
+ &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;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileNamespaceCmd --
+ *
+ * Procedure called to compile the "namespace" command; currently, only
+ * the subcommand "namespace upvar" is compiled to bytecodes.
+ *
+ * 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
+TclCompileNamespaceCmd(
+ 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;
+ }
+
+ /*
+ * Only compile [namespace upvar ...]: needs an odd number of args, >=5
+ */
+
+ numWords = parsePtr->numWords;
+ if (!(numWords%2) || (numWords < 5)) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Check if the second argument is "upvar"
+ */
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ if ((tokenPtr->size != 5) /* 5 == strlen("upvar") */
+ || strncmp(tokenPtr->start, "upvar", 5)) {
+ return TCL_ERROR;
+ }
+
+ /*
+ * Push the namespace
+ */
+
+ tokenPtr = TokenAfter(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=4; i<=numWords; i+=2) {
+ otherTokenPtr = TokenAfter(localTokenPtr);
+ localTokenPtr = TokenAfter(otherTokenPtr);
+
+ CompileWord(envPtr, otherTokenPtr, interp, 1);
+ PushVarNameWord(interp, localTokenPtr, envPtr, TCL_CREATE_VAR,
+ &localIndex, &simpleVarName, &isScalar, 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);
+ PushLiteral(envPtr, "", 0);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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);
+ TclEmitInstInt4(INST_STORE_SCALAR4, localIndex, envPtr);
+ TclEmitOpcode(INST_POP, envPtr);
+ }
+ }
+
+ /*
+ * Set the result to empty
+ */
+
+ PushLiteral(envPtr, "", 0);
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileEnsemble --
+ *
+ * Procedure called to compile an ensemble command. Note that most
+ * ensembles are not compiled, since modifying a compiled ensemble causes
+ * a invalidation of all existing bytecode (expensive!) which is not
+ * normally warranted.
+ *
+ * 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 subcommands of the
+ * ensemble at runtime if a compile-time mapping is possible.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileEnsemble(
+ 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;
+ Tcl_Obj *mapObj, *subcmdObj, *targetCmdObj, *listObj, **elems;
+ Tcl_Command ensemble = (Tcl_Command) cmdPtr;
+ Tcl_Parse synthetic;
+ int len, numBytes, result, flags = 0, i;
+ const char *word;
+
+ if (parsePtr->numWords < 2) {
+ return TCL_ERROR;
+ }
+
+ tokenPtr = TokenAfter(parsePtr->tokenPtr);
+ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+ /*
+ * Too hard.
+ */
+
+ return TCL_ERROR;
+ }
+
+ word = tokenPtr[1].start;
+ numBytes = tokenPtr[1].size;
+
+ /*
+ * There's a sporting chance we'll be able to compile this. But now we
+ * must check properly. To do that, check that we're compiling an ensemble
+ * that has a compilable command as its appropriate subcommand.
+ */
+
+ if (Tcl_GetEnsembleMappingDict(NULL, ensemble, &mapObj) != TCL_OK
+ || mapObj == NULL) {
+ /*
+ * Either not an ensemble or a mapping isn't installed. Crud. Too hard
+ * to proceed.
+ */
+
+ return TCL_ERROR;
+ }
+
+ /*
+ * Next, get the flags. We need them on several code paths.
+ */
+
+ (void) Tcl_GetEnsembleFlags(NULL, ensemble, &flags);
+
+ /*
+ * Check to see if there's also a subcommand list; must check to see if
+ * the subcommand we are calling is in that list if it exists, since that
+ * list filters the entries in the map.
+ */
+
+ (void) Tcl_GetEnsembleSubcommandList(NULL, ensemble, &listObj);
+ if (listObj != NULL) {
+ int sclen;
+ const char *str;
+ Tcl_Obj *matchObj = NULL;
+
+ if (Tcl_ListObjGetElements(NULL, listObj, &len, &elems) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ for (i=0 ; i<len ; i++) {
+ str = Tcl_GetStringFromObj(elems[i], &sclen);
+ if (sclen==numBytes && !memcmp(word, str, (unsigned) numBytes)) {
+ /*
+ * Exact match! Excellent!
+ */
+
+ result = Tcl_DictObjGet(NULL, mapObj,elems[i], &targetCmdObj);
+ if (result != TCL_OK || targetCmdObj == NULL) {
+ return TCL_ERROR;
+ }
+ goto doneMapLookup;
+ }
+
+ /*
+ * Check to see if we've got a prefix match. A single prefix match
+ * is fine, and allows us to refine our dictionary lookup, but
+ * multiple prefix matches is a Bad Thing and will prevent us from
+ * making progress. Note that we cannot do the lookup immediately
+ * in the prefix case; might be another entry later in the list
+ * that causes things to fail.
+ */
+
+ if ((flags & TCL_ENSEMBLE_PREFIX)
+ && strncmp(word, str, (unsigned) numBytes) == 0) {
+ if (matchObj != NULL) {
+ return TCL_ERROR;
+ }
+ matchObj = elems[i];
+ }
+ }
+ if (matchObj != NULL) {
+ result = Tcl_DictObjGet(NULL, mapObj, matchObj, &targetCmdObj);
+ if (result != TCL_OK || targetCmdObj == NULL) {
+ return TCL_ERROR;
+ }
+ goto doneMapLookup;
+ }
+ return TCL_ERROR;
+ } else {
+ /*
+ * No map, so check the dictionary directly.
+ */
+
+ TclNewStringObj(subcmdObj, word, numBytes);
+ result = Tcl_DictObjGet(NULL, mapObj, subcmdObj, &targetCmdObj);
+ TclDecrRefCount(subcmdObj);
+ if (result == TCL_OK && targetCmdObj != NULL) {
+ /*
+ * Got it. Skip the fiddling around with prefixes.
+ */
+
+ goto doneMapLookup;
+ }
+
+ /*
+ * We've not literally got a valid subcommand. But maybe we have a
+ * prefix. Check if prefix matches are allowed.
+ */
+
+ if (flags & TCL_ENSEMBLE_PREFIX) {
+ Tcl_DictSearch s;
+ int done, matched;
+ Tcl_Obj *tmpObj;
+
+ /*
+ * Iterate over the keys in the dictionary, checking to see if
+ * we're a prefix.
+ */
+
+ Tcl_DictObjFirst(NULL,mapObj,&s,&subcmdObj,&tmpObj,&done);
+ matched = 0;
+ while (!done) {
+ if (strncmp(TclGetString(subcmdObj), word,
+ (unsigned) numBytes) == 0) {
+ if (matched++) {
+ /*
+ * Must have matched twice! Not unique, so no point
+ * looking further.
+ */
+
+ break;
+ }
+ targetCmdObj = tmpObj;
+ }
+ Tcl_DictObjNext(&s, &subcmdObj, &tmpObj, &done);
+ }
+ Tcl_DictObjDone(&s);
+
+ /*
+ * If we have anything other than a single match, we've failed the
+ * unique prefix check.
+ */
+
+ if (matched != 1) {
+ return TCL_ERROR;
+ }
+ } else {
+ return TCL_ERROR;
+ }
+ }
+
+ /*
+ * OK, we definitely map to something. But what?
+ *
+ * The command we map to is the first word out of the map element. Note
+ * that we also reject dealing with multi-element rewrites if we are in a
+ * safe interpreter, as there is otherwise a (highly gnarly!) way to make
+ * Tcl crash open to exploit.
+ */
+
+ doneMapLookup:
+ if (Tcl_ListObjGetElements(NULL, targetCmdObj, &len, &elems) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (len > 1 && Tcl_IsSafe(interp)) {
+ return TCL_ERROR;
+ }
+ targetCmdObj = elems[0];
+
+ Tcl_IncrRefCount(targetCmdObj);
+ cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, targetCmdObj);
+ TclDecrRefCount(targetCmdObj);
+ if (cmdPtr == NULL || cmdPtr->compileProc == NULL
+ || cmdPtr->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;
+ }
+
+ /*
+ * 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.
+ */
+
+ TclParseInit(interp, NULL, 0, &synthetic);
+ synthetic.numWords = parsePtr->numWords - 2 + len;
+ TclGrowParseTokenArray(&synthetic, 2*len);
+ synthetic.numTokens = 2*len;
+
+ /*
+ * 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!
+ */
+
+ for (i=0 ; i<len ; i++) {
+ int sclen;
+ const char *str = Tcl_GetStringFromObj(elems[i], &sclen);
+
+ 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;
+
+ 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;
+ }
+
+ /*
+ * Copy over the real argument tokens.
+ */
+
+ for (i=len; i<synthetic.numWords; i++) {
+ int toCopy;
+ tokenPtr = TokenAfter(tokenPtr);
+ toCopy = tokenPtr->numComponents + 1;
+ TclGrowParseTokenArray(&synthetic, toCopy);
+ memcpy(synthetic.tokenPtr + synthetic.numTokens, tokenPtr,
+ sizeof(Tcl_Token) * toCopy);
+ synthetic.numTokens += toCopy;
+ }
+
+ /*
+ * Hand off compilation to the subcommand compiler. At last!
+ */
+
+ result = cmdPtr->compileProc(interp, &synthetic, cmdPtr, envPtr);
+
+ /*
+ * Clean up if necessary.
+ */
+
+ Tcl_FreeParse(&synthetic);
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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, TCL_CREATE_VAR, &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);
+ }
+ }
+ } else {
+ TclEmitOpcode(INST_EXIST_STK, envPtr);
+ }
+
+ return TCL_OK;
}
/*
@@ -3470,4 +6477,3 @@ TclPushVarName(interp, varTokenPtr, envPtr, flags, localIndexPtr,
* fill-column: 78
* End:
*/
-
diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c
index 68533c5..60f95b6 100644
--- a/generic/tclCompExpr.c
+++ b/generic/tclCompExpr.c
@@ -1,578 +1,2020 @@
-/*
+/*
* tclCompExpr.c --
*
- * This file contains the code to compile Tcl expressions.
+ * This file contains the code to parse and compile Tcl expressions
+ * and implementations of the Tcl commands corresponding to expression
+ * operators, such as the command ::tcl::mathop::+ .
*
- * Copyright (c) 1997 Sun Microsystems, Inc.
- * Copyright (c) 1998-2000 by Scriptics Corporation.
+ * Contributions from Don Porter, NIST, 2006-2007. (not subject to US copyright)
*
- * 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.
*/
#include "tclInt.h"
-#include "tclCompile.h"
+#include "tclCompile.h" /* CompileEnv */
/*
- * The stuff below is a bit of a hack so that this file can be used in
- * environments that include no UNIX, i.e. no errno: just arrange to use
- * the errno from tclExecute.c here.
+ * Expression parsing takes place in the routine ParseExpr(). It takes a
+ * string as input, parses that string, and generates a representation of
+ * the expression in the form of a tree of operators, a list of literals,
+ * a list of function names, and an array of Tcl_Token's within a Tcl_Parse
+ * struct. The tree is composed of OpNodes.
*/
-#ifndef TCL_GENERIC_ONLY
-#include "tclPort.h"
-#else
-#define NO_ERRNO_H
-#endif
+typedef struct OpNode {
+ int left; /* "Pointer" to the left operand. */
+ int right; /* "Pointer" to the right operand. */
+ union {
+ int parent; /* "Pointer" to the parent operand. */
+ int prev; /* "Pointer" joining incomplete tree stack */
+ } p;
+ unsigned char lexeme; /* Code that identifies the operator. */
+ unsigned char precedence; /* Precedence of the operator */
+ unsigned char mark; /* Mark used to control traversal. */
+ unsigned char constant; /* Flag marking constant subexpressions. */
+} OpNode;
+
+/*
+ * The storage for the tree is dynamically allocated array of OpNodes. The
+ * array is grown as parsing needs dictate according to a scheme similar to
+ * Tcl's string growth algorithm, so that the resizing costs are O(N) and so
+ * that we use at least half the memory allocated as expressions get large.
+ *
+ * Each OpNode in the tree represents an operator in the expression, either
+ * unary or binary. When parsing is completed successfully, a binary operator
+ * OpNode will have its left and right fields filled with "pointers" to its
+ * left and right operands. A unary operator OpNode will have its right field
+ * filled with a pointer to its single operand. When an operand is a
+ * subexpression the "pointer" takes the form of the index -- a non-negative
+ * integer -- into the OpNode storage array where the root of that
+ * subexpression parse tree is found.
+ *
+ * Non-operator elements of the expression do not get stored in the OpNode
+ * tree. They are stored in the other structures according to their type.
+ * Literal values get appended to the literal list. Elements that denote
+ * forms of quoting or substitution known to the Tcl parser get stored as
+ * Tcl_Tokens. These non-operator elements of the expression are the
+ * leaves of the completed parse tree. When an operand of an OpNode is
+ * one of these leaf elements, the following negative integer codes are used
+ * to indicate which kind of elements it is.
+ */
-#ifdef NO_ERRNO_H
-extern int errno; /* Use errno from tclExecute.c. */
-#define ERANGE 34
-#endif
+enum OperandTypes {
+ OT_LITERAL = -3, /* Operand is a literal in the literal list */
+ OT_TOKENS = -2, /* Operand is sequence of Tcl_Tokens */
+ OT_EMPTY = -1 /* "Operand" is an empty string. This is a
+ * special case used only to represent the
+ * EMPTY lexeme. See below. */
+};
/*
- * Boolean variable that controls whether expression compilation tracing
- * is enabled.
+ * Readable macros to test whether a "pointer" value points to an operator.
+ * They operate on the "non-negative integer -> operator; negative integer ->
+ * a non-operator OperandType" distinction.
*/
-#ifdef TCL_COMPILE_DEBUG
-static int traceExprComp = 0;
-#endif /* TCL_COMPILE_DEBUG */
+#define IsOperator(l) ((l) >= 0)
+#define NotOperator(l) ((l) < 0)
/*
- * The ExprInfo structure describes the state of compiling an expression.
- * A pointer to an ExprInfo record is passed among the routines in
- * this module.
+ * Note that it is sufficient to store in the tree just the type of leaf
+ * operand, without any explicit pointer to which leaf. This is true because
+ * the traversals of the completed tree we perform are known to visit
+ * the leaves in the same order as the original parse.
+ *
+ * In a completed parse tree, those OpNodes that are themselves (roots of
+ * subexpression trees that are) operands of some operator store in their
+ * p.parent field a "pointer" to the OpNode of that operator. The p.parent
+ * field permits a traversal of the tree within a * non-recursive routine
+ * (ConvertTreeToTokens() and CompileExprTree()). This means that even
+ * expression trees of great depth pose no risk of blowing the C stack.
+ *
+ * While the parse tree is being constructed, the same memory space is used
+ * to hold the p.prev field which chains together a stack of incomplete
+ * trees awaiting their right operands.
+ *
+ * The lexeme field is filled in with the lexeme of the operator that is
+ * returned by the ParseLexeme() routine. Only lexemes for unary and
+ * binary operators get stored in an OpNode. Other lexmes get different
+ * treatement.
+ *
+ * The precedence field provides a place to store the precedence of the
+ * operator, so it need not be looked up again and again.
+ *
+ * The mark field is use to control the traversal of the tree, so
+ * that it can be done non-recursively. The mark values are:
*/
-typedef struct ExprInfo {
- Tcl_Interp *interp; /* Used for error reporting. */
- Tcl_Parse *parsePtr; /* Structure filled with information about
- * the parsed expression. */
- CONST char *expr; /* The expression that was originally passed
- * to TclCompileExpr. */
- CONST char *lastChar; /* Points just after last byte of expr. */
- int hasOperators; /* Set 1 if the expr has operators; 0 if
- * expr is only a primary. If 1 after
- * compiling an expr, a tryCvtToNumeric
- * instruction is emitted to convert the
- * primary to a number if possible. */
-} ExprInfo;
+enum Marks {
+ MARK_LEFT, /* Next step of traversal is to visit left subtree */
+ MARK_RIGHT, /* Next step of traversal is to visit right subtree */
+ MARK_PARENT /* Next step of traversal is to return to parent */
+};
/*
- * Definitions of numeric codes representing each expression operator.
- * The order of these must match the entries in the operatorTable below.
- * Also the codes for the relational operators (OP_LESS, OP_GREATER,
- * OP_LE, OP_GE, OP_EQ, and OP_NE) must be consecutive and in that order.
- * Note that OP_PLUS and OP_MINUS represent both unary and binary operators.
+ * The constant field is a boolean flag marking which subexpressions are
+ * completely known at compile time, and are eligible for computing then
+ * rather than waiting until run time.
*/
-#define OP_MULT 0
-#define OP_DIVIDE 1
-#define OP_MOD 2
-#define OP_PLUS 3
-#define OP_MINUS 4
-#define OP_LSHIFT 5
-#define OP_RSHIFT 6
-#define OP_LESS 7
-#define OP_GREATER 8
-#define OP_LE 9
-#define OP_GE 10
-#define OP_EQ 11
-#define OP_NEQ 12
-#define OP_BITAND 13
-#define OP_BITXOR 14
-#define OP_BITOR 15
-#define OP_LAND 16
-#define OP_LOR 17
-#define OP_QUESTY 18
-#define OP_LNOT 19
-#define OP_BITNOT 20
-#define OP_STREQ 21
-#define OP_STRNEQ 22
+/*
+ * Each lexeme belongs to one of four categories, which determine
+ * its place in the parse tree. We use the two high bits of the
+ * (unsigned char) value to store a NODE_TYPE code.
+ */
+
+#define NODE_TYPE 0xC0
+
+/*
+ * The four category values are LEAF, UNARY, and BINARY, explained below,
+ * and "uncategorized", which is used either temporarily, until context
+ * determines which of the other three categories is correct, or for
+ * lexemes like INVALID, which aren't really lexemes at all, but indicators
+ * of a parsing error. Note that the codes must be distinct to distinguish
+ * categories, but need not take the form of a bit array.
+ */
+#define BINARY 0x40 /* This lexeme is a binary operator. An
+ * OpNode representing it should go into the
+ * parse tree, and two operands should be
+ * parsed for it in the expression. */
+#define UNARY 0x80 /* This lexeme is a unary operator. An OpNode
+ * representing it should go into the parse
+ * tree, and one operand should be parsed for
+ * it in the expression. */
+#define LEAF 0xC0 /* This lexeme is a leaf operand in the parse
+ * tree. No OpNode will be placed in the tree
+ * for it. Either a literal value will be
+ * appended to the list of literals in this
+ * expression, or appropriate Tcl_Tokens will
+ * be appended in a Tcl_Parse struct to
+ * represent those leaves that require some
+ * form of substitution.
+ */
+
+/* Uncategorized lexemes */
+
+#define PLUS 1 /* Ambiguous. Resolves to UNARY_PLUS or
+ * BINARY_PLUS according to context. */
+#define MINUS 2 /* Ambiguous. Resolves to UNARY_MINUS or
+ * BINARY_MINUS according to context. */
+#define BAREWORD 3 /* Ambigous. Resolves to BOOLEAN or to
+ * FUNCTION or a parse error according to
+ * context and value. */
+#define INCOMPLETE 4 /* A parse error. Used only when the single
+ * "=" is encountered. */
+#define INVALID 5 /* A parse error. Used when any punctuation
+ * appears that's not a supported operator. */
+
+/* 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() */
+
+/* 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)
+
+/* 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. */
/*
- * Table describing the expression operators. Entries in this table must
- * correspond to the definitions of numeric codes for operators just above.
+ * 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.
*/
-static int opTableInitialized = 0; /* 0 means not yet initialized. */
-
-TCL_DECLARE_MUTEX(opMutex)
-
-typedef struct OperatorDesc {
- char *name; /* Name of the operator. */
- int numOperands; /* Number of operands. 0 if the operator
- * requires special handling. */
- int instruction; /* Instruction opcode for the operator.
- * Ignored if numOperands is 0. */
-} OperatorDesc;
-
-static OperatorDesc operatorTable[] = {
- {"*", 2, INST_MULT},
- {"/", 2, INST_DIV},
- {"%", 2, INST_MOD},
- {"+", 0},
- {"-", 0},
- {"<<", 2, INST_LSHIFT},
- {">>", 2, INST_RSHIFT},
- {"<", 2, INST_LT},
- {">", 2, INST_GT},
- {"<=", 2, INST_LE},
- {">=", 2, INST_GE},
- {"==", 2, INST_EQ},
- {"!=", 2, INST_NEQ},
- {"&", 2, INST_BITAND},
- {"^", 2, INST_BITXOR},
- {"|", 2, INST_BITOR},
- {"&&", 0},
- {"||", 0},
- {"?", 0},
- {"!", 1, INST_LNOT},
- {"~", 1, INST_BITNOT},
- {"eq", 2, INST_STR_EQ},
- {"ne", 2, INST_STR_NEQ},
- {NULL}
+enum Precedence {
+ PREC_END = 1, /* END */
+ PREC_START, /* START */
+ PREC_CLOSE_PAREN, /* ")" */
+ PREC_OPEN_PAREN, /* "(" */
+ PREC_COMMA, /* "," */
+ PREC_CONDITIONAL, /* "?", ":" */
+ PREC_OR, /* "||" */
+ PREC_AND, /* "&&" */
+ PREC_BIT_OR, /* "|" */
+ PREC_BIT_XOR, /* "^" */
+ PREC_BIT_AND, /* "&" */
+ PREC_EQUAL, /* "==", "!=", "eq", "ne", "in", "ni" */
+ PREC_COMPARE, /* "<", ">", "<=", ">=" */
+ PREC_SHIFT, /* "<<", ">>" */
+ PREC_ADD, /* "+", "-" */
+ PREC_MULT, /* "*", "/", "%" */
+ PREC_EXPON, /* "**" */
+ PREC_UNARY /* "+", "-", FUNCTION, "!", "~" */
};
/*
- * Hashtable used to map the names of expression operators to the index
- * of their OperatorDesc description.
+ * 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 Tcl_HashTable opHashTable;
+static const unsigned char prec[] = {
+ /* Non-operator lexemes */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,
+ /* Binary operator lexemes */
+ PREC_ADD, /* BINARY_PLUS */
+ PREC_ADD, /* BINARY_MINUS */
+ PREC_COMMA, /* COMMA */
+ PREC_MULT, /* MULT */
+ PREC_MULT, /* DIVIDE */
+ PREC_MULT, /* MOD */
+ PREC_COMPARE, /* LESS */
+ PREC_COMPARE, /* GREATER */
+ PREC_BIT_AND, /* BIT_AND */
+ PREC_BIT_XOR, /* BIT_XOR */
+ PREC_BIT_OR, /* BIT_OR */
+ PREC_CONDITIONAL, /* QUESTION */
+ PREC_CONDITIONAL, /* COLON */
+ PREC_SHIFT, /* LEFT_SHIFT */
+ PREC_SHIFT, /* RIGHT_SHIFT */
+ PREC_COMPARE, /* LEQ */
+ PREC_COMPARE, /* GEQ */
+ PREC_EQUAL, /* EQUAL */
+ PREC_EQUAL, /* NEQ */
+ PREC_AND, /* AND */
+ PREC_OR, /* OR */
+ PREC_EQUAL, /* STREQ */
+ PREC_EQUAL, /* STRNEQ */
+ PREC_EXPON, /* EXPON */
+ PREC_EQUAL, /* IN_LIST */
+ PREC_EQUAL, /* NOT_IN_LIST */
+ PREC_CLOSE_PAREN, /* CLOSE_PAREN */
+ PREC_END, /* END */
+ /* Expansion room for more binary operators */
+ 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,
+ /* Unary operator lexemes */
+ PREC_UNARY, /* UNARY_PLUS */
+ PREC_UNARY, /* UNARY_MINUS */
+ PREC_UNARY, /* FUNCTION */
+ PREC_START, /* START */
+ PREC_OPEN_PAREN, /* OPEN_PAREN */
+ PREC_UNARY, /* NOT*/
+ PREC_UNARY, /* BIT_NOT*/
+};
/*
- * Declarations for local procedures to this file:
+ * A table mapping lexemes to bytecode instructions, used by CompileExprTree().
*/
-static int CompileCondExpr _ANSI_ARGS_((
- Tcl_Token *exprTokenPtr, ExprInfo *infoPtr,
- CompileEnv *envPtr, Tcl_Token **endPtrPtr));
-static int CompileLandOrLorExpr _ANSI_ARGS_((
- Tcl_Token *exprTokenPtr, int opIndex,
- ExprInfo *infoPtr, CompileEnv *envPtr,
- Tcl_Token **endPtrPtr));
-static int CompileMathFuncCall _ANSI_ARGS_((
- Tcl_Token *exprTokenPtr, CONST char *funcName,
- ExprInfo *infoPtr, CompileEnv *envPtr,
- Tcl_Token **endPtrPtr));
-static int CompileSubExpr _ANSI_ARGS_((
- Tcl_Token *exprTokenPtr, ExprInfo *infoPtr,
- CompileEnv *envPtr));
-static void LogSyntaxError _ANSI_ARGS_((ExprInfo *infoPtr));
+static const unsigned char instruction[] = {
+ /* Non-operator lexemes */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,
+ /* Binary operator lexemes */
+ INST_ADD, /* BINARY_PLUS */
+ INST_SUB, /* BINARY_MINUS */
+ 0, /* COMMA */
+ INST_MULT, /* MULT */
+ INST_DIV, /* DIVIDE */
+ INST_MOD, /* MOD */
+ INST_LT, /* LESS */
+ INST_GT, /* GREATER */
+ INST_BITAND, /* BIT_AND */
+ INST_BITXOR, /* BIT_XOR */
+ INST_BITOR, /* BIT_OR */
+ 0, /* QUESTION */
+ 0, /* COLON */
+ INST_LSHIFT, /* LEFT_SHIFT */
+ INST_RSHIFT, /* RIGHT_SHIFT */
+ INST_LE, /* LEQ */
+ INST_GE, /* GEQ */
+ INST_EQ, /* EQUAL */
+ INST_NEQ, /* NEQ */
+ 0, /* AND */
+ 0, /* OR */
+ INST_STR_EQ, /* STREQ */
+ INST_STR_NEQ, /* STRNEQ */
+ INST_EXPON, /* EXPON */
+ INST_LIST_IN, /* IN_LIST */
+ INST_LIST_NOT_IN, /* NOT_IN_LIST */
+ 0, /* CLOSE_PAREN */
+ 0, /* END */
+ /* Expansion room for more binary operators */
+ 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,
+ /* Unary operator lexemes */
+ INST_UPLUS, /* UNARY_PLUS */
+ INST_UMINUS, /* UNARY_MINUS */
+ 0, /* FUNCTION */
+ 0, /* START */
+ 0, /* OPEN_PAREN */
+ INST_LNOT, /* NOT*/
+ INST_BITNOT, /* BIT_NOT*/
+};
/*
- * Macro used to debug the execution of the expression compiler.
+ * A table mapping a byte value to the corresponding lexeme for use by
+ * ParseLexeme().
*/
-#ifdef TCL_COMPILE_DEBUG
-#define TRACE(exprBytes, exprLength, tokenBytes, tokenLength) \
- if (traceExprComp) { \
- fprintf(stderr, "CompileSubExpr: \"%.*s\", token \"%.*s\"\n", \
- (exprLength), (exprBytes), (tokenLength), (tokenBytes)); \
- }
-#else
-#define TRACE(exprBytes, exprLength, tokenBytes, tokenLength)
-#endif /* TCL_COMPILE_DEBUG */
+static unsigned char Lexeme[] = {
+ INVALID /* NUL */, INVALID /* SOH */,
+ INVALID /* STX */, INVALID /* ETX */,
+ INVALID /* EOT */, INVALID /* ENQ */,
+ INVALID /* ACK */, INVALID /* BEL */,
+ INVALID /* BS */, INVALID /* HT */,
+ INVALID /* LF */, INVALID /* VT */,
+ INVALID /* FF */, INVALID /* CR */,
+ INVALID /* SO */, INVALID /* SI */,
+ INVALID /* DLE */, INVALID /* DC1 */,
+ INVALID /* DC2 */, INVALID /* DC3 */,
+ INVALID /* DC4 */, INVALID /* NAK */,
+ INVALID /* SYN */, INVALID /* ETB */,
+ INVALID /* CAN */, INVALID /* EM */,
+ INVALID /* SUB */, INVALID /* ESC */,
+ INVALID /* FS */, INVALID /* GS */,
+ INVALID /* RS */, INVALID /* US */,
+ INVALID /* SPACE */, 0 /* ! or != */,
+ QUOTED /* " */, INVALID /* # */,
+ VARIABLE /* $ */, MOD /* % */,
+ 0 /* & or && */, INVALID /* ' */,
+ OPEN_PAREN /* ( */, CLOSE_PAREN /* ) */,
+ 0 /* * or ** */, PLUS /* + */,
+ COMMA /* , */, MINUS /* - */,
+ 0 /* . */, DIVIDE /* / */,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0-9 */
+ COLON /* : */, INVALID /* ; */,
+ 0 /* < or << or <= */,
+ 0 /* == or INVALID */,
+ 0 /* > or >> or >= */,
+ QUESTION /* ? */, INVALID /* @ */,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A-M */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* N-Z */
+ SCRIPT /* [ */, INVALID /* \ */,
+ INVALID /* ] */, BIT_XOR /* ^ */,
+ INVALID /* _ */, INVALID /* ` */,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a-m */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* n-z */
+ BRACED /* { */, 0 /* | or || */,
+ INVALID /* } */, BIT_NOT /* ~ */,
+ INVALID /* DEL */
+};
+
+/*
+ * The JumpList struct is used to create a stack of data needed for the
+ * TclEmitForwardJump() and TclFixupForwardJump() calls that are performed
+ * when compiling the short-circuiting operators QUESTION/COLON, AND, and OR.
+ * Keeping a stack permits the CompileExprTree() routine to be non-recursive.
+ */
+
+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;
+
+/*
+ * Declarations for local functions to this file:
+ */
+
+static void CompileExprTree(Tcl_Interp *interp, OpNode *nodes,
+ int index, Tcl_Obj *const **litObjvPtr,
+ Tcl_Obj *const *funcObjv, Tcl_Token *tokenPtr,
+ CompileEnv *envPtr, int optimize);
+static void ConvertTreeToTokens(const char *start, int numBytes,
+ OpNode *nodes, Tcl_Token *tokenPtr,
+ Tcl_Parse *parsePtr);
+static int ExecConstantExprTree(Tcl_Interp *interp, OpNode *nodes,
+ int index, Tcl_Obj * const **litObjvPtr);
+static int ParseExpr(Tcl_Interp *interp, const char *start,
+ int numBytes, OpNode **opTreePtr,
+ Tcl_Obj *litList, Tcl_Obj *funcList,
+ Tcl_Parse *parsePtr, int parseOnly);
+static int ParseLexeme(const char *start, int numBytes,
+ unsigned char *lexemePtr, Tcl_Obj **literalPtr);
+
/*
*----------------------------------------------------------------------
*
- * TclCompileExpr --
+ * ParseExpr --
*
- * This procedure compiles a string containing a Tcl expression into
- * Tcl bytecodes. This procedure is the top-level interface to the
- * the expression compilation module, and is used by such public
- * procedures as Tcl_ExprString, Tcl_ExprStringObj, Tcl_ExprLong,
- * Tcl_ExprDouble, Tcl_ExprBoolean, and Tcl_ExprBooleanObj.
+ * Given a string, the numBytes bytes starting at start, this function
+ * parses it as a Tcl expression and constructs a tree representing
+ * the structure of the expression. The caller must pass in empty
+ * lists as the funcList and litList arguments. The elements of the
+ * parsed expression are returned to the caller as that tree, a list of
+ * literal values, a list of function names, and in Tcl_Tokens
+ * added to a Tcl_Parse struct passed in by the caller.
*
* Results:
- * The return value is TCL_OK on a successful compilation and TCL_ERROR
- * on failure. If TCL_ERROR is returned, then the interpreter's result
- * contains an error message.
+ * If the string is successfully parsed as a valid Tcl expression, TCL_OK
+ * is returned, and data about the expression structure is written to
+ * the last four arguments. If the string cannot be parsed as a valid
+ * Tcl expression, TCL_ERROR is returned, and if interp is non-NULL, an
+ * error message is written to interp.
*
* Side effects:
- * Adds instructions to envPtr to evaluate the expression at runtime.
+ * Memory will be allocated. If TCL_OK is returned, the caller must
+ * clean up the returned data structures. The (OpNode *) value written
+ * to opTreePtr should be passed to ckfree() and the parsePtr argument
+ * should be passed to Tcl_FreeParse(). The elements appended to the
+ * litList and funcList will automatically be freed whenever the
+ * refcount on those lists indicates they can be freed.
*
*----------------------------------------------------------------------
*/
-int
-TclCompileExpr(interp, script, numBytes, envPtr)
- Tcl_Interp *interp; /* Used for error reporting. */
- CONST char *script; /* The source script to compile. */
- int numBytes; /* Number of bytes in script. If < 0, the
- * string consists of all bytes up to the
- * first null character. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
+static int
+ParseExpr(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ const char *start, /* Start of source string to parse. */
+ int numBytes, /* Number of bytes in string. */
+ OpNode **opTreePtr, /* Points to space where a pointer to the
+ * allocated OpNode tree should go. */
+ Tcl_Obj *litList, /* List to append literals to. */
+ Tcl_Obj *funcList, /* List to append function names to. */
+ Tcl_Parse *parsePtr, /* Structure to fill with tokens representing
+ * those operands that require run time
+ * substitutions. */
+ int parseOnly) /* A boolean indicating whether the caller's
+ * aim is just a parse, or whether it will go
+ * on to compile the expression. Different
+ * optimizations are appropriate for the
+ * two scenarios. */
{
- ExprInfo info;
- Tcl_Parse parse;
- Tcl_HashEntry *hPtr;
- int new, i, code;
+ OpNode *nodes = NULL; /* Pointer to the OpNode storage array where
+ * we build the parse tree. */
+ int nodesAvailable = 64; /* Initial size of the storage array. This
+ * value establishes a minimum tree memory cost
+ * of only about 1 kibyte, and is large enough
+ * for most expressions to parse with no need
+ * for array growth and reallocation. */
+ int nodesUsed = 0; /* Number of OpNodes filled. */
+ int scanned = 0; /* Capture number of byte scanned by
+ * parsing routines. */
+ int lastParsed; /* Stores info about what the lexeme parsed
+ * the previous pass through the parsing loop
+ * was. If it was an operator, lastParsed is
+ * the index of the OpNode for that operator.
+ * If it was not an operator, lastParsed holds
+ * an OperandTypes value encoding what we
+ * need to know about it. */
+ int incomplete; /* Index of the most recent incomplete tree
+ * in the OpNode array. Heads a stack of
+ * incomplete trees linked by p.prev. */
+ int complete = OT_EMPTY; /* "Index" of the complete tree (that is, a
+ * complete subexpression) determined at the
+ * moment. OT_EMPTY is a nonsense value
+ * used only to silence compiler warnings.
+ * During a parse, complete will always hold
+ * an index or an OperandTypes value pointing
+ * to an actual leaf at the time the complete
+ * tree is needed. */
+
+ /* 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
+ * information after the error msg and
+ * location have been reported. */
+ const char *mark = "_@_"; /* In the portion of the complete error message
+ * where the error location is reported, this
+ * "mark" substring is inserted into the
+ * string being parsed to aid in pinpointing
+ * the location of the syntax error in the
+ * expression. */
+ int insertMark = 0; /* A boolean controlling whether the "mark"
+ * should be inserted. */
+ const int limit = 25; /* Portions of the error message are
+ * constructed out of substrings of the
+ * original expression. In order to keep the
+ * error message readable, we impose this limit
+ * on the substring size we extract. */
+
+ TclParseInit(interp, start, numBytes, parsePtr);
+
+ nodes = (OpNode *) attemptckalloc(nodesAvailable * sizeof(OpNode));
+ if (nodes == NULL) {
+ TclNewLiteralStringObj(msg, "not enough memory to parse expression");
+ goto error;
+ }
+
+ /* Initialize the parse tree with the special "START" node. */
+ nodes->lexeme = START;
+ nodes->precedence = prec[START];
+ nodes->mark = MARK_RIGHT;
+ nodes->constant = 1;
+ incomplete = lastParsed = nodesUsed;
+ nodesUsed++;
/*
- * If this is the first time we've been called, initialize the table
- * of expression operators.
+ * Main parsing loop parses one lexeme per iteration. We exit the
+ * loop only when there's a syntax error with a "goto error" which
+ * takes us to the error handling code following the loop, or when
+ * we've successfully completed the parse and we return to the caller.
*/
- if (numBytes < 0) {
- numBytes = (script? strlen(script) : 0);
- }
- if (!opTableInitialized) {
- Tcl_MutexLock(&opMutex);
- if (!opTableInitialized) {
- Tcl_InitHashTable(&opHashTable, TCL_STRING_KEYS);
- for (i = 0; operatorTable[i].name != NULL; i++) {
- hPtr = Tcl_CreateHashEntry(&opHashTable,
- operatorTable[i].name, &new);
- if (new) {
- Tcl_SetHashValue(hPtr, (ClientData) i);
- }
+ while (1) {
+ OpNode *nodePtr; /* Points to the OpNode we may fill this
+ * pass through the loop. */
+ unsigned char lexeme; /* The lexeme we parse this iteration. */
+ Tcl_Obj *literal; /* Filled by the ParseLexeme() call when
+ * a literal is parsed that has a Tcl_Obj
+ * rep worth preserving. */
+
+ /*
+ * Each pass through this loop adds up to one more OpNode. Allocate
+ * space for one if required.
+ */
+
+ if (nodesUsed >= nodesAvailable) {
+ int size = nodesUsed * 2;
+ OpNode *newPtr;
+
+ do {
+ newPtr = (OpNode *) attemptckrealloc((char *) nodes,
+ (unsigned int) size * sizeof(OpNode));
+ } while ((newPtr == NULL)
+ && ((size -= (size - nodesUsed) / 2) > nodesUsed));
+ if (newPtr == NULL) {
+ TclNewLiteralStringObj(msg,
+ "not enough memory to parse expression");
+ goto error;
}
- opTableInitialized = 1;
+ nodesAvailable = size;
+ nodes = newPtr;
}
- Tcl_MutexUnlock(&opMutex);
- }
+ nodePtr = nodes + nodesUsed;
+
+ /* Skip white space between lexemes. */
+ scanned = TclParseAllWhiteSpace(start, numBytes);
+ start += scanned;
+ numBytes -= scanned;
+
+ scanned = ParseLexeme(start, numBytes, &lexeme, &literal);
+
+ /* Use context to categorize the lexemes that are ambiguous. */
+ if ((NODE_TYPE & lexeme) == 0) {
+ switch (lexeme) {
+ case INVALID:
+ msg = Tcl_ObjPrintf(
+ "invalid character \"%.*s\"", scanned, start);
+ goto error;
+ case INCOMPLETE:
+ msg = Tcl_ObjPrintf(
+ "incomplete operator \"%.*s\"", scanned, start);
+ goto error;
+ case BAREWORD:
+
+ /*
+ * Most barewords in an expression are a syntax error.
+ * The exceptions are that when a bareword is followed by
+ * an open paren, it might be a function call, and when the
+ * bareword is a legal literal boolean value, we accept that
+ * as well.
+ */
+
+ if (start[scanned+TclParseAllWhiteSpace(
+ start+scanned, numBytes-scanned)] == '(') {
+ lexeme = FUNCTION;
- /*
- * Initialize the structure containing information abvout this
- * expression compilation.
- */
+ /*
+ * When we compile the expression we'll need the function
+ * name, and there's no place in the parse tree to store
+ * it, so we keep a separate list of all the function
+ * names we've parsed in the order we found them.
+ */
- info.interp = interp;
- info.parsePtr = &parse;
- info.expr = script;
- info.lastChar = (script + numBytes);
- info.hasOperators = 0;
+ Tcl_ListObjAppendElement(NULL, funcList, literal);
+ } else {
+ int b;
+ if (Tcl_GetBooleanFromObj(NULL, literal, &b) == TCL_OK) {
+ lexeme = BOOLEAN;
+ } else {
+ Tcl_DecrRefCount(literal);
+ msg = Tcl_ObjPrintf(
+ "invalid bareword \"%.*s%s\"",
+ (scanned < limit) ? scanned : limit - 3, start,
+ (scanned < limit) ? "" : "...");
+ post = Tcl_ObjPrintf(
+ "should be \"$%.*s%s\" or \"{%.*s%s}\"",
+ (scanned < limit) ? scanned : limit - 3,
+ start, (scanned < limit) ? "" : "...",
+ (scanned < limit) ? scanned : limit - 3,
+ start, (scanned < limit) ? "" : "...");
+ Tcl_AppendPrintfToObj(post,
+ " or \"%.*s%s(...)\" or ...",
+ (scanned < limit) ? scanned : limit - 3,
+ start, (scanned < limit) ? "" : "...");
+ 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)) {
+ parsePtr->errorType = TCL_PARSE_BAD_NUMBER;
+
+ switch (start[1]) {
+ case 'b':
+ Tcl_AppendToObj(post,
+ " (invalid binary number?)", -1);
+ break;
+ case 'o':
+ Tcl_AppendToObj(post,
+ " (invalid octal number?)", -1);
+ break;
+ default:
+ if (isdigit(UCHAR(start[1]))) {
+ Tcl_AppendToObj(post,
+ " (invalid octal number?)", -1);
+ }
+ break;
+ }
+ }
+ }
+ goto error;
+ }
+ }
+ break;
+ case PLUS:
+ case MINUS:
+ if (IsOperator(lastParsed)) {
+
+ /*
+ * A "+" or "-" coming just after another operator
+ * must be interpreted as a unary operator.
+ */
+
+ lexeme |= UNARY;
+ } else {
+ lexeme |= BINARY;
+ }
+ }
+ } /* 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.
+ */
+
+ case LEAF: {
+ Tcl_Token *tokenPtr;
+ const char *end = start;
+ int wordIndex;
+ int code = TCL_OK;
+
+ /*
+ * A leaf operand appearing just after something that's not an
+ * operator is a syntax error.
+ */
+
+ if (NotOperator(lastParsed)) {
+ msg = Tcl_ObjPrintf("missing operator at %s", mark);
+ scanned = 0;
+ insertMark = 1;
+
+ /* Free any literal to avoid a memleak. */
+ if ((lexeme == NUMBER) || (lexeme == BOOLEAN)) {
+ Tcl_DecrRefCount(literal);
+ }
+ goto error;
+ }
+
+ switch (lexeme) {
+ case NUMBER:
+ case BOOLEAN:
+ /*
+ * TODO: Consider using a dict or hash to collapse all
+ * duplicate literals into a single representative value.
+ * (Like what is done with [split $s {}]).
+ * Pro: ~75% memory saving on expressions like
+ * {1+1+1+1+1+.....+1} (Convert "pointer + Tcl_Obj" cost
+ * to "pointer" cost only)
+ * Con: Cost of the dict store/retrieve on every literal
+ * in every expression when expressions like the above
+ * tend to be uncommon.
+ * The memory savings is temporary; Compiling to bytecode
+ * will collapse things as literals are registered
+ * anyway, so the savings applies only to the time
+ * between parsing and compiling. Possibly important
+ * due to high-water mark nature of memory allocation.
+ */
+ Tcl_ListObjAppendElement(NULL, litList, literal);
+ complete = lastParsed = OT_LITERAL;
+ start += scanned;
+ numBytes -= scanned;
+ continue;
+
+ default:
+ break;
+ }
+
+ /*
+ * Remaining LEAF cases may involve filling Tcl_Tokens, so
+ * make room for at least 2 more tokens.
+ */
+
+ TclGrowParseTokenArray(parsePtr, 2);
+ wordIndex = parsePtr->numTokens;
+ tokenPtr = parsePtr->tokenPtr + wordIndex;
+ tokenPtr->type = TCL_TOKEN_WORD;
+ tokenPtr->start = start;
+ parsePtr->numTokens++;
+
+ switch (lexeme) {
+ case QUOTED:
+ code = Tcl_ParseQuotedString(NULL, start, numBytes,
+ parsePtr, 1, &end);
+ scanned = end - start;
+ break;
+
+ case BRACED:
+ code = Tcl_ParseBraces(NULL, start, numBytes,
+ parsePtr, 1, &end);
+ scanned = end - start;
+ break;
+
+ case VARIABLE:
+ code = Tcl_ParseVarName(NULL, start, numBytes, parsePtr, 1);
+
+ /*
+ * Handle the quirk that Tcl_ParseVarName reports a successful
+ * parse even when it gets only a "$" with no variable name.
+ */
+
+ tokenPtr = parsePtr->tokenPtr + wordIndex + 1;
+ if (code == TCL_OK && tokenPtr->type != TCL_TOKEN_VARIABLE) {
+ TclNewLiteralStringObj(msg, "invalid character \"$\"");
+ goto error;
+ }
+ scanned = tokenPtr->size;
+ break;
+
+ case SCRIPT: {
+ Tcl_Parse *nestedPtr =
+ (Tcl_Parse *) TclStackAlloc(interp, sizeof(Tcl_Parse));
+
+ tokenPtr = parsePtr->tokenPtr + parsePtr->numTokens;
+ tokenPtr->type = TCL_TOKEN_COMMAND;
+ tokenPtr->start = start;
+ tokenPtr->numComponents = 0;
+
+ end = start + numBytes;
+ start++;
+ while (1) {
+ code = Tcl_ParseCommand(interp, start, (end - start), 1,
+ nestedPtr);
+ if (code != TCL_OK) {
+ parsePtr->term = nestedPtr->term;
+ parsePtr->errorType = nestedPtr->errorType;
+ parsePtr->incomplete = nestedPtr->incomplete;
+ break;
+ }
+ start = (nestedPtr->commandStart + nestedPtr->commandSize);
+ Tcl_FreeParse(nestedPtr);
+ if ((nestedPtr->term < end) && (*(nestedPtr->term) == ']')
+ && !(nestedPtr->incomplete)) {
+ break;
+ }
+
+ if (start == end) {
+ TclNewLiteralStringObj(msg, "missing close-bracket");
+ parsePtr->term = tokenPtr->start;
+ parsePtr->errorType = TCL_PARSE_MISSING_BRACKET;
+ parsePtr->incomplete = 1;
+ code = TCL_ERROR;
+ break;
+ }
+ }
+ TclStackFree(interp, nestedPtr);
+ end = start;
+ start = tokenPtr->start;
+ scanned = end - start;
+ tokenPtr->size = scanned;
+ parsePtr->numTokens++;
+ break;
+ }
+ }
+ if (code != TCL_OK) {
+
+ /*
+ * Here we handle all the syntax errors generated by
+ * the Tcl_Token generating parsing routines called in the
+ * switch just above. If the value of parsePtr->incomplete
+ * is 1, then the error was an unbalanced '[', '(', '{',
+ * or '"' and parsePtr->term is pointing to that unbalanced
+ * character. If the value of parsePtr->incomplete is 0,
+ * then the error is one of lacking whitespace following a
+ * quoted word, for example: expr {[an error {foo}bar]},
+ * and parsePtr->term points to where the whitespace is
+ * missing. We reset our values of start and scanned so that
+ * when our error message is constructed, the location of
+ * the syntax error is sure to appear in it, even if the
+ * quoted expression is truncated.
+ */
+
+ start = parsePtr->term;
+ scanned = parsePtr->incomplete;
+ goto error;
+ }
+
+ tokenPtr = parsePtr->tokenPtr + wordIndex;
+ tokenPtr->size = scanned;
+ tokenPtr->numComponents = parsePtr->numTokens - wordIndex - 1;
+ if (!parseOnly && ((lexeme == QUOTED) || (lexeme == BRACED))) {
+
+ /*
+ * When this expression is destined to be compiled, and a
+ * braced or quoted word within an expression is known at
+ * compile time (no runtime substitutions in it), we can
+ * store it as a literal rather than in its tokenized form.
+ * This is an advantage since the compiled bytecode is going
+ * to need the argument in Tcl_Obj form eventually, so it's
+ * just as well to get there now. Another advantage is that
+ * with this conversion, larger constant expressions might
+ * be grown and optimized.
+ *
+ * On the contrary, if the end goal of this parse is to
+ * fill a Tcl_Parse for a caller of Tcl_ParseExpr(), then it's
+ * wasteful to convert to a literal only to convert back again
+ * later.
+ */
+
+ literal = Tcl_NewObj();
+ if (TclWordKnownAtCompileTime(tokenPtr, literal)) {
+ Tcl_ListObjAppendElement(NULL, litList, literal);
+ complete = lastParsed = OT_LITERAL;
+ parsePtr->numTokens = wordIndex;
+ break;
+ }
+ Tcl_DecrRefCount(literal);
+ }
+ complete = lastParsed = OT_TOKENS;
+ break;
+ } /* case LEAF */
+
+ case UNARY:
+
+ /*
+ * A unary operator appearing just after something that's not an
+ * operator is a syntax error -- something trying to be the left
+ * operand of an operator that doesn't take one.
+ */
+
+ if (NotOperator(lastParsed)) {
+ msg = Tcl_ObjPrintf("missing operator at %s", mark);
+ scanned = 0;
+ insertMark = 1;
+ goto error;
+ }
+
+ /* Create an OpNode for the unary operator */
+ nodePtr->lexeme = lexeme;
+ nodePtr->precedence = prec[lexeme];
+ nodePtr->mark = MARK_RIGHT;
+
+ /*
+ * A FUNCTION cannot be a constant expression, because Tcl allows
+ * functions to return variable results with the same arguments;
+ * for example, rand(). Other unary operators can root a constant
+ * expression, so long as the argument is a constant expression.
+ */
+
+ nodePtr->constant = (lexeme != FUNCTION);
+
+ /*
+ * This unary operator is a new incomplete tree, so push it
+ * onto our stack of incomplete trees. Also remember it as
+ * the last lexeme we parsed.
+ */
+
+ nodePtr->p.prev = incomplete;
+ incomplete = lastParsed = nodesUsed;
+ nodesUsed++;
+ break;
+
+ case BINARY: {
+ OpNode *incompletePtr;
+ unsigned char precedence = prec[lexeme];
+
+ /*
+ * A binary operator appearing just after another operator is a
+ * syntax error -- one of the two operators is missing an operand.
+ */
+
+ if (IsOperator(lastParsed)) {
+ if ((lexeme == CLOSE_PAREN)
+ && (nodePtr[-1].lexeme == OPEN_PAREN)) {
+ if (nodePtr[-2].lexeme == FUNCTION) {
+
+ /*
+ * Normally, "()" is a syntax error, but as a special
+ * case accept it as an argument list for a function.
+ * Treat this as a special LEAF lexeme, and restart
+ * the parsing loop with zero characters scanned.
+ * We'll parse the ")" again the next time through,
+ * but with the OT_EMPTY leaf as the subexpression
+ * between the parens.
+ */
+
+ scanned = 0;
+ complete = lastParsed = OT_EMPTY;
+ break;
+ }
+ msg = Tcl_ObjPrintf("empty subexpression at %s", mark);
+ scanned = 0;
+ insertMark = 1;
+ goto error;
+ }
+
+ if (nodePtr[-1].precedence > precedence) {
+ if (nodePtr[-1].lexeme == OPEN_PAREN) {
+ TclNewLiteralStringObj(msg, "unbalanced open paren");
+ parsePtr->errorType = TCL_PARSE_MISSING_PAREN;
+ } else if (nodePtr[-1].lexeme == COMMA) {
+ msg = Tcl_ObjPrintf(
+ "missing function argument at %s", mark);
+ scanned = 0;
+ insertMark = 1;
+ } else if (nodePtr[-1].lexeme == START) {
+ TclNewLiteralStringObj(msg, "empty expression");
+ }
+ } else {
+ if (lexeme == CLOSE_PAREN) {
+ TclNewLiteralStringObj(msg, "unbalanced close paren");
+ } else if ((lexeme == COMMA)
+ && (nodePtr[-1].lexeme == OPEN_PAREN)
+ && (nodePtr[-2].lexeme == FUNCTION)) {
+ msg = Tcl_ObjPrintf(
+ "missing function argument at %s", mark);
+ scanned = 0;
+ insertMark = 1;
+ }
+ }
+ if (msg == NULL) {
+ msg = Tcl_ObjPrintf("missing operand at %s", mark);
+ scanned = 0;
+ insertMark = 1;
+ }
+ goto error;
+ }
+
+ /*
+ * Here is where the tree comes together. At this point, we
+ * have a stack of incomplete trees corresponding to
+ * substrings that are incomplete expressions, followed by
+ * a complete tree corresponding to a substring that is itself
+ * a complete expression, followed by the binary operator we have
+ * just parsed. The incomplete trees can each be completed by
+ * adding a right operand.
+ *
+ * To illustrate with an example, when we parse the expression
+ * "1+2*3-4" and we reach this point having just parsed the "-"
+ * operator, we have these incomplete trees: START, "1+", and
+ * "2*". Next we have the complete subexpression "3". Last is
+ * the "-" we've just parsed.
+ *
+ * The next step is to join our complete tree to an operator.
+ * The choice is governed by the precedence and associativity
+ * of the competing operators. If we connect it as the right
+ * operand of our most recent incomplete tree, we get a new
+ * complete tree, and we can repeat the process. The while
+ * loop following repeats this until precedence indicates it
+ * is time to join the complete tree as the left operand of
+ * the just parsed binary operator.
+ *
+ * Continuing the example, the first pass through the loop
+ * will join "3" to "2*"; the next pass will join "2*3" to
+ * "1+". Then we'll exit the loop and join "1+2*3" to "-".
+ * When we return to parse another lexeme, our stack of
+ * incomplete trees is START and "1+2*3-".
+ */
+
+ while (1) {
+ incompletePtr = nodes + incomplete;
+
+ if (incompletePtr->precedence < precedence) {
+ break;
+ }
+
+ if (incompletePtr->precedence == precedence) {
+
+ /* Right association rules for exponentiation. */
+ if (lexeme == EXPON) {
+ break;
+ }
+
+ /*
+ * Special association rules for the conditional operators.
+ * The "?" and ":" operators have equal precedence, but
+ * must be linked up in sensible pairs.
+ */
+
+ if ((incompletePtr->lexeme == QUESTION)
+ && (NotOperator(complete)
+ || (nodes[complete].lexeme != COLON))) {
+ break;
+ }
+ if ((incompletePtr->lexeme == COLON)
+ && (lexeme == QUESTION)) {
+ break;
+ }
+ }
+
+ /* Some special syntax checks... */
+
+ /* Parens must balance */
+ if ((incompletePtr->lexeme == OPEN_PAREN)
+ && (lexeme != CLOSE_PAREN)) {
+ TclNewLiteralStringObj(msg, "unbalanced open paren");
+ parsePtr->errorType = TCL_PARSE_MISSING_PAREN;
+ goto error;
+ }
+
+ /* Right operand of "?" must be ":" */
+ if ((incompletePtr->lexeme == QUESTION)
+ && (NotOperator(complete)
+ || (nodes[complete].lexeme != COLON))) {
+ msg = Tcl_ObjPrintf(
+ "missing operator \":\" at %s", mark);
+ scanned = 0;
+ insertMark = 1;
+ goto error;
+ }
+
+ /* Operator ":" may only be right operand of "?" */
+ if (IsOperator(complete)
+ && (nodes[complete].lexeme == COLON)
+ && (incompletePtr->lexeme != QUESTION)) {
+ TclNewLiteralStringObj(msg,
+ "unexpected operator \":\" "
+ "without preceding \"?\"");
+ goto error;
+ }
+
+ /*
+ * Attach complete tree as right operand of most recent
+ * incomplete tree.
+ */
+
+ incompletePtr->right = complete;
+ if (IsOperator(complete)) {
+ nodes[complete].p.parent = incomplete;
+ incompletePtr->constant = incompletePtr->constant
+ && nodes[complete].constant;
+ } else {
+ incompletePtr->constant = incompletePtr->constant
+ && (complete == OT_LITERAL);
+ }
+
+ /*
+ * The QUESTION/COLON and FUNCTION/OPEN_PAREN combinations each
+ * make up a single operator. Force them to agree whether they
+ * have a constant expression.
+ */
+
+ if ((incompletePtr->lexeme == QUESTION)
+ || (incompletePtr->lexeme == FUNCTION)) {
+ nodes[complete].constant = incompletePtr->constant;
+ }
+
+ if (incompletePtr->lexeme == START) {
+
+ /*
+ * Completing the START tree indicates we're done.
+ * Transfer the parse tree to the caller and return.
+ */
+
+ *opTreePtr = nodes;
+ return TCL_OK;
+ }
+
+ /*
+ * With a right operand attached, last incomplete tree has
+ * become the complete tree. Pop it from the incomplete
+ * tree stack.
+ */
+
+ complete = incomplete;
+ incomplete = incompletePtr->p.prev;
+
+ /* CLOSE_PAREN can only close one OPEN_PAREN. */
+ if (incompletePtr->lexeme == OPEN_PAREN) {
+ break;
+ }
+ }
+
+ /* More syntax checks... */
+
+ /* Parens must balance. */
+ if (lexeme == CLOSE_PAREN) {
+ if (incompletePtr->lexeme != OPEN_PAREN) {
+ TclNewLiteralStringObj(msg, "unbalanced close paren");
+ goto error;
+ }
+ }
+
+ /* Commas must appear only in function argument lists. */
+ if (lexeme == COMMA) {
+ if ((incompletePtr->lexeme != OPEN_PAREN)
+ || (incompletePtr[-1].lexeme != FUNCTION)) {
+ TclNewLiteralStringObj(msg,
+ "unexpected \",\" outside function argument list");
+ goto error;
+ }
+ }
+
+ /* Operator ":" may only be right operand of "?" */
+ if (IsOperator(complete) && (nodes[complete].lexeme == COLON)) {
+ TclNewLiteralStringObj(msg,
+ "unexpected operator \":\" without preceding \"?\"");
+ goto error;
+ }
+
+ /* Create no node for a CLOSE_PAREN lexeme. */
+ if (lexeme == CLOSE_PAREN) {
+ break;
+ }
+
+ /* Link complete tree as left operand of new node. */
+ nodePtr->lexeme = lexeme;
+ nodePtr->precedence = precedence;
+ nodePtr->mark = MARK_LEFT;
+ nodePtr->left = complete;
+
+ /*
+ * The COMMA operator cannot be optimized, since the function
+ * needs all of its arguments, and optimization would reduce
+ * the number. Other binary operators root constant expressions
+ * when both arguments are constant expressions.
+ */
+
+ nodePtr->constant = (lexeme != COMMA);
+
+ if (IsOperator(complete)) {
+ nodes[complete].p.parent = nodesUsed;
+ nodePtr->constant = nodePtr->constant
+ && nodes[complete].constant;
+ } else {
+ nodePtr->constant = nodePtr->constant
+ && (complete == OT_LITERAL);
+ }
+
+ /*
+ * With a left operand attached and a right operand missing,
+ * the just-parsed binary operator is root of a new incomplete
+ * tree. Push it onto the stack of incomplete trees.
+ */
+
+ nodePtr->p.prev = incomplete;
+ incomplete = lastParsed = nodesUsed;
+ nodesUsed++;
+ break;
+ } /* case BINARY */
+ } /* lexeme handler */
+
+ /* Advance past the just-parsed lexeme */
+ start += scanned;
+ numBytes -= scanned;
+ } /* main parsing loop */
+
+ error:
/*
- * Parse the expression then compile it.
+ * We only get here if there's been an error.
+ * Any errors that didn't get a suitable parsePtr->errorType,
+ * get recorded as syntax errors.
*/
- code = Tcl_ParseExpr(interp, script, numBytes, &parse);
- if (code != TCL_OK) {
- goto done;
+ if (parsePtr->errorType == TCL_PARSE_SUCCESS) {
+ parsePtr->errorType = TCL_PARSE_SYNTAX;
}
-#ifdef TCL_TIP280
- /* TIP #280 : Track Lines within the expression */
- TclAdvanceLines (&envPtr->line, script, parse.tokenPtr->start);
-#endif
-
- code = CompileSubExpr(parse.tokenPtr, &info, envPtr);
- if (code != TCL_OK) {
- Tcl_FreeParse(&parse);
- goto done;
+ /* Free any partial parse tree we've built. */
+ if (nodes != NULL) {
+ ckfree((char*) nodes);
}
-
- if (!info.hasOperators) {
+
+ if (interp == NULL) {
+
+ /* Nowhere to report an error message, so just free it */
+ if (msg) {
+ Tcl_DecrRefCount(msg);
+ }
+ } else {
+
/*
- * Attempt to convert the primary's object to an int or double.
- * This is done in order to support Tcl's policy of interpreting
- * operands if at all possible as first integers, else
- * floating-point numbers.
+ * Construct the complete error message. Start with the simple
+ * error message, pulled from the interp result if necessary...
*/
-
- TclEmitOpcode(INST_TRY_CVT_TO_NUMERIC, envPtr);
+
+ if (msg == NULL) {
+ msg = Tcl_GetObjResult(interp);
+ }
+
+ /*
+ * Add a detailed quote from the bad expression, displaying and
+ * sometimes marking the precise location of the syntax error.
+ */
+
+ Tcl_AppendPrintfToObj(msg, "\nin expression \"%s%.*s%.*s%s%s%.*s%s\"",
+ ((start - limit) < parsePtr->string) ? "" : "...",
+ ((start - limit) < parsePtr->string)
+ ? (int) (start - parsePtr->string) : limit - 3,
+ ((start - limit) < parsePtr->string)
+ ? parsePtr->string : start - limit + 3,
+ (scanned < limit) ? scanned : limit - 3, start,
+ (scanned < limit) ? "" : "...", insertMark ? mark : "",
+ (start + scanned + limit > parsePtr->end)
+ ? (int) (parsePtr->end - start) - scanned : limit-3,
+ start + scanned,
+ (start + scanned + limit > parsePtr->end) ? "" : "...");
+
+ /* Next, append any postscript message. */
+ if (post != NULL) {
+ Tcl_AppendToObj(msg, ";\n", -1);
+ Tcl_AppendObjToObj(msg, post);
+ Tcl_DecrRefCount(post);
+ }
+ Tcl_SetObjResult(interp, msg);
+
+ /* Finally, place context information in the errorInfo. */
+ numBytes = parsePtr->end - parsePtr->string;
+ Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+ "\n (parsing expression \"%.*s%s\")",
+ (numBytes < limit) ? numBytes : limit - 3,
+ parsePtr->string, (numBytes < limit) ? "" : "..."));
}
- Tcl_FreeParse(&parse);
- done:
- return code;
+ return TCL_ERROR;
}
/*
*----------------------------------------------------------------------
*
- * TclFinalizeCompilation --
+ * ConvertTreeToTokens --
*
- * Clean up the compilation environment so it can later be
- * properly reinitialized. This procedure is called by Tcl_Finalize().
+ * Given a string, the numBytes bytes starting at start, and an OpNode
+ * tree and Tcl_Token array created by passing that same string to
+ * ParseExpr(), this function writes into *parsePtr the sequence of
+ * Tcl_Tokens needed so to satisfy the historical interface provided
+ * by Tcl_ParseExpr(). Note that this routine exists only for the sake
+ * of the public Tcl_ParseExpr() routine. It is not used by Tcl itself
+ * at all.
*
* Results:
* None.
*
* Side effects:
- * Cleans up the compilation environment. At the moment, just the
- * table of expression operators is freed.
+ * The Tcl_Parse *parsePtr is filled with Tcl_Tokens representing the
+ * parsed expression.
*
*----------------------------------------------------------------------
*/
-void
-TclFinalizeCompilation()
+static void
+ConvertTreeToTokens(
+ const char *start,
+ int numBytes,
+ OpNode *nodes,
+ Tcl_Token *tokenPtr,
+ Tcl_Parse *parsePtr)
{
- Tcl_MutexLock(&opMutex);
- if (opTableInitialized) {
- Tcl_DeleteHashTable(&opHashTable);
- opTableInitialized = 0;
+ int subExprTokenIdx = 0;
+ OpNode *nodePtr = nodes;
+ int next = nodePtr->right;
+
+ while (1) {
+ Tcl_Token *subExprTokenPtr;
+ int scanned, parentIdx;
+ unsigned char lexeme;
+
+ /*
+ * Advance the mark so the next exit from this node won't retrace
+ * steps over ground already covered.
+ */
+
+ nodePtr->mark++;
+
+ /* Handle next child node or leaf */
+ switch (next) {
+ case OT_EMPTY:
+
+ /* No tokens and no characters for the OT_EMPTY leaf. */
+ break;
+
+ case OT_LITERAL:
+
+ /* Skip any white space that comes before the literal */
+ scanned = TclParseAllWhiteSpace(start, numBytes);
+ start +=scanned;
+ numBytes -= scanned;
+
+ /* Reparse the literal to get pointers into source string */
+ scanned = ParseLexeme(start, numBytes, &lexeme, NULL);
+
+ TclGrowParseTokenArray(parsePtr, 2);
+ subExprTokenPtr = parsePtr->tokenPtr + parsePtr->numTokens;
+ subExprTokenPtr->type = TCL_TOKEN_SUB_EXPR;
+ subExprTokenPtr->start = start;
+ subExprTokenPtr->size = scanned;
+ subExprTokenPtr->numComponents = 1;
+ subExprTokenPtr[1].type = TCL_TOKEN_TEXT;
+ subExprTokenPtr[1].start = start;
+ subExprTokenPtr[1].size = scanned;
+ subExprTokenPtr[1].numComponents = 0;
+
+ parsePtr->numTokens += 2;
+ start +=scanned;
+ numBytes -= scanned;
+ break;
+
+ case OT_TOKENS: {
+
+ /*
+ * tokenPtr points to a token sequence that came from parsing
+ * a Tcl word. A Tcl word is made up of a sequence of one or
+ * more elements. When the word is only a single element, it's
+ * been the historical practice to replace the TCL_TOKEN_WORD
+ * token directly with a TCL_TOKEN_SUB_EXPR token. However,
+ * when the word has multiple elements, a TCL_TOKEN_WORD token
+ * is kept as a grouping device so that TCL_TOKEN_SUB_EXPR
+ * always has only one element. Wise or not, these are the
+ * rules the Tcl expr parser has followed, and for the sake
+ * of those few callers of Tcl_ParseExpr() we do not change
+ * them now. Internally, we can do better.
+ */
+
+ int toCopy = tokenPtr->numComponents + 1;
+
+ if (tokenPtr->numComponents == tokenPtr[1].numComponents + 1) {
+
+ /*
+ * Single element word. Copy tokens and convert the leading
+ * token to TCL_TOKEN_SUB_EXPR.
+ */
+
+ TclGrowParseTokenArray(parsePtr, toCopy);
+ subExprTokenPtr = parsePtr->tokenPtr + parsePtr->numTokens;
+ memcpy(subExprTokenPtr, tokenPtr,
+ (size_t) toCopy * sizeof(Tcl_Token));
+ subExprTokenPtr->type = TCL_TOKEN_SUB_EXPR;
+ parsePtr->numTokens += toCopy;
+ } else {
+
+ /*
+ * Multiple element word. Create a TCL_TOKEN_SUB_EXPR
+ * token to lead, with fields initialized from the leading
+ * token, then copy entire set of word tokens.
+ */
+
+ TclGrowParseTokenArray(parsePtr, toCopy+1);
+ subExprTokenPtr = parsePtr->tokenPtr + parsePtr->numTokens;
+ *subExprTokenPtr = *tokenPtr;
+ subExprTokenPtr->type = TCL_TOKEN_SUB_EXPR;
+ subExprTokenPtr->numComponents++;
+ subExprTokenPtr++;
+ memcpy(subExprTokenPtr, tokenPtr,
+ (size_t) toCopy * sizeof(Tcl_Token));
+ parsePtr->numTokens += toCopy + 1;
+ }
+
+ scanned = tokenPtr->start + tokenPtr->size - start;
+ start +=scanned;
+ numBytes -= scanned;
+ tokenPtr += toCopy;
+ break;
+ }
+
+ default:
+
+ /* Advance to the child node, which is an operator. */
+ nodePtr = nodes + next;
+
+ /* Skip any white space that comes before the subexpression */
+ scanned = TclParseAllWhiteSpace(start, numBytes);
+ start +=scanned;
+ numBytes -= scanned;
+
+ /* Generate tokens for the operator / subexpression... */
+ switch (nodePtr->lexeme) {
+ case OPEN_PAREN:
+ case COMMA:
+ case COLON:
+
+ /*
+ * Historical practice has been to have no Tcl_Tokens for
+ * these operators.
+ */
+
+ break;
+
+ default: {
+
+ /*
+ * Remember the index of the last subexpression we were
+ * working on -- that of our parent. We'll stack it later.
+ */
+
+ parentIdx = subExprTokenIdx;
+
+ /*
+ * Verify space for the two leading Tcl_Tokens representing
+ * the subexpression rooted by this operator. The first
+ * Tcl_Token will be of type TCL_TOKEN_SUB_EXPR; the second
+ * of type TCL_TOKEN_OPERATOR.
+ */
+
+ TclGrowParseTokenArray(parsePtr, 2);
+ subExprTokenIdx = parsePtr->numTokens;
+ subExprTokenPtr = parsePtr->tokenPtr + subExprTokenIdx;
+ parsePtr->numTokens += 2;
+ subExprTokenPtr->type = TCL_TOKEN_SUB_EXPR;
+ subExprTokenPtr[1].type = TCL_TOKEN_OPERATOR;
+
+ /*
+ * Our current position scanning the string is the starting
+ * point for this subexpression.
+ */
+
+ subExprTokenPtr->start = start;
+
+ /*
+ * Eventually, we know that the numComponents field of the
+ * Tcl_Token of type TCL_TOKEN_OPERATOR will be 0. This means
+ * we can make other use of this field for now to track the
+ * stack of subexpressions we have pending.
+ */
+
+ subExprTokenPtr[1].numComponents = parentIdx;
+ break;
+ }
+ }
+ break;
+ }
+
+ /* Determine which way to exit the node on this pass. */
+ router:
+ switch (nodePtr->mark) {
+ case MARK_LEFT:
+ next = nodePtr->left;
+ break;
+
+ case MARK_RIGHT:
+ next = nodePtr->right;
+
+ /* Skip any white space that comes before the operator */
+ scanned = TclParseAllWhiteSpace(start, numBytes);
+ start +=scanned;
+ numBytes -= scanned;
+
+ /*
+ * Here we scan from the string the operator corresponding to
+ * nodePtr->lexeme.
+ */
+
+ scanned = ParseLexeme(start, numBytes, &lexeme, NULL);
+
+ switch(nodePtr->lexeme) {
+ case OPEN_PAREN:
+ case COMMA:
+ case COLON:
+
+ /* No tokens for these lexemes -> nothing to do. */
+ break;
+
+ default:
+
+ /*
+ * Record in the TCL_TOKEN_OPERATOR token the pointers into
+ * the string marking where the operator is.
+ */
+
+ subExprTokenPtr = parsePtr->tokenPtr + subExprTokenIdx;
+ subExprTokenPtr[1].start = start;
+ subExprTokenPtr[1].size = scanned;
+ break;
+ }
+
+ start +=scanned;
+ numBytes -= scanned;
+ break;
+
+ case MARK_PARENT:
+ switch (nodePtr->lexeme) {
+ case START:
+
+ /* When we get back to the START node, we're done. */
+ return;
+
+ case COMMA:
+ case COLON:
+
+ /* No tokens for these lexemes -> nothing to do. */
+ break;
+
+ case OPEN_PAREN:
+
+ /* Skip past matching close paren. */
+ scanned = TclParseAllWhiteSpace(start, numBytes);
+ start +=scanned;
+ numBytes -= scanned;
+ scanned = ParseLexeme(start, numBytes, &lexeme, NULL);
+ start +=scanned;
+ numBytes -= scanned;
+ break;
+
+ default: {
+
+ /*
+ * Before we leave this node/operator/subexpression for the
+ * last time, finish up its tokens....
+ *
+ * Our current position scanning the string is where the
+ * substring for the subexpression ends.
+ */
+
+ subExprTokenPtr = parsePtr->tokenPtr + subExprTokenIdx;
+ subExprTokenPtr->size = start - subExprTokenPtr->start;
+
+ /*
+ * All the Tcl_Tokens allocated and filled belong to
+ * this subexpresion. The first token is the leading
+ * TCL_TOKEN_SUB_EXPR token, and all the rest (one fewer)
+ * are its components.
+ */
+
+ subExprTokenPtr->numComponents =
+ (parsePtr->numTokens - subExprTokenIdx) - 1;
+
+ /*
+ * Finally, as we return up the tree to our parent, pop the
+ * parent subexpression off our subexpression stack, and
+ * fill in the zero numComponents for the operator Tcl_Token.
+ */
+
+ parentIdx = subExprTokenPtr[1].numComponents;
+ subExprTokenPtr[1].numComponents = 0;
+ subExprTokenIdx = parentIdx;
+ break;
+ }
+ }
+
+ /* Since we're returning to parent, skip child handling code. */
+ nodePtr = nodes + nodePtr->p.parent;
+ goto router;
+ }
}
- Tcl_MutexUnlock(&opMutex);
}
/*
*----------------------------------------------------------------------
*
- * CompileSubExpr --
+ * Tcl_ParseExpr --
*
- * Given a pointer to a TCL_TOKEN_SUB_EXPR token describing a
- * subexpression, this procedure emits instructions to evaluate the
- * subexpression at runtime.
+ * Given a string, the numBytes bytes starting at start, this function
+ * parses it as a Tcl expression and stores information about the
+ * structure of the expression in the Tcl_Parse struct indicated by the
+ * caller.
*
* Results:
- * The return value is TCL_OK on a successful compilation and TCL_ERROR
- * on failure. If TCL_ERROR is returned, then the interpreter's result
- * contains an error message.
+ * If the string is successfully parsed as a valid Tcl expression, TCL_OK
+ * is returned, and data about the expression structure is written to
+ * *parsePtr. If the string cannot be parsed as a valid Tcl expression,
+ * TCL_ERROR is returned, and if interp is non-NULL, an error message is
+ * written to interp.
*
* Side effects:
- * Adds instructions to envPtr to evaluate the subexpression.
+ * If there is insufficient space in parsePtr to hold all the information
+ * about the expression, then additional space is malloc-ed. If the
+ * function returns TCL_OK then the caller must eventually invoke
+ * Tcl_FreeParse to release any additional space that was allocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ParseExpr(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ const char *start, /* Start of source string to parse. */
+ int numBytes, /* Number of bytes in string. If < 0, the
+ * string consists of all bytes up to the
+ * first null character. */
+ Tcl_Parse *parsePtr) /* Structure to fill with information about
+ * the parsed expression; any previous
+ * information in the structure is ignored. */
+{
+ int code;
+ OpNode *opTree = NULL; /* Will point to the tree of operators */
+ Tcl_Obj *litList = Tcl_NewObj(); /* List to hold the literals */
+ Tcl_Obj *funcList = Tcl_NewObj(); /* List to hold the functon names*/
+ Tcl_Parse *exprParsePtr =
+ (Tcl_Parse *) TclStackAlloc(interp, sizeof(Tcl_Parse));
+ /* Holds the Tcl_Tokens of substitutions */
+
+ if (numBytes < 0) {
+ numBytes = (start ? strlen(start) : 0);
+ }
+
+ code = ParseExpr(interp, start, numBytes, &opTree, litList,
+ funcList, exprParsePtr, 1 /* parseOnly */);
+ Tcl_DecrRefCount(funcList);
+ Tcl_DecrRefCount(litList);
+
+ TclParseInit(interp, start, numBytes, parsePtr);
+ if (code == TCL_OK) {
+ ConvertTreeToTokens(start, numBytes,
+ opTree, exprParsePtr->tokenPtr, parsePtr);
+ } else {
+ parsePtr->term = exprParsePtr->term;
+ parsePtr->errorType = exprParsePtr->errorType;
+ }
+
+ Tcl_FreeParse(exprParsePtr);
+ TclStackFree(interp, exprParsePtr);
+ ckfree((char *) opTree);
+ return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ParseLexeme --
+ *
+ * Parse a single lexeme from the start of a string, scanning no more
+ * than numBytes bytes.
+ *
+ * Results:
+ * Returns the number of bytes scanned to produce the lexeme.
+ *
+ * Side effects:
+ * Code identifying lexeme parsed is writen to *lexemePtr.
*
*----------------------------------------------------------------------
*/
static int
-CompileSubExpr(exprTokenPtr, infoPtr, envPtr)
- Tcl_Token *exprTokenPtr; /* Points to TCL_TOKEN_SUB_EXPR token
- * to compile. */
- ExprInfo *infoPtr; /* Describes the compilation state for the
- * expression being compiled. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
+ParseLexeme(
+ const char *start, /* Start of lexeme to parse. */
+ int numBytes, /* Number of bytes in string. */
+ unsigned char *lexemePtr, /* Write code of parsed lexeme to this
+ * storage. */
+ Tcl_Obj **literalPtr) /* Write corresponding literal value to this
+ storage, if non-NULL. */
{
- Tcl_Interp *interp = infoPtr->interp;
- Tcl_Token *tokenPtr, *endPtr = NULL; /* silence gcc 4 warning */
- Tcl_Token *afterSubexprPtr;
- OperatorDesc *opDescPtr;
- Tcl_HashEntry *hPtr;
- CONST char *operator;
- Tcl_DString opBuf;
- int objIndex, opIndex, length, code;
- char buffer[TCL_UTF_MAX];
-
- if (exprTokenPtr->type != TCL_TOKEN_SUB_EXPR) {
- panic("CompileSubExpr: token type %d not TCL_TOKEN_SUB_EXPR\n",
- exprTokenPtr->type);
+ const char *end;
+ int scanned;
+ Tcl_UniChar ch;
+ Tcl_Obj *literal = NULL;
+ unsigned char byte;
+
+ if (numBytes == 0) {
+ *lexemePtr = END;
+ return 0;
}
- code = TCL_OK;
+ byte = (unsigned char)(*start);
+ if (byte < sizeof(Lexeme) && Lexeme[byte] != 0) {
+ *lexemePtr = Lexeme[byte];
+ return 1;
+ }
+ switch (byte) {
+ case '*':
+ if ((numBytes > 1) && (start[1] == '*')) {
+ *lexemePtr = EXPON;
+ return 2;
+ }
+ *lexemePtr = MULT;
+ return 1;
- /*
- * Switch on the type of the first token after the subexpression token.
- * After processing it, advance tokenPtr to point just after the
- * subexpression's last token.
- */
-
- tokenPtr = exprTokenPtr+1;
- TRACE(exprTokenPtr->start, exprTokenPtr->size,
- tokenPtr->start, tokenPtr->size);
- switch (tokenPtr->type) {
- case TCL_TOKEN_WORD:
- code = TclCompileTokens(interp, tokenPtr+1,
- tokenPtr->numComponents, envPtr);
- if (code != TCL_OK) {
- goto done;
- }
- tokenPtr += (tokenPtr->numComponents + 1);
- break;
-
- case TCL_TOKEN_TEXT:
- if (tokenPtr->size > 0) {
- objIndex = TclRegisterNewLiteral(envPtr, tokenPtr->start,
- tokenPtr->size);
- } else {
- objIndex = TclRegisterNewLiteral(envPtr, "", 0);
- }
- TclEmitPush(objIndex, envPtr);
- tokenPtr += 1;
- break;
-
- case TCL_TOKEN_BS:
- length = TclParseBackslash(tokenPtr->start, tokenPtr->size,
- (int *) NULL, buffer);
- if (length > 0) {
- objIndex = TclRegisterNewLiteral(envPtr, buffer, length);
- } else {
- objIndex = TclRegisterNewLiteral(envPtr, "", 0);
- }
- TclEmitPush(objIndex, envPtr);
- tokenPtr += 1;
- break;
-
- case TCL_TOKEN_COMMAND:
- code = TclCompileScript(interp, tokenPtr->start+1,
- tokenPtr->size-2, /*nested*/ 0, envPtr);
- if (code != TCL_OK) {
- goto done;
- }
- tokenPtr += 1;
- break;
-
- case TCL_TOKEN_VARIABLE:
- code = TclCompileTokens(interp, tokenPtr, 1, envPtr);
- if (code != TCL_OK) {
- goto done;
+ case '=':
+ if ((numBytes > 1) && (start[1] == '=')) {
+ *lexemePtr = EQUAL;
+ return 2;
+ }
+ *lexemePtr = INCOMPLETE;
+ return 1;
+
+ case '!':
+ if ((numBytes > 1) && (start[1] == '=')) {
+ *lexemePtr = NEQ;
+ return 2;
+ }
+ *lexemePtr = NOT;
+ return 1;
+
+ case '&':
+ if ((numBytes > 1) && (start[1] == '&')) {
+ *lexemePtr = AND;
+ return 2;
+ }
+ *lexemePtr = BIT_AND;
+ return 1;
+
+ case '|':
+ if ((numBytes > 1) && (start[1] == '|')) {
+ *lexemePtr = OR;
+ return 2;
+ }
+ *lexemePtr = BIT_OR;
+ return 1;
+
+ case '<':
+ if (numBytes > 1) {
+ switch (start[1]) {
+ case '<':
+ *lexemePtr = LEFT_SHIFT;
+ return 2;
+ case '=':
+ *lexemePtr = LEQ;
+ return 2;
}
- tokenPtr += (tokenPtr->numComponents + 1);
- break;
-
- case TCL_TOKEN_SUB_EXPR:
- code = CompileSubExpr(tokenPtr, infoPtr, envPtr);
- if (code != TCL_OK) {
- goto done;
+ }
+ *lexemePtr = LESS;
+ return 1;
+
+ case '>':
+ if (numBytes > 1) {
+ switch (start[1]) {
+ case '>':
+ *lexemePtr = RIGHT_SHIFT;
+ return 2;
+ case '=':
+ *lexemePtr = GEQ;
+ return 2;
}
- tokenPtr += (tokenPtr->numComponents + 1);
- break;
-
- case TCL_TOKEN_OPERATOR:
+ }
+ *lexemePtr = GREATER;
+ return 1;
+
+ case 'i':
+ if ((numBytes > 1) && (start[1] == 'n')
+ && ((numBytes == 2) || !isalpha(UCHAR(start[2])))) {
+
/*
- * Look up the operator. If the operator isn't found, treat it
- * as a math function.
+ * Must make this check so we can tell the difference between
+ * the "in" operator and the "int" function name and the
+ * "infinity" numeric value.
*/
- Tcl_DStringInit(&opBuf);
- operator = Tcl_DStringAppend(&opBuf,
- tokenPtr->start, tokenPtr->size);
- hPtr = Tcl_FindHashEntry(&opHashTable, operator);
- if (hPtr == NULL) {
- code = CompileMathFuncCall(exprTokenPtr, operator, infoPtr,
- envPtr, &endPtr);
- Tcl_DStringFree(&opBuf);
- if (code != TCL_OK) {
- goto done;
- }
- tokenPtr = endPtr;
- break;
+
+ *lexemePtr = IN_LIST;
+ return 2;
+ }
+ break;
+
+ case 'e':
+ if ((numBytes > 1) && (start[1] == 'q')
+ && ((numBytes == 2) || !isalpha(UCHAR(start[2])))) {
+ *lexemePtr = STREQ;
+ return 2;
+ }
+ break;
+
+ case 'n':
+ if ((numBytes > 1) && ((numBytes == 2) || !isalpha(UCHAR(start[2])))) {
+ switch (start[1]) {
+ case 'e':
+ *lexemePtr = STRNEQ;
+ return 2;
+ case 'i':
+ *lexemePtr = NOT_IN_LIST;
+ return 2;
+ }
+ }
+ }
+
+ literal = Tcl_NewObj();
+ if (TclParseNumber(NULL, literal, NULL, start, numBytes, &end,
+ TCL_PARSE_NO_WHITESPACE) == TCL_OK) {
+ 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);
}
- Tcl_DStringFree(&opBuf);
- opIndex = (int) Tcl_GetHashValue(hPtr);
- opDescPtr = &(operatorTable[opIndex]);
+ return (end-start);
+ } else {
+ unsigned char lexeme;
/*
- * If the operator is "normal", compile it using information
- * from the operator table.
+ * 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 (opDescPtr->numOperands > 0) {
- tokenPtr++;
- code = CompileSubExpr(tokenPtr, infoPtr, envPtr);
- if (code != TCL_OK) {
- goto done;
- }
- tokenPtr += (tokenPtr->numComponents + 1);
-
- if (opDescPtr->numOperands == 2) {
- code = CompileSubExpr(tokenPtr, infoPtr, envPtr);
- if (code != TCL_OK) {
- goto done;
+ 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;
}
- tokenPtr += (tokenPtr->numComponents + 1);
}
- TclEmitOpcode(opDescPtr->instruction, envPtr);
- infoPtr->hasOperators = 1;
- break;
}
-
+ 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;
+ }
/*
- * The operator requires special treatment, and is either
- * "+" or "-", or one of "&&", "||" or "?".
+ * Otherwise, fall through and parse the whole as a bareword.
*/
-
- switch (opIndex) {
- case OP_PLUS:
- case OP_MINUS:
- tokenPtr++;
- code = CompileSubExpr(tokenPtr, infoPtr, envPtr);
- if (code != TCL_OK) {
- goto done;
- }
- tokenPtr += (tokenPtr->numComponents + 1);
-
- /*
- * Check whether the "+" or "-" is unary.
- */
-
- afterSubexprPtr = exprTokenPtr
- + exprTokenPtr->numComponents+1;
- if (tokenPtr == afterSubexprPtr) {
- TclEmitOpcode(((opIndex==OP_PLUS)?
- INST_UPLUS : INST_UMINUS),
- envPtr);
- break;
- }
-
- /*
- * The "+" or "-" is binary.
- */
-
- code = CompileSubExpr(tokenPtr, infoPtr, envPtr);
- if (code != TCL_OK) {
- goto done;
- }
- tokenPtr += (tokenPtr->numComponents + 1);
- TclEmitOpcode(((opIndex==OP_PLUS)? INST_ADD : INST_SUB),
- envPtr);
- break;
-
- case OP_LAND:
- case OP_LOR:
- code = CompileLandOrLorExpr(exprTokenPtr, opIndex,
- infoPtr, envPtr, &endPtr);
- if (code != TCL_OK) {
- goto done;
- }
- tokenPtr = endPtr;
- break;
-
- case OP_QUESTY:
- code = CompileCondExpr(exprTokenPtr, infoPtr,
- envPtr, &endPtr);
- if (code != TCL_OK) {
- goto done;
- }
- tokenPtr = endPtr;
- break;
-
- default:
- panic("CompileSubExpr: unexpected operator %d requiring special treatment\n",
- opIndex);
- } /* end switch on operator requiring special treatment */
- infoPtr->hasOperators = 1;
- break;
-
- default:
- panic("CompileSubExpr: unexpected token type %d\n",
- tokenPtr->type);
+ }
}
- /*
- * Verify that the subexpression token had the required number of
- * subtokens: that we've advanced tokenPtr just beyond the
- * subexpression's last token. For example, a "*" subexpression must
- * contain the tokens for exactly two operands.
- */
-
- if (tokenPtr != (exprTokenPtr + exprTokenPtr->numComponents+1)) {
- LogSyntaxError(infoPtr);
- code = TCL_ERROR;
+ if (Tcl_UtfCharComplete(start, numBytes)) {
+ scanned = Tcl_UtfToUniChar(start, &ch);
+ } else {
+ char utfBytes[TCL_UTF_MAX];
+ memcpy(utfBytes, start, (size_t) numBytes);
+ utfBytes[numBytes] = '\0';
+ scanned = Tcl_UtfToUniChar(utfBytes, &ch);
}
-
- done:
- return code;
+ if (!isalnum(UCHAR(ch))) {
+ *lexemePtr = INVALID;
+ Tcl_DecrRefCount(literal);
+ return scanned;
+ }
+ end = start;
+ while (isalnum(UCHAR(ch)) || (UCHAR(ch) == '_')) {
+ end += scanned;
+ numBytes -= scanned;
+ if (Tcl_UtfCharComplete(end, numBytes)) {
+ scanned = Tcl_UtfToUniChar(end, &ch);
+ } else {
+ char utfBytes[TCL_UTF_MAX];
+ memcpy(utfBytes, end, (size_t) numBytes);
+ utfBytes[numBytes] = '\0';
+ scanned = Tcl_UtfToUniChar(utfBytes, &ch);
+ }
+ }
+ *lexemePtr = BAREWORD;
+ if (literalPtr) {
+ Tcl_SetStringObj(literal, start, (int) (end-start));
+ *literalPtr = literal;
+ } else {
+ Tcl_DecrRefCount(literal);
+ }
+ return (end-start);
}
/*
*----------------------------------------------------------------------
*
- * CompileLandOrLorExpr --
+ * TclCompileExpr --
*
- * This procedure compiles a Tcl logical and ("&&") or logical or
- * ("||") subexpression.
+ * This procedure compiles a string containing a Tcl expression into Tcl
+ * bytecodes.
*
* Results:
- * The return value is TCL_OK on a successful compilation and TCL_ERROR
- * on failure. If TCL_OK is returned, a pointer to the token just after
- * the last one in the subexpression is stored at the address in
- * endPtrPtr. If TCL_ERROR is returned, then the interpreter's result
- * contains an error message.
+ * None.
*
* Side effects:
* Adds instructions to envPtr to evaluate the expression at runtime.
@@ -580,387 +2022,680 @@ CompileSubExpr(exprTokenPtr, infoPtr, envPtr)
*----------------------------------------------------------------------
*/
-static int
-CompileLandOrLorExpr(exprTokenPtr, opIndex, infoPtr, envPtr, endPtrPtr)
- Tcl_Token *exprTokenPtr; /* Points to TCL_TOKEN_SUB_EXPR token
- * containing the "&&" or "||" operator. */
- int opIndex; /* A code describing the expression
- * operator: either OP_LAND or OP_LOR. */
- ExprInfo *infoPtr; /* Describes the compilation state for the
- * expression being compiled. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
- Tcl_Token **endPtrPtr; /* If successful, a pointer to the token
- * just after the last token in the
- * subexpression is stored here. */
+void
+TclCompileExpr(
+ Tcl_Interp *interp, /* Used for error reporting. */
+ const char *script, /* The source script to compile. */
+ int numBytes, /* Number of bytes in script. */
+ CompileEnv *envPtr, /* Holds resulting instructions. */
+ int optimize) /* 0 for one-off expressions */
{
- JumpFixup shortCircuitFixup; /* Used to fix up the short circuit jump
- * after the first subexpression. */
- JumpFixup lhsTrueFixup, lhsEndFixup;
- /* Used to fix up jumps used to convert the
- * first operand to 0 or 1. */
- Tcl_Token *tokenPtr;
- int dist, code;
- int savedStackDepth = envPtr->currStackDepth;
+ OpNode *opTree = NULL; /* Will point to the tree of operators */
+ Tcl_Obj *litList = Tcl_NewObj(); /* List to hold the literals */
+ Tcl_Obj *funcList = Tcl_NewObj(); /* List to hold the functon names*/
+ Tcl_Parse *parsePtr =
+ (Tcl_Parse *) TclStackAlloc(interp, sizeof(Tcl_Parse));
+ /* Holds the Tcl_Tokens of substitutions */
+
+ int code = ParseExpr(interp, script, numBytes, &opTree, litList,
+ funcList, parsePtr, 0 /* parseOnly */);
+
+ if (code == TCL_OK) {
+
+ /* Valid parse; compile the tree. */
+ int objc;
+ Tcl_Obj *const *litObjv;
+ Tcl_Obj **funcObjv;
+
+ /* TIP #280 : Track Lines within the expression */
+ TclAdvanceLines(&envPtr->line, script,
+ script + TclParseAllWhiteSpace(script, numBytes));
+
+ TclListObjGetElements(NULL, litList, &objc, (Tcl_Obj ***)&litObjv);
+ TclListObjGetElements(NULL, funcList, &objc, &funcObjv);
+ CompileExprTree(interp, opTree, 0, &litObjv, funcObjv,
+ parsePtr->tokenPtr, envPtr, optimize);
+ } else {
+ TclCompileSyntaxError(interp, envPtr);
+ }
- /*
- * Emit code for the first operand.
- */
+ Tcl_FreeParse(parsePtr);
+ TclStackFree(interp, parsePtr);
+ Tcl_DecrRefCount(funcList);
+ Tcl_DecrRefCount(litList);
+ ckfree((char *) opTree);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ExecConstantExprTree --
+ * Compiles and executes bytecode for the subexpression tree at index
+ * in the nodes array. This subexpression must be constant, made up
+ * of only constant operators (not functions) and literals.
+ *
+ * Results:
+ * A standard Tcl return code and result left in interp.
+ *
+ * Side effects:
+ * Consumes subtree of nodes rooted at index. Advances the pointer
+ * *litObjvPtr.
+ *
+ *----------------------------------------------------------------------
+ */
- tokenPtr = exprTokenPtr+2;
- code = CompileSubExpr(tokenPtr, infoPtr, envPtr);
- if (code != TCL_OK) {
- goto done;
- }
- tokenPtr += (tokenPtr->numComponents + 1);
+static int
+ExecConstantExprTree(
+ Tcl_Interp *interp,
+ OpNode *nodes,
+ int index,
+ Tcl_Obj *const **litObjvPtr)
+{
+ CompileEnv *envPtr;
+ ByteCode *byteCodePtr;
+ int code;
+ Tcl_Obj *byteCodeObj = Tcl_NewObj();
/*
- * Convert the first operand to the result that Tcl requires:
- * "0" or "1". Eventually we'll use a new instruction for this.
+ * Note we are compiling an expression with literal arguments. This means
+ * there can be no [info frame] calls when we execute the resulting
+ * bytecode, so there's no need to tend to TIP 280 issues.
*/
-
- TclEmitForwardJump(envPtr, TCL_TRUE_JUMP, &lhsTrueFixup);
- TclEmitPush(TclRegisterNewLiteral(envPtr, "0", 1), envPtr);
- TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &lhsEndFixup);
- dist = (envPtr->codeNext - envPtr->codeStart) - lhsTrueFixup.codeOffset;
- if (TclFixupForwardJump(envPtr, &lhsTrueFixup, dist, 127)) {
- badDist:
- panic("CompileLandOrLorExpr: bad jump distance %d\n", dist);
- }
- envPtr->currStackDepth = savedStackDepth;
- TclEmitPush(TclRegisterNewLiteral(envPtr, "1", 1), envPtr);
- dist = (envPtr->codeNext - envPtr->codeStart) - lhsEndFixup.codeOffset;
- if (TclFixupForwardJump(envPtr, &lhsEndFixup, dist, 127)) {
- goto badDist;
- }
- /*
- * Emit the "short circuit" jump around the rest of the expression.
- * Duplicate the "0" or "1" on top of the stack first to keep the
- * jump from consuming it.
- */
+ envPtr = (CompileEnv *) TclStackAlloc(interp, sizeof(CompileEnv));
+ TclInitCompileEnv(interp, envPtr, NULL, 0, NULL, 0);
+ CompileExprTree(interp, nodes, index, litObjvPtr, NULL, NULL, envPtr,
+ 0 /* optimize */);
+ TclEmitOpcode(INST_DONE, envPtr);
+ Tcl_IncrRefCount(byteCodeObj);
+ TclInitByteCodeObj(byteCodeObj, envPtr);
+ TclFreeCompileEnv(envPtr);
+ TclStackFree(interp, envPtr);
+ byteCodePtr = (ByteCode *) byteCodeObj->internalRep.otherValuePtr;
+ code = TclExecuteByteCode(interp, byteCodePtr);
+ Tcl_DecrRefCount(byteCodeObj);
+ return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CompileExprTree --
+ * Compiles and writes to envPtr instructions for the subexpression
+ * tree at index in the nodes array. (*litObjvPtr) must point to the
+ * proper location in a corresponding literals list. Likewise, when
+ * non-NULL, funcObjv and tokenPtr must point into matching arrays of
+ * function names and Tcl_Token's derived from earlier call to
+ * ParseExpr(). When optimize is true, any constant subexpressions
+ * will be precomputed.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Adds instructions to envPtr to evaluate the expression at runtime.
+ * Consumes subtree of nodes rooted at index. Advances the pointer
+ * *litObjvPtr.
+ *
+ *----------------------------------------------------------------------
+ */
- TclEmitOpcode(INST_DUP, envPtr);
- TclEmitForwardJump(envPtr,
- ((opIndex==OP_LAND)? TCL_FALSE_JUMP : TCL_TRUE_JUMP),
- &shortCircuitFixup);
+static void
+CompileExprTree(
+ Tcl_Interp *interp,
+ OpNode *nodes,
+ int index,
+ Tcl_Obj *const **litObjvPtr,
+ Tcl_Obj *const *funcObjv,
+ Tcl_Token *tokenPtr,
+ CompileEnv *envPtr,
+ int optimize)
+{
+ OpNode *nodePtr = nodes + index;
+ OpNode *rootPtr = nodePtr;
+ int numWords = 0;
+ JumpList *jumpPtr = NULL;
+ int convert = 1;
+
+ while (1) {
+ int next;
+ JumpList *freePtr, *newJump;
+
+ if (nodePtr->mark == MARK_LEFT) {
+ next = nodePtr->left;
+
+ switch (nodePtr->lexeme) {
+ case QUESTION:
+ newJump = (JumpList *) TclStackAlloc(interp, sizeof(JumpList));
+ newJump->next = jumpPtr;
+ jumpPtr = newJump;
+ newJump = (JumpList *) TclStackAlloc(interp, sizeof(JumpList));
+ newJump->next = jumpPtr;
+ jumpPtr = newJump;
+ jumpPtr->depth = envPtr->currStackDepth;
+ convert = 1;
+ break;
+ case AND:
+ case OR:
+ newJump = (JumpList *) TclStackAlloc(interp, sizeof(JumpList));
+ newJump->next = jumpPtr;
+ jumpPtr = newJump;
+ newJump = (JumpList *) TclStackAlloc(interp, sizeof(JumpList));
+ newJump->next = jumpPtr;
+ jumpPtr = newJump;
+ newJump = (JumpList *) TclStackAlloc(interp, sizeof(JumpList));
+ newJump->next = jumpPtr;
+ jumpPtr = newJump;
+ jumpPtr->depth = envPtr->currStackDepth;
+ break;
+ }
+ } else if (nodePtr->mark == MARK_RIGHT) {
+ next = nodePtr->right;
+
+ switch (nodePtr->lexeme) {
+ case FUNCTION: {
+ Tcl_DString cmdName;
+ const char *p;
+ int length;
+
+ Tcl_DStringInit(&cmdName);
+ Tcl_DStringAppend(&cmdName, "tcl::mathfunc::", -1);
+ p = TclGetStringFromObj(*funcObjv, &length);
+ funcObjv++;
+ Tcl_DStringAppend(&cmdName, p, length);
+ TclEmitPush(TclRegisterNewNSLiteral(envPtr,
+ Tcl_DStringValue(&cmdName),
+ Tcl_DStringLength(&cmdName)), envPtr);
+ Tcl_DStringFree(&cmdName);
+
+ /*
+ * Start a count of the number of words in this function
+ * command invocation. In case there's already a count
+ * in progress (nested functions), save it in our unused
+ * "left" field for restoring later.
+ */
+
+ nodePtr->left = numWords;
+ numWords = 2; /* Command plus one argument */
+ break;
+ }
+ case QUESTION:
+ TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &(jumpPtr->jump));
+ break;
+ case COLON:
+ TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP,
+ &(jumpPtr->next->jump));
+ envPtr->currStackDepth = jumpPtr->depth;
+ jumpPtr->offset = (envPtr->codeNext - envPtr->codeStart);
+ jumpPtr->convert = convert;
+ convert = 1;
+ break;
+ case AND:
+ TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &(jumpPtr->jump));
+ break;
+ case OR:
+ TclEmitForwardJump(envPtr, TCL_TRUE_JUMP, &(jumpPtr->jump));
+ break;
+ }
+ } else {
+ switch (nodePtr->lexeme) {
+ case START:
+ case QUESTION:
+ if (convert && (nodePtr == rootPtr)) {
+ TclEmitOpcode(INST_TRY_CVT_TO_NUMERIC, envPtr);
+ }
+ break;
+ case OPEN_PAREN:
- /*
- * Emit code for the second operand.
- */
+ /* do nothing */
+ break;
+ case FUNCTION:
- code = CompileSubExpr(tokenPtr, infoPtr, envPtr);
- if (code != TCL_OK) {
- goto done;
- }
- tokenPtr += (tokenPtr->numComponents + 1);
+ /*
+ * Use the numWords count we've kept to invoke the
+ * function command with the correct number of arguments.
+ */
- /*
- * Emit a "logical and" or "logical or" instruction. This does not try
- * to "short- circuit" the evaluation of both operands, but instead
- * ensures that we either have a "1" or a "0" result.
- */
+ if (numWords < 255) {
+ TclEmitInstInt1(INST_INVOKE_STK1, numWords, envPtr);
+ } else {
+ TclEmitInstInt4(INST_INVOKE_STK4, numWords, envPtr);
+ }
- TclEmitOpcode(((opIndex==OP_LAND)? INST_LAND : INST_LOR), envPtr);
+ /* Restore any saved numWords value. */
+ numWords = nodePtr->left;
+ convert = 1;
+ break;
+ case COMMA:
- /*
- * Now that we know the target of the forward jump, update it with the
- * correct distance.
- */
+ /* Each comma implies another function argument. */
+ numWords++;
+ break;
+ case COLON:
+ if (TclFixupForwardJump(envPtr, &(jumpPtr->next->jump),
+ (envPtr->codeNext - envPtr->codeStart)
+ - jumpPtr->next->jump.codeOffset, 127)) {
+ jumpPtr->offset += 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);
+ freePtr = jumpPtr;
+ jumpPtr = jumpPtr->next;
+ TclStackFree(interp, freePtr);
+ break;
+ case AND:
+ case OR:
+ TclEmitForwardJump(envPtr, (nodePtr->lexeme == AND)
+ ? TCL_FALSE_JUMP : TCL_TRUE_JUMP,
+ &(jumpPtr->next->jump));
+ 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;
+ }
+ TclEmitPush(TclRegisterNewLiteral(envPtr,
+ (nodePtr->lexeme == AND) ? "0" : "1", 1), envPtr);
+ TclFixupForwardJumpToHere(envPtr, &(jumpPtr->next->next->jump),
+ 127);
+ 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);
+ break;
+ default:
+ TclEmitOpcode(instruction[nodePtr->lexeme], envPtr);
+ convert = 0;
+ break;
+ }
+ if (nodePtr == rootPtr) {
- dist = (envPtr->codeNext - envPtr->codeStart)
- - shortCircuitFixup.codeOffset;
- TclFixupForwardJump(envPtr, &shortCircuitFixup, dist, 127);
- *endPtrPtr = tokenPtr;
+ /* We're done */
+ return;
+ }
+ nodePtr = nodes + nodePtr->p.parent;
+ continue;
+ }
- done:
- envPtr->currStackDepth = savedStackDepth + 1;
- return code;
+ nodePtr->mark++;
+ switch (next) {
+ case OT_EMPTY:
+ numWords = 1; /* No arguments, so just the command */
+ break;
+ case OT_LITERAL: {
+ Tcl_Obj *const *litObjv = *litObjvPtr;
+ Tcl_Obj *literal = *litObjv;
+
+ if (optimize) {
+ int length, index;
+ const char *bytes = TclGetStringFromObj(literal, &length);
+ LiteralEntry *lePtr;
+ Tcl_Obj *objPtr;
+
+ index = TclRegisterNewLiteral(envPtr, bytes, length);
+ lePtr = envPtr->literalArrayPtr + index;
+ objPtr = lePtr->objPtr;
+ if ((objPtr->typePtr == NULL) && (literal->typePtr != NULL)) {
+ /*
+ * Would like to do this:
+ *
+ * lePtr->objPtr = literal;
+ * Tcl_IncrRefCount(literal);
+ * Tcl_DecrRefCount(objPtr);
+ *
+ * However, the design of the "global" and "local"
+ * LiteralTable does not permit the value of lePtr->objPtr
+ * to change. So rather than replace lePtr->objPtr, we
+ * do surgery to transfer our desired intrep into it.
+ *
+ */
+ objPtr->typePtr = literal->typePtr;
+ objPtr->internalRep = literal->internalRep;
+ literal->typePtr = NULL;
+ }
+ TclEmitPush(index, envPtr);
+ } else {
+ /*
+ * When optimize==0, we know the expression is a one-off
+ * and there's nothing to be gained from sharing literals
+ * when they won't live long, and the copies we have already
+ * have an appropriate intrep. In this case, skip literal
+ * registration that would enable sharing, and use the routine
+ * that preserves intreps.
+ */
+ TclEmitPush(TclAddLiteralObj(envPtr, literal, NULL), envPtr);
+ }
+ (*litObjvPtr)++;
+ break;
+ }
+ case OT_TOKENS:
+ TclCompileTokens(interp, tokenPtr+1, tokenPtr->numComponents,
+ envPtr);
+ tokenPtr += tokenPtr->numComponents + 1;
+ break;
+ default:
+ if (optimize && nodes[next].constant) {
+ Tcl_InterpState save = Tcl_SaveInterpState(interp, TCL_OK);
+ if (ExecConstantExprTree(interp, nodes, next, litObjvPtr)
+ == TCL_OK) {
+ TclEmitPush(TclAddLiteralObj(envPtr,
+ Tcl_GetObjResult(interp), NULL), envPtr);
+ } else {
+ TclCompileSyntaxError(interp, envPtr);
+ }
+ Tcl_RestoreInterpState(interp, save);
+ convert = 0;
+ } else {
+ nodePtr = nodes + next;
+ }
+ }
+ }
}
/*
*----------------------------------------------------------------------
*
- * CompileCondExpr --
- *
- * This procedure compiles a Tcl conditional expression:
- * condExpr ::= lorExpr ['?' condExpr ':' condExpr]
+ * 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
+ * or exactly two arguments as suitable for the operator.
*
* Results:
- * The return value is TCL_OK on a successful compilation and TCL_ERROR
- * on failure. If TCL_OK is returned, a pointer to the token just after
- * the last one in the subexpression is stored at the address in
- * endPtrPtr. If TCL_ERROR is returned, then the interpreter's result
- * contains an error message.
+ * A standard Tcl return code and result left in interp.
*
* Side effects:
- * Adds instructions to envPtr to evaluate the expression at runtime.
+ * None.
*
*----------------------------------------------------------------------
*/
-static int
-CompileCondExpr(exprTokenPtr, infoPtr, envPtr, endPtrPtr)
- Tcl_Token *exprTokenPtr; /* Points to TCL_TOKEN_SUB_EXPR token
- * containing the "?" operator. */
- ExprInfo *infoPtr; /* Describes the compilation state for the
- * expression being compiled. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
- Tcl_Token **endPtrPtr; /* If successful, a pointer to the token
- * just after the last token in the
- * subexpression is stored here. */
+int
+TclSingleOpCmd(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
{
- JumpFixup jumpAroundThenFixup, jumpAroundElseFixup;
- /* Used to update or replace one-byte jumps
- * around the then and else expressions when
- * their target PCs are determined. */
- Tcl_Token *tokenPtr;
- int elseCodeOffset, dist, code;
- int savedStackDepth = envPtr->currStackDepth;
-
- /*
- * Emit code for the test.
- */
+ TclOpCmdClientData *occdPtr = (TclOpCmdClientData *)clientData;
+ unsigned char lexeme;
+ OpNode nodes[2];
+ Tcl_Obj *const *litObjv = objv + 1;
+
+ if (objc != 1+occdPtr->i.numArgs) {
+ Tcl_WrongNumArgs(interp, 1, objv, occdPtr->expected);
+ return TCL_ERROR;
+ }
- tokenPtr = exprTokenPtr+2;
- code = CompileSubExpr(tokenPtr, infoPtr, envPtr);
- if (code != TCL_OK) {
- goto done;
+ ParseLexeme(occdPtr->op, strlen(occdPtr->op), &lexeme, NULL);
+ nodes[0].lexeme = START;
+ nodes[0].mark = MARK_RIGHT;
+ nodes[0].right = 1;
+ nodes[1].lexeme = lexeme;
+ if (objc == 2) {
+ nodes[1].mark = MARK_RIGHT;
+ } else {
+ nodes[1].mark = MARK_LEFT;
+ nodes[1].left = OT_LITERAL;
}
- tokenPtr += (tokenPtr->numComponents + 1);
-
- /*
- * Emit the jump to the "else" expression if the test was false.
- */
-
- TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &jumpAroundThenFixup);
+ nodes[1].right = OT_LITERAL;
+ nodes[1].p.parent = 0;
- /*
- * Compile the "then" expression. Note that if a subexpression is only
- * a primary, we need to try to convert it to numeric. We do this to
- * support Tcl's policy of interpreting operands if at all possible as
- * first integers, else floating-point numbers.
- */
+ return ExecConstantExprTree(interp, nodes, 0, &litObjv);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSortingOpCmd --
+ * Implements the commands: <, <=, >, >=, ==, eq
+ * in the ::tcl::mathop namespace. These commands are defined for
+ * arbitrary number of arguments by computing the AND of the base
+ * operator applied to all neighbor argument pairs.
+ *
+ * Results:
+ * A standard Tcl return code and result left in interp.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
- infoPtr->hasOperators = 0;
- code = CompileSubExpr(tokenPtr, infoPtr, envPtr);
- if (code != TCL_OK) {
- goto done;
- }
- tokenPtr += (tokenPtr->numComponents + 1);
- if (!infoPtr->hasOperators) {
- TclEmitOpcode(INST_TRY_CVT_TO_NUMERIC, envPtr);
- }
+int
+TclSortingOpCmd(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ int code = TCL_OK;
- /*
- * Emit an unconditional jump around the "else" condExpr.
- */
-
- TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP,
- &jumpAroundElseFixup);
+ if (objc < 3) {
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
+ } else {
+ TclOpCmdClientData *occdPtr = (TclOpCmdClientData *)clientData;
+ Tcl_Obj **litObjv = (Tcl_Obj **) TclStackAlloc(interp,
+ 2*(objc-2)*sizeof(Tcl_Obj *));
+ OpNode *nodes = (OpNode *) TclStackAlloc(interp,
+ 2*(objc-2)*sizeof(OpNode));
+ unsigned char lexeme;
+ int i, lastAnd = 1;
+ Tcl_Obj *const *litObjPtrPtr = litObjv;
+
+ ParseLexeme(occdPtr->op, strlen(occdPtr->op), &lexeme, NULL);
+
+ litObjv[0] = objv[1];
+ nodes[0].lexeme = START;
+ nodes[0].mark = MARK_RIGHT;
+ for (i=2; i<objc-1; i++) {
+ litObjv[2*(i-1)-1] = objv[i];
+ nodes[2*(i-1)-1].lexeme = lexeme;
+ nodes[2*(i-1)-1].mark = MARK_LEFT;
+ nodes[2*(i-1)-1].left = OT_LITERAL;
+ nodes[2*(i-1)-1].right = OT_LITERAL;
+
+ litObjv[2*(i-1)] = objv[i];
+ nodes[2*(i-1)].lexeme = AND;
+ nodes[2*(i-1)].mark = MARK_LEFT;
+ nodes[2*(i-1)].left = lastAnd;
+ nodes[lastAnd].p.parent = 2*(i-1);
+
+ nodes[2*(i-1)].right = 2*(i-1)+1;
+ nodes[2*(i-1)+1].p.parent= 2*(i-1);
+
+ lastAnd = 2*(i-1);
+ }
+ litObjv[2*(objc-2)-1] = objv[objc-1];
- /*
- * Compile the "else" expression.
- */
+ nodes[2*(objc-2)-1].lexeme = lexeme;
+ nodes[2*(objc-2)-1].mark = MARK_LEFT;
+ nodes[2*(objc-2)-1].left = OT_LITERAL;
+ nodes[2*(objc-2)-1].right = OT_LITERAL;
- envPtr->currStackDepth = savedStackDepth;
- elseCodeOffset = (envPtr->codeNext - envPtr->codeStart);
- infoPtr->hasOperators = 0;
- code = CompileSubExpr(tokenPtr, infoPtr, envPtr);
- if (code != TCL_OK) {
- goto done;
- }
- tokenPtr += (tokenPtr->numComponents + 1);
- if (!infoPtr->hasOperators) {
- TclEmitOpcode(INST_TRY_CVT_TO_NUMERIC, envPtr);
- }
+ nodes[0].right = lastAnd;
+ nodes[lastAnd].p.parent = 0;
- /*
- * Fix up the second jump around the "else" expression.
- */
+ code = ExecConstantExprTree(interp, nodes, 0, &litObjPtrPtr);
- dist = (envPtr->codeNext - envPtr->codeStart)
- - jumpAroundElseFixup.codeOffset;
- if (TclFixupForwardJump(envPtr, &jumpAroundElseFixup, dist, 127)) {
- /*
- * Update the else expression's starting code offset since it
- * moved down 3 bytes too.
- */
-
- elseCodeOffset += 3;
+ TclStackFree(interp, nodes);
+ TclStackFree(interp, litObjv);
}
-
- /*
- * Fix up the first jump to the "else" expression if the test was false.
- */
-
- dist = (elseCodeOffset - jumpAroundThenFixup.codeOffset);
- TclFixupForwardJump(envPtr, &jumpAroundThenFixup, dist, 127);
- *endPtrPtr = tokenPtr;
-
- done:
- envPtr->currStackDepth = savedStackDepth + 1;
return code;
}
/*
*----------------------------------------------------------------------
*
- * CompileMathFuncCall --
- *
- * This procedure compiles a call on a math function in an expression:
- * mathFuncCall ::= funcName '(' [condExpr {',' condExpr}] ')'
+ * TclVariadicOpCmd --
+ * Implements the commands: +, *, &, |, ^, **
+ * in the ::tcl::mathop namespace. These commands are defined for
+ * arbitrary number of arguments by repeatedly applying the base
+ * operator with suitable associative rules. When fewer than two
+ * arguments are provided, suitable identity values are returned.
*
* Results:
- * The return value is TCL_OK on a successful compilation and TCL_ERROR
- * on failure. If TCL_OK is returned, a pointer to the token just after
- * the last one in the subexpression is stored at the address in
- * endPtrPtr. If TCL_ERROR is returned, then the interpreter's result
- * contains an error message.
+ * A standard Tcl return code and result left in interp.
*
* Side effects:
- * Adds instructions to envPtr to evaluate the math function at
- * runtime.
+ * None.
*
*----------------------------------------------------------------------
*/
-static int
-CompileMathFuncCall(exprTokenPtr, funcName, infoPtr, envPtr, endPtrPtr)
- Tcl_Token *exprTokenPtr; /* Points to TCL_TOKEN_SUB_EXPR token
- * containing the math function call. */
- CONST char *funcName; /* Name of the math function. */
- ExprInfo *infoPtr; /* Describes the compilation state for the
- * expression being compiled. */
- CompileEnv *envPtr; /* Holds resulting instructions. */
- Tcl_Token **endPtrPtr; /* If successful, a pointer to the token
- * just after the last token in the
- * subexpression is stored here. */
+int
+TclVariadicOpCmd(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
{
- Tcl_Interp *interp = infoPtr->interp;
- Interp *iPtr = (Interp *) interp;
- MathFunc *mathFuncPtr;
- Tcl_HashEntry *hPtr;
- Tcl_Token *tokenPtr, *afterSubexprPtr;
- int code, i;
-
- /*
- * Look up the MathFunc record for the function.
- */
+ TclOpCmdClientData *occdPtr = (TclOpCmdClientData *)clientData;
+ unsigned char lexeme;
+ int code;
- code = TCL_OK;
- hPtr = Tcl_FindHashEntry(&iPtr->mathFuncTable, funcName);
- if (hPtr == NULL) {
- Tcl_ResetResult(interp);
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "unknown math function \"", funcName, "\"", (char *) NULL);
- code = TCL_ERROR;
- goto done;
+ if (objc < 2) {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(occdPtr->i.identity));
+ return TCL_OK;
}
- mathFuncPtr = (MathFunc *) Tcl_GetHashValue(hPtr);
- /*
- * If not a builtin function, push an object with the function's name.
- */
-
- if (mathFuncPtr->builtinFuncIndex < 0) {
- TclEmitPush(TclRegisterNewLiteral(envPtr, funcName, -1), envPtr);
- }
+ ParseLexeme(occdPtr->op, strlen(occdPtr->op), &lexeme, NULL);
+ lexeme |= BINARY;
+
+ if (objc == 2) {
+ Tcl_Obj *litObjv[2];
+ OpNode nodes[2];
+ int decrMe = 0;
+ Tcl_Obj *const *litObjPtrPtr = litObjv;
+
+ if (lexeme == EXPON) {
+ litObjv[1] = Tcl_NewIntObj(occdPtr->i.identity);
+ Tcl_IncrRefCount(litObjv[1]);
+ decrMe = 1;
+ litObjv[0] = objv[1];
+ nodes[0].lexeme = START;
+ nodes[0].mark = MARK_RIGHT;
+ nodes[0].right = 1;
+ nodes[1].lexeme = lexeme;
+ nodes[1].mark = MARK_LEFT;
+ nodes[1].left = OT_LITERAL;
+ nodes[1].right = OT_LITERAL;
+ nodes[1].p.parent = 0;
+ } else {
+ if (lexeme == DIVIDE) {
+ litObjv[0] = Tcl_NewDoubleObj(1.0);
+ } else {
+ litObjv[0] = Tcl_NewIntObj(occdPtr->i.identity);
+ }
+ Tcl_IncrRefCount(litObjv[0]);
+ litObjv[1] = objv[1];
+ nodes[0].lexeme = START;
+ nodes[0].mark = MARK_RIGHT;
+ nodes[0].right = 1;
+ nodes[1].lexeme = lexeme;
+ nodes[1].mark = MARK_LEFT;
+ nodes[1].left = OT_LITERAL;
+ nodes[1].right = OT_LITERAL;
+ nodes[1].p.parent = 0;
+ }
- /*
- * Compile any arguments for the function.
- */
+ code = ExecConstantExprTree(interp, nodes, 0, &litObjPtrPtr);
- tokenPtr = exprTokenPtr+2;
- afterSubexprPtr = exprTokenPtr + (exprTokenPtr->numComponents + 1);
- if (mathFuncPtr->numArgs > 0) {
- for (i = 0; i < mathFuncPtr->numArgs; i++) {
- if (tokenPtr == afterSubexprPtr) {
- Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "too few arguments for math function", -1);
- code = TCL_ERROR;
- goto done;
- }
- code = CompileSubExpr(tokenPtr, infoPtr, envPtr);
- if (code != TCL_OK) {
- goto done;
+ Tcl_DecrRefCount(litObjv[decrMe]);
+ return code;
+ } else {
+ Tcl_Obj *const *litObjv = objv + 1;
+ OpNode *nodes = (OpNode *) TclStackAlloc(interp,
+ (objc-1)*sizeof(OpNode));
+ int i, lastOp = OT_LITERAL;
+
+ nodes[0].lexeme = START;
+ nodes[0].mark = MARK_RIGHT;
+ if (lexeme == EXPON) {
+ for (i=objc-2; i>0; i-- ) {
+ nodes[i].lexeme = lexeme;
+ nodes[i].mark = MARK_LEFT;
+ nodes[i].left = OT_LITERAL;
+ nodes[i].right = lastOp;
+ if (lastOp >= 0) {
+ nodes[lastOp].p.parent = i;
+ }
+ lastOp = i;
+ }
+ } else {
+ for (i=1; i<objc-1; i++ ) {
+ nodes[i].lexeme = lexeme;
+ nodes[i].mark = MARK_LEFT;
+ nodes[i].left = lastOp;
+ if (lastOp >= 0) {
+ nodes[lastOp].p.parent = i;
+ }
+ nodes[i].right = OT_LITERAL;
+ lastOp = i;
}
- tokenPtr += (tokenPtr->numComponents + 1);
}
- if (tokenPtr != afterSubexprPtr) {
- Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "too many arguments for math function", -1);
- code = TCL_ERROR;
- goto done;
- }
- } else if (tokenPtr != afterSubexprPtr) {
- Tcl_ResetResult(interp);
- Tcl_AppendToObj(Tcl_GetObjResult(interp),
- "too many arguments for math function", -1);
- code = TCL_ERROR;
- goto done;
- }
-
- /*
- * Compile the call on the math function. Note that the "objc" argument
- * count for non-builtin functions is incremented by 1 to include the
- * function name itself.
- */
+ nodes[0].right = lastOp;
+ nodes[lastOp].p.parent = 0;
- if (mathFuncPtr->builtinFuncIndex >= 0) { /* a builtin function */
- /*
- * Adjust the current stack depth by the number of arguments
- * of the builtin function. This cannot be handled by the
- * TclEmitInstInt1 macro as the number of arguments is not
- * passed as an operand.
- */
+ code = ExecConstantExprTree(interp, nodes, 0, &litObjv);
- if (envPtr->maxStackDepth < envPtr->currStackDepth) {
- envPtr->maxStackDepth = envPtr->currStackDepth;
- }
- TclEmitInstInt1(INST_CALL_BUILTIN_FUNC1,
- mathFuncPtr->builtinFuncIndex, envPtr);
- envPtr->currStackDepth -= mathFuncPtr->numArgs;
- } else {
- TclEmitInstInt1(INST_CALL_FUNC1, (mathFuncPtr->numArgs+1), envPtr);
- }
- *endPtrPtr = afterSubexprPtr;
+ TclStackFree(interp, nodes);
- done:
- return code;
+ return code;
+ }
}
/*
*----------------------------------------------------------------------
*
- * LogSyntaxError --
- *
- * This procedure is invoked after an error occurs when compiling an
- * expression. It sets the interpreter result to an error message
- * describing the error.
+ * TclNoIdentOpCmd --
+ * Implements the commands: -, /
+ * in the ::tcl::mathop namespace. These commands are defined for
+ * arbitrary non-zero number of arguments by repeatedly applying
+ * the base operator with suitable associative rules. When no
+ * arguments are provided, an error is raised.
*
* Results:
- * None.
+ * A standard Tcl return code and result left in interp.
*
* Side effects:
- * Sets the interpreter result to an error message describing the
- * expression that was being compiled when the error occurred.
+ * None.
*
*----------------------------------------------------------------------
*/
-static void
-LogSyntaxError(infoPtr)
- ExprInfo *infoPtr; /* Describes the compilation state for the
- * expression being compiled. */
+int
+TclNoIdentOpCmd(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
{
- int numBytes = (infoPtr->lastChar - infoPtr->expr);
- char buffer[100];
-
- sprintf(buffer, "syntax error in expression \"%.*s\"",
- ((numBytes > 60)? 60 : numBytes), infoPtr->expr);
- Tcl_ResetResult(infoPtr->interp);
- Tcl_AppendStringsToObj(Tcl_GetObjResult(infoPtr->interp),
- buffer, (char *) NULL);
+ TclOpCmdClientData *occdPtr = (TclOpCmdClientData *)clientData;
+ if (objc < 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, occdPtr->expected);
+ return TCL_ERROR;
+ }
+ return TclVariadicOpCmd(clientData, interp, objc, objv);
}
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclCompile.c b/generic/tclCompile.c